Repository navigation
Conversation
…file instruction injection
Dict-form `docker.env` entries were interpolated into the generated
Dockerfile without any sanitization (`ARG {{ key }}={{ value }}` in base.j2),
while the list form was regex-validated and system_packages/base_image went
through bash_quote/normalize_line. A value containing a newline breaks out of
the ARG line and executes arbitrary instructions at build time.
- _convert_env dict branch now rejects keys/values containing newline or
control characters (single choke point, covers every template)
- BentoEnvSchema (v2 envs path) gets the same guard via attr validators;
bash_quote alone is insufficient because Dockerfile quotes do not span lines
Fixes bentoml#5656
Author
|
Closing as part of a contribution-portfolio consolidation: my effort is now focused on a single project (failroute, a static analyzer for silent-failure anti-patterns) and its upstream follow-through. Happy to revisit if there is interest. |
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.
Fixes #5656
Root cause
Dict-form
docker.enventries were interpolated into the generated Dockerfile completely raw (ARG {{ key }}={{ value }}inbase.j2), while sibling paths were already hardened:env→ regex-validated in_convert_env(build_config.py)system_packages→bash_quotebase_image→normalize_lineA newline in a value terminates the
ARGinstruction — Dockerfile instructions are newline-delimited and quotes do not span lines, so any following lines execute as instructions at build time (reproduced offline viagenerate_containerfile; the reporter's exact payload renders a liveRUN echo PWNED...step).Fix (
src/bentoml/_internal/bento/build_config.py, +45/-3)_convert_env: keys/values are checked against a control-character class ([\x00-\x1f\x7f]) and raiseBentoMLExceptionwith guidance to use the list form or an.envfile for complex values. This is the single choke point every template renders from, so v1/v2/debian/alpine/ubi8 are all covered.ARG KEY=valuelines ({"GREETING": "hello world"}renders exactly as before).BentoEnvSchema(the v2envs:path): same guard added as attr validators onname/value. The issue notes this path as "hardened", butbash_quoteonly wraps in single quotes — a raw newline inside still breaks the instruction, so the guard is needed at definition time.Tests (
tests/unit/_internal/container/test_generate.py, +40 lines)Following the existing same-family patterns (
test_generate_containerfile_quotes_system_packages,..._normalizes_custom_base_image):BentoMLExceptionatDockerOptionsconstruction (before any template rendering)"hello world", URL) render unchanged and no payload appearsBentoEnvSchemarejects control chars in value and name, accepts legit entriesRed→green verified against the pre-fix tree: 5 passed → 8 passed (the 3 new tests fail without the fix; the reporter's repro script also flips from "Injection present: True" to raising at construction).
ruff check/format --check: zero new findings vs. baseline on both touched files.