torusguard 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.torusguard/.manifest.json +66 -63
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/.torusguard/rules_catalog.json +520 -0
- package/.torusguard/runs/report-latest.html +93 -7
- package/.torusguard/runs/run-20260912-214110-audit/findings.json +1256 -0
- package/.torusguard/runs/run-20260912-214110-audit/findings.md +534 -0
- package/.torusguard/runs/run-20260912-214110-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214110-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.json +992 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.md +422 -0
- package/.torusguard/runs/run-20260912-214813-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214813-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.json +530 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.md +232 -0
- package/.torusguard/runs/run-20260912-215555-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260912-215555-audit/remediation.md +102 -0
- package/.torusguard/runs/run-20260912-215555-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215731-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/minimal_patch_plan.md +22 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/patch.diff +10 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/diff_summary.md +186 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.json +497 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.md +218 -0
- package/.torusguard/runs/run-20260912-215731-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260912-215731-audit/recheck.md +76 -0
- package/.torusguard/runs/run-20260912-215731-audit/remediation.md +234 -0
- package/.torusguard/runs/run-20260912-215731-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.json +68 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.md +36 -0
- package/.torusguard/runs/run-20260912-220134-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220134-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220200-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220200-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220200-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220227-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220227-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220227-audit/summary.md +5 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/report_sync.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +383 -377
- package/.torusguard/scripts/audit_runner.py +1306 -653
- package/.torusguard/scripts/finding_scorer.py +14 -2
- package/.torusguard/scripts/harden_runner.py +628 -455
- package/.torusguard/scripts/recheck_runner.py +248 -238
- package/.torusguard/scripts/recipes_runner.py +137 -137
- package/.torusguard/scripts/report_sync.py +423 -0
- package/.torusguard/scripts/sarif_exporter.py +116 -116
- package/.torusguard/scripts/term_ui.py +162 -162
- package/.torusguard/snapshots/run-20260912-215731-audit/demo/playground/vulnerable_nextjs/actions.ts.bak +24 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/hardened-react-express/server/index.js.bak +121 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/python/fastapi-vuln/main.py.bak +20 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/vite.config.js.bak +12 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/workflows/apply.md +11 -4
- package/.torusguard/workflows/audit.md +7 -1
- package/.torusguard/workflows/authorize.md +2 -1
- package/.torusguard/workflows/exploit-check.md +2 -1
- package/.torusguard/workflows/harden.md +7 -1
- package/.torusguard/workflows/init.md +6 -1
- package/.torusguard/workflows/memory.md +2 -1
- package/.torusguard/workflows/recheck.md +7 -1
- package/.torusguard/workflows/report.md +7 -1
- package/.torusguard/workflows/status.md +6 -1
- package/.torusguard/workflows/verify.md +6 -1
- package/.torusguard/workflows/web-validate.md +2 -1
- package/README.md +470 -345
- package/bin/torusguard.js +550 -545
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +73 -72
- package/skills/torusguard/payload/.manifest.json +66 -63
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/skills/torusguard/payload/rules_catalog.json +520 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +383 -377
- package/skills/torusguard/payload/scripts/audit_runner.py +1306 -653
- package/skills/torusguard/payload/scripts/finding_scorer.py +14 -2
- package/skills/torusguard/payload/scripts/harden_runner.py +628 -455
- package/skills/torusguard/payload/scripts/recheck_runner.py +248 -238
- package/skills/torusguard/payload/scripts/recipes_runner.py +137 -137
- package/skills/torusguard/payload/scripts/report_sync.py +423 -0
- package/skills/torusguard/payload/scripts/sarif_exporter.py +116 -116
- package/skills/torusguard/payload/scripts/term_ui.py +162 -162
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +75 -72
- package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +7 -2
- package/skills/torusguard/payload/workflows/apply.md +11 -4
- package/skills/torusguard/payload/workflows/audit.md +7 -1
- package/skills/torusguard/payload/workflows/authorize.md +2 -1
- package/skills/torusguard/payload/workflows/exploit-check.md +2 -1
- package/skills/torusguard/payload/workflows/harden.md +7 -1
- package/skills/torusguard/payload/workflows/init.md +6 -1
- package/skills/torusguard/payload/workflows/memory.md +2 -1
- package/skills/torusguard/payload/workflows/recheck.md +7 -1
- package/skills/torusguard/payload/workflows/report.md +7 -1
- package/skills/torusguard/payload/workflows/status.md +6 -1
- package/skills/torusguard/payload/workflows/verify.md +6 -1
- package/skills/torusguard/payload/workflows/web-validate.md +2 -1
- package/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard-web-validate/SKILL.md +7 -2
|
@@ -1,37 +1,44 @@
|
|
|
1
|
-
# TG-CACHE-003: Sensitive Data in URL
|
|
1
|
+
# TG-CACHE-003: Sensitive Data in URL Query Parameters
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Medium. Passing API keys, session tokens, passwords, or PII in URL query parameters causes secrets to be persisted in browser histories, web server access logs, and HTTP `Referer` headers.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Authentication Flows, Invitation Links, Reset Handlers
|
|
8
|
+
- Frontend JS, Express, Django, FastAPI, Go, PHP
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
URLs are routinely logged in plaintext by reverse proxies, load balancers, CDN providers, and browser histories. If tokens are in query strings (`/login?token=xyz`), any external asset loaded on the page receives the token in the `Referer` header.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Query parameter patterns matching `api_key=`, `token=`, `secret=`, or `password=` in GET routes.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Accepting credentials or tokens in URL query string
|
|
19
|
+
app.get('/api/auth/callback', (req, res) => {
|
|
20
|
+
const { apiKey, password } = req.query;
|
|
21
|
+
authenticate(apiKey, password);
|
|
22
|
+
});
|
|
18
23
|
```
|
|
19
24
|
|
|
20
25
|
## Safe Example
|
|
21
26
|
```javascript
|
|
22
|
-
//
|
|
27
|
+
// SAFE: Passing credentials in Authorization header or POST request body
|
|
28
|
+
app.post('/api/auth/token', (req, res) => {
|
|
29
|
+
const { apiKey, password } = req.body;
|
|
30
|
+
authenticate(apiKey, password);
|
|
31
|
+
});
|
|
23
32
|
```
|
|
24
33
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
34
|
+
## Ponytail Remediation Budget
|
|
35
|
+
- Additions: <= 6 lines
|
|
36
|
+
- Deletions: <= 3 lines
|
|
32
37
|
|
|
33
|
-
##
|
|
34
|
-
|
|
38
|
+
## Remediation
|
|
39
|
+
1. Migrate authentication parameters to `Authorization: Bearer` headers or JSON request bodies via POST.
|
|
40
|
+
2. Strip sensitive query parameters from URLs using history replace state before page render.
|
|
35
41
|
|
|
36
42
|
## Related Rules
|
|
37
|
-
- TG-
|
|
43
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
44
|
+
- `TG-SEC-004`: Sensitive Information in Logs
|
|
@@ -1,37 +1,50 @@
|
|
|
1
1
|
# TG-CSRF-001: Missing CSRF Protection
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. State-changing endpoints (POST, PUT, DELETE, PATCH) that rely on ambient credentials (cookies, basic auth) without CSRF tokens or SameSite cookie protection allow malicious third-party websites to execute actions on behalf of authenticated users.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Traditional Form Submissions, Cookie-Authenticated REST APIs
|
|
8
|
+
- Express (csurf), Django, Flask (Flask-WTF), Rails, Spring Security, ASP.NET Core
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
If a banking or SaaS application authenticates requests solely via browser cookies, a user visiting a malicious site can be tricked into submitting unauthorized form requests that the browser will automatically authenticate with the user's cookies.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- State-changing route handlers lacking CSRF middleware, CSRF tokens in headers, or explicit SameSite cookie configurations.
|
|
15
|
+
- Explicit disabling of CSRF protection (e.g. `@csrf_exempt`, `csrf().disable()`).
|
|
14
16
|
|
|
15
17
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
+
```python
|
|
19
|
+
# UNSAFE: Disabling CSRF protection on state-changing endpoint
|
|
20
|
+
from django.views.decorators.csrf import csrf_exempt
|
|
21
|
+
|
|
22
|
+
@csrf_exempt
|
|
23
|
+
def update_email(request):
|
|
24
|
+
request.user.email = request.POST.get("email")
|
|
25
|
+
request.user.save()
|
|
18
26
|
```
|
|
19
27
|
|
|
20
28
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
29
|
+
```python
|
|
30
|
+
# SAFE: Enforcing CSRF token verification
|
|
31
|
+
from django.views.decorators.csrf import csrf_protect
|
|
32
|
+
|
|
33
|
+
@csrf_protect
|
|
34
|
+
def update_email(request):
|
|
35
|
+
request.user.email = request.POST.get("email")
|
|
36
|
+
request.user.save()
|
|
23
37
|
```
|
|
24
38
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
39
|
+
## Ponytail Remediation Budget
|
|
40
|
+
- Additions: <= 4 lines
|
|
41
|
+
- Deletions: <= 2 lines
|
|
32
42
|
|
|
33
|
-
##
|
|
34
|
-
|
|
43
|
+
## Remediation
|
|
44
|
+
1. Never disable framework CSRF protection with `@csrf_exempt` or `csrf().disable()`.
|
|
45
|
+
2. Configure session cookies with `SameSite: 'Lax'` or `'Strict'`.
|
|
46
|
+
3. For single-page applications, validate custom headers (e.g. `X-Requested-With`, `X-CSRF-Token`).
|
|
35
47
|
|
|
36
48
|
## Related Rules
|
|
37
|
-
- TG-
|
|
49
|
+
- `TG-AUTH-004`: Insecure Session Cookie Configuration
|
|
50
|
+
- `TG-PLATFORM-001`: Wildcard CORS With Credentials
|
|
@@ -1,37 +1,48 @@
|
|
|
1
|
-
# TG-CSRF-002: Unsafe Credentialed Cross-Origin
|
|
1
|
+
# TG-CSRF-002: Unsafe Credentialed Cross-Origin Requests
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Enabling credentialed cross-origin access (`credentials: true` / `Access-Control-Allow-Credentials: true`) combined with dynamic reflection of incoming `Origin` headers allows any untrusted domain to read authenticated responses.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- CORS Middleware Configurations
|
|
8
|
+
- Express (cors), FastAPI, Flask-CORS, Django-cors-headers, Spring Security
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
When a server blindly reflects the `Origin` header while allowing credentials, any malicious site visited by an authenticated user can make cross-origin requests and read private user data, completely circumventing the Same-Origin Policy.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- CORS configurations reflecting `req.headers.origin` directly when `credentials: true` is enabled.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Blindly reflecting any origin with credentials enabled
|
|
19
|
+
app.use(cors({
|
|
20
|
+
origin: (origin, callback) => callback(null, true),
|
|
21
|
+
credentials: true
|
|
22
|
+
}));
|
|
18
23
|
```
|
|
19
24
|
|
|
20
25
|
## Safe Example
|
|
21
26
|
```javascript
|
|
22
|
-
//
|
|
27
|
+
// SAFE: Strictly validating origin against an explicit environment allowlist
|
|
28
|
+
const allowedOrigins = (process.env.ALLOWED_ORIGINS || 'https://app.example.com').split(',');
|
|
29
|
+
app.use(cors({
|
|
30
|
+
origin: (origin, callback) => {
|
|
31
|
+
if (!origin || allowedOrigins.includes(origin)) return callback(null, true);
|
|
32
|
+
callback(new Error('Blocked by CORS'));
|
|
33
|
+
},
|
|
34
|
+
credentials: true
|
|
35
|
+
}));
|
|
23
36
|
```
|
|
24
37
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
38
|
+
## Ponytail Remediation Budget
|
|
39
|
+
- Additions: <= 8 lines
|
|
40
|
+
- Deletions: <= 4 lines
|
|
32
41
|
|
|
33
|
-
##
|
|
34
|
-
|
|
42
|
+
## Remediation
|
|
43
|
+
1. Restrict CORS origins to a static, verified allowlist stored in environment variables.
|
|
44
|
+
2. Never reflect untrusted `req.headers.origin` when credentials are permitted.
|
|
35
45
|
|
|
36
46
|
## Related Rules
|
|
37
|
-
- TG-
|
|
47
|
+
- `TG-PLATFORM-001`: Wildcard CORS With Credentials
|
|
48
|
+
- `TG-CSRF-001`: Missing CSRF Protection
|
|
@@ -1,37 +1,53 @@
|
|
|
1
|
-
# TG-GQL-002: Resolver Missing Authorization
|
|
1
|
+
# TG-GQL-002: GraphQL Resolver Missing Authorization
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
High
|
|
4
|
+
High. Exposing GraphQL mutation or query resolvers without granular user ownership or role authorization checks allows authenticated users to query or mutate records belonging to other tenants.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- GraphQL Servers (Apollo Server, Yoga, Pothos, Graphene)
|
|
8
|
+
- Node.js, Python, Go, Java
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
In GraphQL, nested queries allow clients to traverse relationships (e.g. `user { organization { members { invoices } } }`). If individual field resolvers fail to assert ownership, users can traverse schema graphs to access unauthorized tenant resources.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- GraphQL resolver functions querying database entities directly by `args.id` without checking `context.user` or filtering by `context.tenantId`.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Querying invoice directly by ID without checking user or tenant
|
|
19
|
+
const resolvers = {
|
|
20
|
+
Query: {
|
|
21
|
+
invoice: async (_, { id }) => {
|
|
22
|
+
return await db.invoice.findUnique({ where: { id } });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
18
26
|
```
|
|
19
27
|
|
|
20
28
|
## Safe Example
|
|
21
29
|
```javascript
|
|
22
|
-
//
|
|
30
|
+
// SAFE: Scoping query by tenant and authenticated user context
|
|
31
|
+
const resolvers = {
|
|
32
|
+
Query: {
|
|
33
|
+
invoice: async (_, { id }, context) => {
|
|
34
|
+
if (!context.user) throw new Error('Unauthorized');
|
|
35
|
+
return await db.invoice.findFirst({
|
|
36
|
+
where: { id, tenantId: context.user.tenantId }
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
23
41
|
```
|
|
24
42
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
43
|
+
## Ponytail Remediation Budget
|
|
44
|
+
- Additions: <= 8 lines
|
|
45
|
+
- Deletions: <= 2 lines
|
|
32
46
|
|
|
33
|
-
##
|
|
34
|
-
|
|
47
|
+
## Remediation
|
|
48
|
+
1. Enforce shield/guard middleware or resolver-level ownership checks on all query and mutation fields.
|
|
49
|
+
2. Pass authenticated `context` to all database queries and enforce `tenantId` constraints.
|
|
35
50
|
|
|
36
51
|
## Related Rules
|
|
37
|
-
- TG-
|
|
52
|
+
- `TG-DB-004`: Missing Multi-Tenant Query Isolation
|
|
53
|
+
- `TG-AUTH-003`: Missing Object-Level Authorization (IDOR)
|
|
@@ -1,37 +1,52 @@
|
|
|
1
1
|
# TG-GQL-003: Unbounded GraphQL Pagination or Batching
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Medium. Permitting unbounded `first`, `limit`, or batching queries in GraphQL enables resource exhaustion and Denial of Service (DoS).
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Apollo Server, GraphQL Yoga, Graphene
|
|
8
|
+
- Node.js, Python, Go
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Clients can request `users(first: 1000000)` or send a batched array of 500 queries in a single HTTP request, forcing the server to exhaust memory and database connection pools.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Resolvers accepting integer `first` / `limit` arguments without enforcing a maximum cap (e.g. `Math.min(limit, 100)`).
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Directly passing client-controlled limit to database
|
|
19
|
+
const resolvers = {
|
|
20
|
+
Query: {
|
|
21
|
+
users: async (_, { limit = 50 }) => {
|
|
22
|
+
return await db.user.findMany({ take: limit }); // Attacker passes limit: 500000
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
18
26
|
```
|
|
19
27
|
|
|
20
28
|
## Safe Example
|
|
21
29
|
```javascript
|
|
22
|
-
//
|
|
30
|
+
// SAFE: Enforcing strict maximum upper bound on pagination
|
|
31
|
+
const MAX_LIMIT = 100;
|
|
32
|
+
const resolvers = {
|
|
33
|
+
Query: {
|
|
34
|
+
users: async (_, { limit = 20 }) => {
|
|
35
|
+
const safeLimit = Math.min(Math.max(1, limit), MAX_LIMIT);
|
|
36
|
+
return await db.user.findMany({ take: safeLimit });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
23
40
|
```
|
|
24
41
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
42
|
+
## Ponytail Remediation Budget
|
|
43
|
+
- Additions: <= 5 lines
|
|
44
|
+
- Deletions: <= 2 lines
|
|
32
45
|
|
|
33
|
-
##
|
|
34
|
-
|
|
46
|
+
## Remediation
|
|
47
|
+
1. Enforce maximum limit boundaries on all pagination arguments.
|
|
48
|
+
2. Disable batched HTTP query execution unless explicitly required.
|
|
35
49
|
|
|
36
50
|
## Related Rules
|
|
37
|
-
- TG-
|
|
51
|
+
- `TG-RATE-003`: Unbounded Resource Consumption
|
|
52
|
+
- `TG-GQL-001`: Missing Query Depth Limits
|
|
@@ -1,37 +1,46 @@
|
|
|
1
1
|
# TG-GQL-004: Unnecessary Production Introspection
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Medium. Enabling GraphQL schema introspection in production environments reveals full schema types, queries, mutations, and deprecated fields to external attackers.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- GraphQL Servers (Apollo, Yoga, Mercurius, Helix)
|
|
8
|
+
- Production Node.js, Python, Go deployments
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
While introspection powers developer tools like Apollo Studio and GraphiQL, in production it provides attackers with an automated blueprint of the internal API surface, administrative fields, and hidden parameters.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- GraphQL server initialization setting `introspection: true` or failing to disable introspection when `NODE_ENV === 'production'`.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Introspection unconditionally enabled
|
|
19
|
+
const server = new ApolloServer({
|
|
20
|
+
typeDefs,
|
|
21
|
+
resolvers,
|
|
22
|
+
introspection: true
|
|
23
|
+
});
|
|
18
24
|
```
|
|
19
25
|
|
|
20
26
|
## Safe Example
|
|
21
27
|
```javascript
|
|
22
|
-
//
|
|
28
|
+
// SAFE: Introspection restricted to non-production environments
|
|
29
|
+
const server = new ApolloServer({
|
|
30
|
+
typeDefs,
|
|
31
|
+
resolvers,
|
|
32
|
+
introspection: process.env.NODE_ENV !== 'production'
|
|
33
|
+
});
|
|
23
34
|
```
|
|
24
35
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
36
|
+
## Ponytail Remediation Budget
|
|
37
|
+
- Additions: <= 2 lines
|
|
38
|
+
- Deletions: <= 2 lines
|
|
32
39
|
|
|
33
|
-
##
|
|
34
|
-
|
|
40
|
+
## Remediation
|
|
41
|
+
1. Bind `introspection` to environment checks (`process.env.NODE_ENV !== 'production'`).
|
|
42
|
+
2. Disable GraphQL Playground and Apollo Sandbox in production.
|
|
35
43
|
|
|
36
44
|
## Related Rules
|
|
37
|
-
- TG-
|
|
45
|
+
- `TG-PLATFORM-003`: Production Stack Trace Exposure
|
|
46
|
+
- `TG-CLIENT-001`: Public Production Source Maps
|
|
@@ -1,37 +1,42 @@
|
|
|
1
|
-
# TG-SEC-005: Secret in Git History
|
|
1
|
+
# TG-SEC-005: Secret or Private Key in Git History
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Committing private API keys, credentials, or private certificates into git history persists them permanently across all cloned repositories, even if deleted in subsequent commits.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Git Repositories, Public and Private Remotes
|
|
8
|
+
- All Languages & Frameworks
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Deleting a secret file in a follow-up commit (`git rm .env`) does NOT remove it from git history. Attackers clone public repositories and run scanners (`git log -p`) to extract historical secrets within seconds.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Git commit objects or patch diffs containing private keys, AWS access keys, or JWT secret strings.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```bash
|
|
18
|
+
# UNSAFE: Adding .env with live credentials directly to git tracking
|
|
19
|
+
git add .env
|
|
20
|
+
git commit -m "Add production database credentials"
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
24
|
+
```bash
|
|
25
|
+
# SAFE: Keeping .env in .gitignore; using .env.example with placeholder tokens
|
|
26
|
+
echo ".env" >> .gitignore
|
|
27
|
+
git add .gitignore .env.example
|
|
28
|
+
git commit -m "Add environment configuration baseline"
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
31
|
+
## Ponytail Remediation Budget
|
|
32
|
+
- Additions: <= 2 lines
|
|
33
|
+
- Deletions: <= 2 lines
|
|
32
34
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
+
## Remediation
|
|
36
|
+
1. Immediately rotate any secret that was committed to git history.
|
|
37
|
+
2. Use tools like `git-filter-repo` or BFG Repo-Cleaner to purge the commit blob from repository history.
|
|
38
|
+
3. Add `.env` and `*.pem` to `.gitignore`.
|
|
35
39
|
|
|
36
40
|
## Related Rules
|
|
37
|
-
- TG-
|
|
41
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
42
|
+
- `TG-SEC-003`: Unencrypted Secret in Tracked Config File
|
|
@@ -1,37 +1,54 @@
|
|
|
1
|
-
# TG-SEC-006: Secret in Build Artifact
|
|
1
|
+
# TG-SEC-006: Secret in Build Artifact or Container Image
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Copying `.env` files, build-time secrets, or SSH keys into Docker build layers persists secrets in image layers, allowing anyone with pull access to extract credentials via `docker history` or container inspection.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Dockerfiles, Container Builds, Serverless Bundle Artifacts
|
|
8
|
+
- Docker, Containerd, Podman, Webpack, Vite
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Docker image layers are cached and stored individually. Running `COPY .env .` followed by `RUN rm .env` still retains the `.env` file in the preceding layer blob, allowing trivial credential recovery.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Dockerfile instructions containing `COPY .env` or `ARG SECRET_KEY` without BuildKit secret mount protection.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```dockerfile
|
|
18
|
+
# UNSAFE: Copying local .env into container layer
|
|
19
|
+
FROM node:20-alpine
|
|
20
|
+
WORKDIR /app
|
|
21
|
+
COPY package*.json ./
|
|
22
|
+
RUN npm ci
|
|
23
|
+
COPY .env .
|
|
24
|
+
COPY . .
|
|
25
|
+
RUN npm run build
|
|
18
26
|
```
|
|
19
27
|
|
|
20
28
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
29
|
+
```dockerfile
|
|
30
|
+
# SAFE: Using BuildKit secret mounts or multi-stage build without persisting secrets
|
|
31
|
+
# syntax=docker/dockerfile:1.4
|
|
32
|
+
FROM node:20-alpine AS builder
|
|
33
|
+
WORKDIR /app
|
|
34
|
+
COPY package*.json ./
|
|
35
|
+
RUN npm ci
|
|
36
|
+
COPY . .
|
|
37
|
+
RUN --mount=type=secret,id=build_secrets npm run build
|
|
38
|
+
|
|
39
|
+
FROM node:20-alpine
|
|
40
|
+
WORKDIR /app
|
|
41
|
+
COPY --from=builder /app/dist ./dist
|
|
23
42
|
```
|
|
24
43
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
44
|
+
## Ponytail Remediation Budget
|
|
45
|
+
- Additions: <= 5 lines
|
|
46
|
+
- Deletions: <= 2 lines
|
|
32
47
|
|
|
33
|
-
##
|
|
34
|
-
|
|
48
|
+
## Remediation
|
|
49
|
+
1. Use Docker BuildKit secret mounts (`--mount=type=secret`) for credentials needed during build.
|
|
50
|
+
2. Use multi-stage Docker builds to ensure final runtime images only contain compiled frontend assets.
|
|
35
51
|
|
|
36
52
|
## Related Rules
|
|
37
|
-
- TG-
|
|
53
|
+
- `TG-SUPPLY-006`: Container Build Secret Persistence
|
|
54
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
# TG-SEC-007: Secret in Test or Example Fixture
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Medium. Committing real production or staging credentials into test fixtures, mocks, or example configuration files leaks secrets under the assumption that test directories are unmonitored.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Test Suites, Mock Fixtures, Example Configs
|
|
8
|
+
- All Languages & Frameworks
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Developers often copy live payload captures from production to create integration tests or seed fixtures. If these fixtures contain real API keys or customer JWT tokens, they are exposed in source control.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- High-entropy tokens, Stripe live keys (`sk_live_`), or valid JWT signatures present in `tests/`, `fixtures/`, or `examples/` directories.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Real active production API key used in test fixture
|
|
19
|
+
const mockAuth = {
|
|
20
|
+
apiKey: "sk_live_51M0...REAL_STRIPE_LIVE_KEY_12345"
|
|
21
|
+
};
|
|
18
22
|
```
|
|
19
23
|
|
|
20
24
|
## Safe Example
|
|
21
25
|
```javascript
|
|
22
|
-
//
|
|
26
|
+
// SAFE: Explicit synthetic mock sentinel string
|
|
27
|
+
const mockAuth = {
|
|
28
|
+
apiKey: "sk_test_fake_mock_token_for_unit_tests_only"
|
|
29
|
+
};
|
|
23
30
|
```
|
|
24
31
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
32
|
+
## Ponytail Remediation Budget
|
|
33
|
+
- Additions: <= 2 lines
|
|
34
|
+
- Deletions: <= 2 lines
|
|
32
35
|
|
|
33
|
-
##
|
|
34
|
-
|
|
36
|
+
## Remediation
|
|
37
|
+
1. Replace all real credentials in test directories with synthetic, inert mock sentinels (`test_token_dummy`).
|
|
38
|
+
2. Rotate any credentials that were copied from production to test files.
|
|
35
39
|
|
|
36
40
|
## Related Rules
|
|
37
|
-
- TG-
|
|
41
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
42
|
+
- `TG-SEC-004`: Sensitive Information in Logs
|