Fix CA-key-in-image (HackerOne #3764027) and root-cron privesc in simplerisk - #169
Merged
jsokol merged 3 commits intoSep 20, 2026
Merged
Conversation
…ckerOne #3764027) The Dockerfile generated a CA key/cert and Apache TLS key/cert at build time, baked both into the published image layer, and installed the CA into the container's system trust store. Anyone who pulled the image could extract the CA private key and forge certs for any hostname the container's own outbound HTTPS calls (e.g. the schema fetch in entrypoint.sh) would then trust. Removes the custom CA entirely -- unnecessary, since the non-minimal simplerisk image self-signs its Apache cert directly without one -- and moves self-signed cert generation from build time to container startup, so each deployment gets its own key instead of a key shared by every pull of the same tag. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
/var/www/simplerisk (including cron/cron.php) is chowned to www-data, but the cron.d entry executed it as root every minute. Any web-tier compromise that gets code execution as www-data could overwrite cron.php and escalate to root on the next cron tick -- the same CWE-732 privilege-boundary crossing reported and fixed upstream in simplerisk/setup-scripts as HackerOne #3761952, just baked into this image's Dockerfile instead of the bare-metal installer script. cron.php only runs application-level jobs that already execute as www-data under Apache, so it doesn't need root. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jsokol
force-pushed
the
security/hackerone-3764027-docker-ssl-and-cron-privesc
branch
from
September 20, 2026 18:38
62e0065 to
d6860d5
Compare
CVE-2026-19931 and CVE-2026-18924 are the same pre-existing Grype false positive already documented above (binary classifier reads the PHP interpreter's embedded version string out of curl.so and reports it as curl's own version), just newly published CVE IDs against that same fictitious version. Verified via `grype -o json`: the only match is /usr/local/lib/php/extensions/.../curl.so; the real Debian curl package is a separate match Debian's tracker marks "wont-fix", which --only-fixed already excludes on its own. This was failing container-validation.yml on all three simplerisk-minimal PHP variants. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jsokol
deleted the
security/hackerone-3764027-docker-ssl-and-cron-privesc
branch
September 20, 2026 19:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
simplerisk-minimalbaked a CA key + Apache TLS key into the published image layer at build time and installed the CA into the container's trust store. Anyone whodocker pulled the image could extract the CA private key and forge certs the container's own outbound HTTPS calls would trust. The CA is removed entirely and the self-signed Apache cert is now generated at container startup (entrypoint.sh), so each deployment gets its own unique key instead of one shared across every pull of a tag.simplerisk/setup-scripts), found while auditing for it here: the full-stacksimpleriskimage rancron/cron.phpas root via/etc/cron.d/simplerisk-cron, while/var/www/simplerisk(includingcron.php) ischown -R www-data. A web-tier compromise aswww-datacould overwritecron.phpand escalate to root on the next cron tick. The cron entry now runs aswww-data, matching file ownership;cron.phponly runs application-level jobs that already execute aswww-dataunder Apache.simplerisk/setup-scripts, not this repo) don't otherwise apply here:simplerisk-minimal's app cron already runs as the non-rootsimpleriskuser, and the only external feed value we consume (download_and_verify_bundle.sh's hash lookup) is strictly regex-validated before use, never interpolated into a shell command.Test plan
shellcheck --severity=erroron bothentrypoint.shscriptstest_generate_dockerfile.shregression suite passes for bothsimpleriskandsimplerisk-minimalsimplerisk-minimallocally; confirmed no CA/cert/key material is present in the image, and thatentrypoint.shgenerates a fresh self-signed cert on first container startup (idempotent across restarts), and that HTTPS serves correctly (curl -kreturns 200)container-validation.yml(builds all 5 variants, Dockle, Grype, generator checks)🤖 Generated with Claude Code