name: Scheduled Security Scan on: schedule: - cron: "17 3 * * 1" workflow_dispatch: jobs: security-scan: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Detect project stack id: detect shell: bash run: | stacks="" [ -f package.json ] && stacks="${stacks} node" { [ -f pyproject.toml ] || [ -f requirements.txt ]; } && stacks="${stacks} python" [ -f Cargo.toml ] && stacks="${stacks} rust" [ -f go.mod ] && stacks="${stacks} go" { [ -f Dockerfile ] || [ -f compose.yml ] || [ -f docker-compose.yml ]; } && stacks="${stacks} docker" echo "stacks=${stacks:-generic}" >> "$GITHUB_OUTPUT" echo "Detected stacks:${stacks:- generic}" - name: Node production dependency audit if: contains(steps.detect.outputs.stacks, 'node') run: npm audit --omit=dev --audit-level=high - name: Python dependency audit if: contains(steps.detect.outputs.stacks, 'python') shell: bash run: | python -m pip install --upgrade pip pip-audit if [ -f requirements.txt ]; then pip-audit -r requirements.txt else pip-audit fi - name: Rust dependency audit if: contains(steps.detect.outputs.stacks, 'rust') shell: bash run: | cargo install cargo-audit --locked cargo audit - name: Go vulnerability scan if: contains(steps.detect.outputs.stacks, 'go') shell: bash run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./... - name: Suspicious code pattern scan shell: bash run: | grep_excludes=( --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build --exclude-dir=release --exclude=security-scan.yml ) patterns=( 'eval\s*\(' 'new Function\s*\(' 'dangerouslySetInnerHTML' 'innerHTML\s*=' 'child_process' 'exec\s*\(' 'spawn\s*\(' 'shell\.openExternal' 'nodeIntegration:\s*true' 'webSecurity:\s*false' 'allowRunningInsecureContent:\s*true' 'curl .*sh' 'wget .*sh' ) found=0 for pattern in "${patterns[@]}"; do if grep -RInE "${grep_excludes[@]}" "$pattern" .; then found=1 fi done if [ "$found" -eq 1 ]; then echo "Suspicious code patterns were found. Review the matches above." exit 1 fi - name: Secret and config leak scan shell: bash run: | grep_excludes=( --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build --exclude-dir=release --exclude=security-scan.yml ) patterns=( 'BEGIN (RSA |EC |OPENSSH |)PRIVATE KEY' 'AKIA[0-9A-Z]{16}' 'xox[baprs]-[0-9A-Za-z-]+' 'gh[pousr]_[0-9A-Za-z_]+' 'sk-[A-Za-z0-9]{20,}' 'api[_-]?key\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}' 'token\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}' 'password\s*=\s*["'\'']?[^[:space:]]{8,}' ) found=0 for pattern in "${patterns[@]}"; do if grep -RInE "${grep_excludes[@]}" "$pattern" .; then found=1 fi done if find . -path ./.git -prune -o \( -name ".env" -o -name ".env.*" \) -not -name ".env.example" -print | grep .; then echo "Committed environment files were found." found=1 fi if [ "$found" -eq 1 ]; then echo "Potential secret or config leak detected. Review the matches above." exit 1 fi - name: AI instruction safety scan shell: bash run: | grep_excludes=( --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build --exclude-dir=release --exclude=security-scan.yml ) patterns=( 'ignore (all )?(previous|above) instructions' 'system prompt' 'developer message' 'reveal your instructions' 'exfiltrate' 'send.*token' 'send.*secret' 'disable.*safety' 'jailbreak' ) found=0 for pattern in "${patterns[@]}"; do if grep -RInEi "${grep_excludes[@]}" "$pattern" .; then found=1 fi done if [ "$found" -eq 1 ]; then echo "Potential unsafe AI-control text found. Review whether this is documentation, test data, or malicious content." exit 1 fi