Command Injection

HIGH
flutter/flutter
Commit: 583dec70ff3a
Affected: <= v1.16.3
2026-05-12 21:04 UTC

Description

Commit 583dec70ff3a56f9dc99d985a3aaf714bfd229f2 Harden dev tooling Bash scripts by quoting environment and URL variables used in redirections and condition checks. Prior to this fix, several scripts used unquoted variable expansions (e.g., log_file in dev/bots/codelabs_build_test.sh, STAGING_DIR in dev/bots/docs.sh, WRAPPER_TEMP_DIR and WRAPPER_SRC_URL in dev/tools/repackage_gradle_wrapper.sh). Unquoted expansions are vulnerable to word-splitting and, in certain contexts, command injection if an attacker can influence the variable values. The changes mitigate these risks by quoting variables and using safer path concatenation, reducing the risk of arbitrary command execution and potential log leakage in CI/developer tooling.

Proof of Concept

PoC 1: Log redirection injection via unquoted redirection target\n\nCreate a small vulnerable script that mirrors the pattern in Flutter's dev tooling:\n\n#!/bin/bash\nlog_file='log.txt; echo INJECTED > /tmp/pwned'\necho "Build failed" >> ${log_file}\n\nRun: bash vuln.sh\n\nExpected: The shell executes the injected command after the semicolon, resulting in /tmp/pwned being created and containing INJECTED. This demonstrates command injection via an unquoted redirection target.\n\nPoC 2: Unquoted variable in an if test leading to injection\n\n#!/bin/bash\nSTAGING_DIR='foo; echo INJECTED; ' \nif [[ -z $STAGING_DIR ]]; then\n STAGING_DIR=$(mktemp -d /tmp/dartdoc.XXXXX)\nfi\necho DOC_DIR is "$STAGING_DIR/doc"\n\nRun: bash vuln2.sh\n\nExpected: The injected command (echo INJECTED) executes as part of the shell parsing, demonstrating injection via an unquoted test variable.\n

Commit Details

Author: Muhammad Ishaq Khan

Date: 2026-05-12 19:06 UTC

Message:

Harden dev tooling scripts against command injection and log leaks (#186076) ## Description This PR hardens several developer and CI scripts against command injection, URL-splitting, and information disclosure. These were flagged as high-severity vulnerabilities by static analysis. Fixes applied: * Properly quoted `$STAGING_DIR`, `${log_file}`, `$WRAPPER_TEMP_DIR`, and `$WRAPPER_SRC_URL` in Bash scripts to prevent arbitrary command injection.

Triage Assessment

Vulnerability Type: Command Injection

Confidence: HIGH

Reasoning:

Commit description and code changes show explicit hardening against command injection and information leakage by properly quoting environment and URL variables in Bash scripts, preventing potential arbitrary command execution and log leakage. This is a security vulnerability fix in developer/CI tooling scripts.

Verification Assessment

Vulnerability Type: Command Injection

Confidence: HIGH

Affected Versions: <= v1.16.3

Code Diff

diff --git a/dev/bots/codelabs_build_test.sh b/dev/bots/codelabs_build_test.sh index e5f70c1f69177..013aba20c8733 100755 --- a/dev/bots/codelabs_build_test.sh +++ b/dev/bots/codelabs_build_test.sh @@ -29,7 +29,7 @@ if [ ${PIPESTATUS[0]} -eq 0 ] || is_expected_failure "$log_file"; then rm "$log_file" else all_builds_ok=0 - echo "View https://github.com/flutter/flutter/blob/main/dev/bots/README.md for steps to resolve this failed build test." >> ${log_file} + echo "View https://github.com/flutter/flutter/blob/main/dev/bots/README.md for steps to resolve this failed build test." >> "${log_file}" echo echo "Log left in $log_file." echo diff --git a/dev/bots/docs.sh b/dev/bots/docs.sh index 73ee71f1f7ad9..7ba9d30a4a442 100755 --- a/dev/bots/docs.sh +++ b/dev/bots/docs.sh @@ -96,7 +96,7 @@ function parse_args() { esac shift done - if [[ -z $STAGING_DIR ]]; then + if [[ -z "$STAGING_DIR" ]]; then STAGING_DIR=$(mktemp -d /tmp/dartdoc.XXXXX) fi DOC_DIR="$STAGING_DIR/doc" diff --git a/dev/tools/repackage_gradle_wrapper.sh b/dev/tools/repackage_gradle_wrapper.sh index c0c1fad39d442..951d455cdd64a 100755 --- a/dev/tools/repackage_gradle_wrapper.sh +++ b/dev/tools/repackage_gradle_wrapper.sh @@ -48,7 +48,7 @@ WRAPPER_TEMP_DIR="$FLUTTER_ROOT/bin/cache/gradle-wrapper-temp" echo "Downloading gradle wrapper..." rm -rf "$WRAPPER_TEMP_DIR" mkdir "$WRAPPER_TEMP_DIR" -curl --continue-at - --location --output "$WRAPPER_TEMP_DIR/templates.tgz" "$WRAPPER_SRC_URL" 2>&1 +curl --continue-at - --location --output "${WRAPPER_TEMP_DIR}/templates.tgz" "${WRAPPER_SRC_URL}" 2>&1 echo echo "Repackaging files..."
← Back to Alerts View on GitHub →