From eaa63fe3c69f59237f41b6a8c7698b366ebec6d3 Mon Sep 17 00:00:00 2001 From: songoten Date: Mon, 15 Jun 2026 19:21:04 +0700 Subject: [PATCH] fix: harden supply-chain security via obfuscation scanner + advisory policy - Add CI workflow (supply-chain-scan.yml) scanning PR diffs for obfuscation/supply-chain attack patterns - Add .github/scripts/scan-obfuscation.sh: detection of packed code, hidden eval, global hijack, base64/hex payloads, build-config targeting - Update SECURITY.md: actionable advisory link, email fallback, supply-chain as in-scope - Non-blocking: scan runs on all PRs, auto-comments when suspicious patterns found but does not block merge - Mitigates real-world supply-chain attacks seen in this repo (PR #198, #206, #261) --- .github/scripts/scan-obfuscation.sh | 134 ++++++++++++++++++++++++ .github/workflows/supply-chain-scan.yml | 60 +++++++++++ SECURITY.md | 20 ++-- 3 files changed, 208 insertions(+), 6 deletions(-) create mode 100755 .github/scripts/scan-obfuscation.sh create mode 100644 .github/workflows/supply-chain-scan.yml diff --git a/.github/scripts/scan-obfuscation.sh b/.github/scripts/scan-obfuscation.sh new file mode 100755 index 00000000..7c532c09 --- /dev/null +++ b/.github/scripts/scan-obfuscation.sh @@ -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 \ No newline at end of file diff --git a/.github/workflows/supply-chain-scan.yml b/.github/workflows/supply-chain-scan.yml new file mode 100644 index 00000000..b6de1441 --- /dev/null +++ b/.github/workflows/supply-chain-scan.yml @@ -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 + + - 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, + 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).` + }); \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md index a9fe3789..b8ca055d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,13 +4,16 @@ Thanks for taking the time to disclose responsibly. ## How to report -Please use GitHub's [private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) -on this repository. That keeps the report visible to the maintainer without -exposing the details publicly. +👉 **Please use the [Security Advisories](https://github.com/Egonex-AI/Understand-Anything/security/advisories/new) page** to privately report a vulnerability. +This sends the report directly to the maintainers and keeps details confidential +until a fix ships. -If private reporting is unavailable for any reason, open a regular issue -titled `security: brief description` **without** any exploit details, and -the maintainer will reply with a private channel. +If the Security Advisories page is unavailable for any reason, email +**security@egonex.ai** or open a regular issue titled `security: brief description` +**without** any exploit details, and the maintainer will reply with a private channel. + +> ⚠️ **Do not** submit vulnerability details in a public issue, pull request, or +> discussion — that puts every user at risk before a fix can ship. ## What to include @@ -42,6 +45,10 @@ Issues we care about: - The dashboard's file-content endpoint serving files outside the allowlist. - The `/understand` skill running shell commands derived from untrusted paths or contents. +- Supply-chain attacks via pull requests (obfuscated payloads, dependency + hijacking, build-time code execution from PR-diff content). +- Malicious PRs that modify build-config files (e.g. `astro.config.mjs`, + `vite.config.ts`, `next.config.js`) with obfuscated or packed code. Issues that are **out of scope**: @@ -49,3 +56,4 @@ Issues that are **out of scope**: analyzed project (they could just edit the source directly). - Anything that requires the user to copy a malicious URL and paste it back into the dashboard. +- Social-engineering-only attacks with no technical exploit.