-
Notifications
You must be signed in to change notification settings - Fork 5.2k
fix: harden supply-chain security — obfuscation scanner + advisory policy #458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| #!/usr/bin/env bash | ||
| # Supply-chain obfuscation scanner | ||
| # Scans PR diffs for patterns commonly found in malicious supply-chain attacks: | ||
| # - Obfuscated code (packed, shuffled, base64-encoded, hex-encoded) | ||
| # - Suspicious global/prototype assignments in build config files | ||
| # - Hidden eval / Function constructor calls | ||
| # - Large diffs dominated by non-human-readable strings | ||
| # | ||
| # Exit 0 = clean. Exit 1 = suspicious patterns found (review required). | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| RED='\033[0;31m' | ||
| YELLOW='\033[1;33m' | ||
| NC='\033[0m' # No Color | ||
|
|
||
| WARNINGS=0 | ||
|
|
||
| check_pattern() { | ||
| local label="$1" | ||
| local pattern="$2" | ||
| local severity="${3:-WARN}" | ||
|
|
||
| if grep -n -P "$pattern" /tmp/pr-diff.txt 2>/dev/null; then | ||
| echo -e "${RED}[${severity}]${NC} $label — matches found (see above)" | ||
| WARNINGS=$((WARNINGS + 1)) | ||
| fi | ||
| } | ||
|
|
||
| echo "::group::Obfuscation Scan" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # 1. OBFUSCATION PATTERNS | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| echo "→ Scanning for obfuscation patterns..." | ||
|
|
||
| # Packed/obfuscated code blocks (long base64-like strings, hex chains) | ||
| check_pattern \ | ||
| "Packed/obfuscated JavaScript blob (self-decoding function pattern)" \ | ||
| '(\w+),\s*\w+\s*=\s*function\s*\(\w+,\s*\w+,\s*\w+\)' \ | ||
| "HIGH" | ||
|
|
||
| # Large base64 strings (potential hidden payloads) | ||
| check_pattern \ | ||
| "Large base64-encoded string (≥100 chars, potential hidden payload)" \ | ||
| '['\''"][A-Za-z0-9+/=]{100,}['\''"]' \ | ||
| "HIGH" | ||
|
|
||
| # Hex-encoded strings | ||
| check_pattern \ | ||
| "Hex-encoded string ≥40 chars" \ | ||
| '\\x[0-9a-fA-F]{2}\\x[0-9a-fA-F]{2}\\x[0-9a-fA-F]{2}' \ | ||
| "MEDIUM" | ||
|
|
||
| # String-shuffle decoders | ||
| check_pattern \ | ||
| "String-shuffle / deobfuscation wrapper" \ | ||
| '\[\]\s*=\s*\(\w+\[\]\[\w+\]\+"\w+"\)' \ | ||
| "HIGH" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # 2. DANGEROUS RUNTIME PATTERNS IN BUILD FILES | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| echo "→ Scanning for suspicious patterns in build-config files..." | ||
|
|
||
| for pattern in 'global\['\''[!$]'\''\]' 'global\s*=\s*global'; do | ||
| for match in $(grep -l "$pattern" /tmp/pr-diff.txt 2>/dev/null || true); do | ||
| echo -e "${RED}[HIGH]${NC} Suspicious global assignment in build/config file: $match" | ||
| WARNINGS=$((WARNINGS + 1)) | ||
| done | ||
| done | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # 3. HIDDEN CODE EXECUTION | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| echo "→ Scanning for hidden code execution..." | ||
|
|
||
| # eval / Function / setTimeout with long strings (> 80 chars, likely obfuscated) | ||
| check_pattern \ | ||
| "Hidden eval/Function call with large argument" \ | ||
| '(?:eval|Function|setTimeout|setInterval)\s*\(\s*['\''"`][^)]{80,}['\''"`]\s*\)' \ | ||
| "HIGH" | ||
|
|
||
| # require/module rebinding | ||
| check_pattern \ | ||
| "require/module rebinding via global" \ | ||
| 'global\[.*\]\s*=\s*require' \ | ||
| "CRITICAL" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # 4. FILE-TYPE TARGETING | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| echo "→ Checking for targeted build-config file modifications..." | ||
|
|
||
| # Check if the PR modifies config files that auto-execute | ||
| CONFIG_FILES=( | ||
| 'astro.config.mjs' | ||
| 'astro.config.ts' | ||
| 'vite.config.ts' | ||
| 'vite.config.js' | ||
| 'next.config.js' | ||
| 'next.config.mjs' | ||
| 'webpack.config.js' | ||
| '.npmrc' | ||
| '.env' | ||
| 'package.json' | ||
| ) | ||
|
|
||
| for cf in "${CONFIG_FILES[@]}"; do | ||
| if grep -q "^.*${cf}\$" /tmp/pr-diff.txt 2>/dev/null; then | ||
| echo -e "${YELLOW}[INFO]${NC} PR modifies auto-exec config file: $cf — requires manual review" | ||
| WARNINGS=$((WARNINGS + 1)) | ||
| fi | ||
| done | ||
|
|
||
| echo "::endgroup::" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # RESULT | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| if [ "$WARNINGS" -gt 0 ]; then | ||
| echo "" | ||
| echo "⚠️ $WARNINGS suspicious pattern(s) detected — manual security review required before merging." | ||
| echo " See https://github.com/Egonex-AI/Understand-Anything/security/advisories for guidance." | ||
| exit 1 | ||
| else | ||
| echo "✅ No supply-chain obfuscation patterns detected." | ||
| exit 0 | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| name: Supply-Chain Security Scan | ||
|
|
||
| on: | ||
| pull_request: | ||
| # Trigger on any PR so we catch supply-chain attacks before review | ||
| types: [opened, synchronize, reopened, edited] | ||
| paths-ignore: | ||
| # Skip docs-only PRs (but NOT build config files) | ||
| - '**/*.md' | ||
| - '**/*.png' | ||
| - '**/*.svg' | ||
| - '**/*.jpg' | ||
|
|
||
| concurrency: | ||
| group: supply-chain-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| scan-obfuscation: | ||
| runs-on: ubuntu-latest | ||
| if: github.event.pull_request.head.repo.fork || github.event_name != 'pull_request_target' | ||
| # ^ Always runs for forks (highest risk). For non-fork PRs, runs on pull_request too. | ||
|
|
||
| steps: | ||
| - name: Checkout PR head | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Generate PR diff | ||
| run: | | ||
| git diff \ | ||
| ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} \ | ||
| > /tmp/pr-diff.txt | ||
| echo "Diff size: $(wc -c < /tmp/pr-diff.txt) bytes" | ||
| echo "Diff lines: $(wc -l < /tmp/pr-diff.txt)" | ||
|
|
||
| - name: Run obfuscation scanner | ||
| run: bash .github/scripts/scan-obfuscation.sh | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
|
|
||
| - name: Flag for manual review (non-blocking) | ||
| if: failure() | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
|
Comment on lines
+47
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In fork PRs, which this workflow explicitly targets, the Useful? React with 👍 / 👎. |
||
| body: `⚠️ **Supply-chain security scan detected suspicious patterns** in this PR. | ||
|
|
||
| The obfuscation scanner found code patterns commonly associated with supply-chain attacks (packed/obfuscated JavaScript, suspicious global assignments, hidden eval calls). | ||
|
|
||
| **Action required:** A maintainer must manually review the diff before merging. | ||
| See the [scan-obfuscation.sh](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/.github/scripts/scan-obfuscation.sh) script for details. | ||
|
|
||
| If this is a false positive, a maintainer can override this check. | ||
| For legitimate security concerns, please report via [Security Advisories](https://github.com/${context.repo.owner}/${context.repo.repo}/security/advisories/new).` | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the job checks out the PR head before this line, a malicious fork PR can change
.github/scripts/scan-obfuscation.shin the same PR to simplyexit 0or omit the dangerous patterns, so the supply-chain scan is bypassed exactly in the untrusted PRs it is meant to catch. Run the scanner from the base repository/workflow checkout or otherwise pin the script before checking out untrusted code.Useful? React with 👍 / 👎.