VYPR
High severity7.8OSV Advisory· Published Sep 2, 2025· Updated Apr 15, 2026

CVE-2025-58178

CVE-2025-58178

Description

SonarQube Server and Cloud is a static analysis solution for continuous code quality and security inspection. In versions 4 to 5.3.0, a command injection vulnerability was discovered in the SonarQube Scan GitHub Action that allows untrusted input arguments to be processed without proper sanitization. Arguments sent to the action are treated as shell expressions, allowing potential execution of arbitrary commands. A fix has been released in SonarQube Scan GitHub Action 5.3.1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
SonarSource/sonarqube-scan-actionGitHub Actions
>= 4.0.0, < 5.3.15.3.1

Affected products

1

Patches

2
1a6d90ebcb0e

SQSCANGHA-102 Pin actions/cache to a full-length commit SHA (#199)

1 file changed · +1 1
  • action.yml+1 1 modified
    @@ -33,7 +33,7 @@ runs:
             INPUT_SCANNERVERSION: ${{ inputs.scannerVersion }}
         - name: Load Sonar Scanner CLI from cache
           id: sonar-scanner-cli
    -      uses: actions/cache@v4
    +      uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
           env:
             # The default value is 60mins. Reaching timeout is treated the same as a cache miss.
             SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
    
016cabf33a6b

SQSCANGHA-101 Add more command injection tests

https://github.com/sonarsource/sonarqube-scan-actionAleksandra BozhinoskaAug 28, 2025via osv
4 files changed · +109 8
  • action.yml+2 4 modified
    @@ -51,11 +51,9 @@ runs:
           run: echo "${RUNNER_TEMP}/sonar-scanner-cli-${{ inputs.scannerVersion }}-${{ runner.os }}-${{ runner.arch }}/bin" >> $GITHUB_PATH
           shell: bash
         - name: Run SonarScanner
    -      run: |
    -        args=(${{ inputs.args }})
    -        cmd=(${GITHUB_ACTION_PATH}/scripts/run-sonar-scanner-cli.sh "${args[@]}")
    -        "${cmd[@]}"
    +      run: ${GITHUB_ACTION_PATH}/scripts/run-sonar-scanner.sh
           shell: bash
           env:
    +        INPUT_ARGS: ${{ inputs.args }}
             INPUT_PROJECTBASEDIR: ${{ inputs.projectBaseDir }}
             SONAR_SCANNER_JRE: ${{ runner.temp }}/sonar-scanner-cli-${{ inputs.scannerVersion }}-${{ runner.os }}-${{ runner.arch }}/jre
    
  • .github/workflows/qa-main.yml+90 3 modified
    @@ -41,20 +41,22 @@ jobs:
           - name: Run action with args
             uses: ./
             with:
    -          args: -Dsonar.someArg=aValue -Dsonar.anotherArgWithSpaces="Another Value"
    +          args: -Dsonar.someArg=aValue -Dsonar.anotherArgWithSpaces="Another Value" -Dsonar.argWithSingleQuotes='Another Value'
             env:
               SONAR_HOST_URL: http://not_actually_used
               SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
           - name: Assert
             run: |
               ./test/assertFileContains ./output.properties "sonar.someArg=aValue"
    -          ./test/assertFileContains ./output.properties "sonar.anotherArgWithSpaces=Another Value"
    +          ./test/assertFileContains ./output.properties 'sonar.anotherArgWithSpaces="Another Value"'
    +          ./test/assertFileContains ./output.properties "sonar.argWithSingleQuotes='Another Value'"
       argsInputInjectionTest:
         name: >
           'args' input with command injection will fail
         strategy:
           matrix:
             os: [ ubuntu-latest-large, windows-latest-large, macos-latest ]
    +        args: [ -Dsonar.someArg=aValue && echo "Injection", -Dsonar.someArg="value\"; whoami; echo \"" ]
         runs-on: ${{ matrix.os }}
         steps:
           - uses: actions/checkout@v5
    @@ -64,7 +66,7 @@ jobs:
             uses: ./
             continue-on-error: true
             with:
    -          args: -Dsonar.someArg=aValue && echo "Injection"
    +          args: ${{ matrix.args }}
             env:
               SONAR_HOST_URL: http://not_actually_used
               SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
    @@ -74,6 +76,91 @@ jobs:
           - name: Assert the scanner was not called
             run: |
               ./test/assertFileDoesntExist ./output.properties
    +  backtickCommandInjectionTest:
    +    name: >
    +      'args' input with backticks injection does not execute command
    +    strategy:
    +      matrix:
    +        os: [ ubuntu-latest-large, windows-latest-large, macos-latest ]
    +    runs-on: ${{ matrix.os }}
    +    steps:
    +      - uses: actions/checkout@v5
    +        with:
    +          token: ${{ secrets.GITHUB_TOKEN }}
    +      - name: Run action with args
    +        uses: ./
    +        continue-on-error: true
    +        with:
    +          args: >
    +            -Dsonar.arg1="refs/heads/branch: [workflows] Bump `actions/*`" -Dsonar.arg2="test `echo Command Injection`" -Dsonar.arg3="`id`" -Dsonar.arg4="test'; `echo injection`; echo '" -Dsonar.arg5="   `whoami`   " -Dsonar.arg6="test\`echo injection\`test"
    +        env:
    +          SONAR_HOST_URL: http://not_actually_used
    +          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
    +      - name: Assert command in arg is not executed
    +        run: |
    +          ./test/assertFileContains ./output.properties 'sonar.arg1="refs/heads/branch\\: \[workflows\] Bump `actions/\*`"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg2="test `echo Command Injection`"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg3="`id`"'
    +          ./test/assertFileContains ./output.properties "sonar.arg4=\"test'; \`echo injection\`; echo '\""
    +          ./test/assertFileContains ./output.properties 'sonar.arg5="   `whoami`   "'
    +          ./test/assertFileContains ./output.properties 'sonar.arg6="test\\\\`echo injection\\\\`test"'
    +  dollarSymbolCommandInjectionTest:
    +    name: >
    +      'args' input with dollar command injection does not execute command
    +    strategy:
    +      matrix:
    +        os: [ ubuntu-latest-large, windows-latest-large, macos-latest ]
    +    runs-on: ${{ matrix.os }}
    +    steps:
    +      - uses: actions/checkout@v5
    +        with:
    +          token: ${{ secrets.GITHUB_TOKEN }}
    +      - name: Run action with args
    +        uses: ./
    +        continue-on-error: true
    +        with:
    +          args: -Dsonar.arg1="$(whoami)" -Dsonar.arg2="$GITHUB_TOKEN" -Dsonar.arg3="$(echo outer $(echo inner))" -Dsonar.arg4="value\$(whoami)end" -Dsonar.arg5="$(printf 'A%.0s' {1..10000})" -Dsonar.arg6='value"; $(whoami); echo "'
    +        env:
    +          SONAR_HOST_URL: http://not_actually_used
    +          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
    +      - name: Assert command in arg is not executed
    +        run: |
    +          ./test/assertFileContains ./output.properties 'sonar.arg1="$(whoami)"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg2="$GITHUB_TOKEN"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg3="$(echo outer $(echo inner))"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg4="value\\\\$(whoami)end"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg5="$(printf '\''A%.0s'\'' {1..10000})"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg6='\''value"; $(whoami); echo "'\'''
    +  otherCommandInjectionVariantsTest:
    +    name: >
    +      'args' input with other command injection variants does not execute command
    +    strategy:
    +      matrix:
    +        os: [ ubuntu-latest-large, windows-latest-large, macos-latest ]
    +    runs-on: ${{ matrix.os }}
    +    steps:
    +      - uses: actions/checkout@v5
    +        with:
    +          token: ${{ secrets.GITHUB_TOKEN }}
    +      - name: Run action with args
    +        uses: ./
    +        continue-on-error: true
    +        with:
    +          args: -Dsonar.arg1="test | base64" -Dsonar.arg2="value; whoami" -Dsonar.arg3="value && echo test" -Dsonar.arg4="value > /tmp/output.txt" -Dsonar.arg5="< /etc/passwd" -Dsonar.arg6="" -Dsonar.arg7="../../../*" -Dsonar.arg8="*.key" -Dsonar.arg9="test\u0027\u0060whoami\u0060"
    +        env:
    +          SONAR_HOST_URL: http://not_actually_used
    +          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
    +      - name: Assert command in arg is not executed
    +        run: |
    +          ./test/assertFileContains ./output.properties 'sonar.arg1="test | base64"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg2="value; whoami"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg3="value && echo test"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg4="value > /tmp/output.txt"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg5="< /etc/passwd"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg6=""'
    +          ./test/assertFileContains ./output.properties 'sonar.arg7="../../../\*"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg8="\*.key"'
    +          ./test/assertFileContains ./output.properties 'sonar.arg9="test\\\\u0027\\\\u0060whoami\\\\u0060"'
       projectBaseDirInputTest:
         name: >
           'projectBaseDir' input
    
  • scripts/run-sonar-scanner-cli.sh+11 1 modified
    @@ -73,7 +73,17 @@ if [[ -n "${SONAR_ROOT_CERT}" ]]; then
       scanner_args+=("-Dsonar.scanner.truststorePassword=$SONAR_SSL_TRUSTSTORE_PASSWORD")
     fi
     
    -scanner_args+=("$@")
    +# split input args correctly (passed through INPUT_ARGS env var to avoid execution of injected command)
    +args=()
    +if [[ -n "${INPUT_ARGS}" ]]; then
    +#  the regex recognizes args with values in single or double quotes (without character escaping), and args without quotes as well
    +#  more specifically, the following patterns: -Darg="value", -Darg='value', -Darg=value, "-Darg=value" and '-Darg=value'
    +  IFS=$'\n'; args=($(echo ${INPUT_ARGS} | egrep -o '[^" '\'']+="[^"]*"|[^" '\'']+='\''[^'\'']*'\''|[^" '\'']+|"[^"]+"|'\''[^'\'']+'\'''))
    +fi
    +
    +for arg in "${args[@]}"; do
    +  scanner_args+=("$arg")
    +done
     
     set -ux
     
    
  • scripts/run-sonar-scanner.sh+6 0 added
    @@ -0,0 +1,6 @@
    +#!/usr/bin/env bash
    +set -euo pipefail
    +
    +# run the sonar scanner cli
    +cmd=(${GITHUB_ACTION_PATH}/scripts/run-sonar-scanner-cli.sh "${INPUT_ARGS}")
    +"${cmd[@]}"
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.