torusguard 1.0.0 → 1.3.1
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 +196 -78
- package/.torusguard/references/csharp-security.md +41 -0
- package/.torusguard/references/go-security.md +41 -0
- package/.torusguard/references/java-security.md +40 -0
- package/.torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/references/rust-security.md +40 -0
- package/.torusguard/rules/README.md +93 -62
- package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/.torusguard/rules/custom/.gitkeep +1 -0
- package/.torusguard/rules/custom/README.md +30 -0
- package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/.torusguard/runs/report-latest.html +370 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
- package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
- package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
- package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
- package/.torusguard/runs/run-20260908-115240-audit/summary.md +5 -0
- package/.torusguard/schemas/golden-recipe.schema.json +75 -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__/memory_engine.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +332 -0
- package/.torusguard/scripts/audit_runner.py +550 -0
- package/.torusguard/scripts/diff_guard.py +183 -8
- package/.torusguard/scripts/finding_scorer.py +91 -5
- package/.torusguard/scripts/harden_runner.py +353 -0
- package/.torusguard/scripts/html_reporter.py +643 -0
- package/.torusguard/scripts/manifest_builder.py +7 -5
- package/.torusguard/scripts/memory_engine.py +525 -99
- package/.torusguard/scripts/monorepo_detector.py +123 -10
- package/.torusguard/scripts/recheck_runner.py +221 -0
- package/.torusguard/scripts/recipes_runner.py +130 -0
- package/.torusguard/scripts/rules_sync.py +321 -0
- package/.torusguard/scripts/run_manager.py +17 -5
- package/.torusguard/scripts/stack_detect.py +458 -26
- package/.torusguard/skills/torusguard/SKILL.md +42 -42
- package/.torusguard/skills/torusguard/references/csharp-security.md +41 -0
- package/.torusguard/skills/torusguard/references/go-security.md +41 -0
- package/.torusguard/skills/torusguard/references/java-security.md +40 -0
- package/.torusguard/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/skills/torusguard/references/rust-security.md +40 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
- package/README.md +344 -410
- package/bin/torusguard.js +195 -21
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/bootstrap.py +149 -70
- package/skills/torusguard/payload/.manifest.json +196 -78
- package/skills/torusguard/payload/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/references/go-security.md +41 -0
- package/skills/torusguard/payload/references/java-security.md +40 -0
- package/skills/torusguard/payload/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/references/rust-security.md +40 -0
- package/skills/torusguard/payload/rules/README.md +93 -62
- package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/skills/torusguard/payload/rules/custom/.gitkeep +1 -0
- package/skills/torusguard/payload/rules/custom/README.md +30 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/skills/torusguard/payload/schemas/golden-recipe.schema.json +75 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +332 -0
- package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +183 -8
- package/skills/torusguard/payload/scripts/finding_scorer.py +91 -5
- package/skills/torusguard/payload/scripts/harden_runner.py +353 -0
- package/skills/torusguard/payload/scripts/html_reporter.py +643 -0
- package/skills/torusguard/payload/scripts/manifest_builder.py +7 -5
- package/skills/torusguard/payload/scripts/memory_engine.py +525 -99
- package/skills/torusguard/payload/scripts/monorepo_detector.py +123 -10
- package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
- package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
- package/skills/torusguard/payload/scripts/rules_sync.py +321 -0
- package/skills/torusguard/payload/scripts/run_manager.py +17 -5
- package/skills/torusguard/payload/scripts/stack_detect.py +458 -26
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +149 -70
- package/skills/torusguard/payload/skills/torusguard/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/go-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/java-security.md +40 -0
- package/skills/torusguard/payload/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/skills/torusguard/references/rust-security.md +40 -0
- package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
- package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# TG-SEC-001: Hardcoded Secrets in Tracked Source
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
Critical
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- JavaScript, TypeScript, Python, Go, Java, C#, Ruby, PHP
|
|
8
|
+
- Backend services, scripts, CI helpers, and shared utilities
|
|
9
|
+
- Any tracked file in `src/`, `app/`, `server/`, `api/`, `scripts/`, or `lib/`
|
|
10
|
+
- Infrastructure manifests that can hold credentials
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Hardcoded secrets in source control are frequently harvested by automated scanners within minutes of exposure.
|
|
14
|
+
Once committed, credentials may remain accessible through forks, clones, build logs, and historical refs even after removal.
|
|
15
|
+
Leaked API keys, JWT secrets, passwords, and database URLs can enable privilege escalation, data exfiltration, and account takeover.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- String literals assigned to names such as `apiKey`, `token`, `jwtSecret`, `password`, `dbUrl`, `connectionString`
|
|
19
|
+
- Credential-shaped values in code, including:
|
|
20
|
+
- Long base64-like tokens
|
|
21
|
+
- Hex secrets
|
|
22
|
+
- URLs with embedded credentials (`protocol://user:pass@host`)
|
|
23
|
+
- Insecure defaults like `JWT_SECRET = "change-me"` left in tracked files
|
|
24
|
+
- Commented-out credentials that still exist in committed code
|
|
25
|
+
- Secret values in configuration source files (`.ts`, `.js`, `.py`, `.yaml`, `.json`)
|
|
26
|
+
|
|
27
|
+
## Unsafe Example
|
|
28
|
+
```ts
|
|
29
|
+
// src/auth/session.ts
|
|
30
|
+
import jwt from "jsonwebtoken";
|
|
31
|
+
|
|
32
|
+
const JWT_SECRET = "prod_jwt_secret_8392b76ed18bb1";
|
|
33
|
+
const adminPassword = "S3rv!ce-Adm1n-Temp";
|
|
34
|
+
const dbUrl = "postgres://app_user:PlainTextPass@db.internal:5432/payments";
|
|
35
|
+
|
|
36
|
+
export function signSession(payload: object) {
|
|
37
|
+
return jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Safe Example
|
|
42
|
+
```ts
|
|
43
|
+
// src/auth/session.ts
|
|
44
|
+
import jwt from "jsonwebtoken";
|
|
45
|
+
|
|
46
|
+
const JWT_SECRET = process.env.JWT_SECRET;
|
|
47
|
+
const DB_URL = process.env.DATABASE_URL;
|
|
48
|
+
|
|
49
|
+
if (!JWT_SECRET) {
|
|
50
|
+
throw new Error("Missing JWT_SECRET environment variable");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function signSession(payload: object) {
|
|
54
|
+
return jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Remediation (numbered)
|
|
59
|
+
1. Remove hardcoded credentials from tracked source files immediately.
|
|
60
|
+
2. Move all secrets to environment variables or a managed secrets provider.
|
|
61
|
+
3. Rotate every exposed key, password, token, and signing secret.
|
|
62
|
+
4. Invalidate active sessions or tokens derived from leaked secrets.
|
|
63
|
+
5. Rewrite affected git history if required by policy and incident scope.
|
|
64
|
+
6. Add pre-commit and CI secret scanning to prevent recurrence.
|
|
65
|
+
7. Document the incident, impact, and completed rotations for auditability.
|
|
66
|
+
|
|
67
|
+
## Verification
|
|
68
|
+
- Search the repository for secret-like assignments and literal credentials.
|
|
69
|
+
- Confirm runtime configuration loads from environment or secret manager.
|
|
70
|
+
- Validate rotated credentials by checking old values no longer authenticate.
|
|
71
|
+
- Review CI and deployment settings to ensure secret injection is externalized.
|
|
72
|
+
- Ensure no credential-shaped literals remain in tracked source paths.
|
|
73
|
+
|
|
74
|
+
## False Positives and Exceptions
|
|
75
|
+
- Example/test fixtures are acceptable only when values are obviously fake.
|
|
76
|
+
- Non-sensitive identifiers (public analytics IDs, harmless tenant IDs) may match patterns.
|
|
77
|
+
- Internal placeholder strings are allowed if they are non-functional and non-deployable.
|
|
78
|
+
- Exception approvals should be documented with justification and owner.
|
|
79
|
+
|
|
80
|
+
## Related Rules
|
|
81
|
+
- [TG-SEC-002](./TG-SEC-002-public-environment-secrets.md) - Public environment variable secret exposure
|
|
82
|
+
- [TG-SEC-003](./TG-SEC-003-tracked-env-file.md) - Tracked environment file leakage
|
|
83
|
+
- [TG-DB-002](./TG-DB-002-privileged-database-credential.md) - Privileged database credentials in browser code
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# TG-SEC-002: Secrets in Public Environment Variables
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
Critical
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Frontend frameworks exposing build-time env vars to browser bundles
|
|
8
|
+
- Vite (`VITE_*`), Next.js (`NEXT_PUBLIC_*`), CRA (`REACT_APP_*`)
|
|
9
|
+
- Client-rendered pages, static exports, and edge-delivered frontend assets
|
|
10
|
+
- Monorepos where frontend apps consume shared environment files
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Public-prefixed environment variables are intentionally embedded into shipped JavaScript and are readable by any user.
|
|
14
|
+
Placing API secrets, private signing keys, or privileged service credentials in these variables effectively publishes them.
|
|
15
|
+
Exposure allows unauthorized API usage, quota theft, account compromise, and backend pivoting.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Secret-like values assigned to `VITE_*`, `NEXT_PUBLIC_*`, or `REACT_APP_*`
|
|
19
|
+
- Names suggesting private intent despite public prefix:
|
|
20
|
+
- `VITE_JWT_SECRET`
|
|
21
|
+
- `NEXT_PUBLIC_DB_PASSWORD`
|
|
22
|
+
- `REACT_APP_SERVICE_ROLE_KEY`
|
|
23
|
+
- Long tokens, private keys, and credential URLs in frontend env config
|
|
24
|
+
- Client code directly reading sensitive public variables for auth or data access
|
|
25
|
+
- Build scripts promoting server-only variables into public namespaces
|
|
26
|
+
|
|
27
|
+
## Unsafe Example
|
|
28
|
+
```env
|
|
29
|
+
# .env.production
|
|
30
|
+
NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_51N9x...
|
|
31
|
+
VITE_DB_URL=postgres://admin:supersecret@db.prod:5432/core
|
|
32
|
+
REACT_APP_JWT_SIGNING_KEY=prod_signing_key_q2f8j1
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// src/lib/payments.ts
|
|
37
|
+
export const stripeSecret = process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY!;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Safe Example
|
|
41
|
+
```env
|
|
42
|
+
# .env.production
|
|
43
|
+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_51N9x...
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// src/lib/payments.ts
|
|
48
|
+
export async function createCheckoutSession(cartId: string) {
|
|
49
|
+
const res = await fetch("/api/checkout/session", {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "content-type": "application/json" },
|
|
52
|
+
body: JSON.stringify({ cartId }),
|
|
53
|
+
});
|
|
54
|
+
return res.json();
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Remediation (numbered)
|
|
59
|
+
1. Remove secrets from every `VITE_*`, `NEXT_PUBLIC_*`, and `REACT_APP_*` variable.
|
|
60
|
+
2. Move sensitive values to server-only environment variables without public prefixes.
|
|
61
|
+
3. Route privileged operations through backend APIs with access control.
|
|
62
|
+
4. Rotate all credentials that were exposed in public frontend environments.
|
|
63
|
+
5. Rebuild and redeploy frontend assets after variable cleanup.
|
|
64
|
+
6. Add CI policy checks blocking secret-like values in public env namespaces.
|
|
65
|
+
7. Update team docs to separate publishable keys from secret keys explicitly.
|
|
66
|
+
|
|
67
|
+
## Verification
|
|
68
|
+
- Inspect built bundles to ensure no secret values are embedded.
|
|
69
|
+
- Validate frontend only references publishable or non-sensitive config.
|
|
70
|
+
- Confirm backend endpoints own all privileged API calls.
|
|
71
|
+
- Check environment templates for corrected naming and scope boundaries.
|
|
72
|
+
- Ensure old exposed keys fail when tested after rotation.
|
|
73
|
+
|
|
74
|
+
## False Positives and Exceptions
|
|
75
|
+
- Publishable keys (for example, Stripe publishable key) are acceptable by design.
|
|
76
|
+
- Public feature flags and app metadata can safely use public prefixes.
|
|
77
|
+
- A value that looks random is not always secret; validate provider classification.
|
|
78
|
+
- Exceptions require documented approval and periodic re-review.
|
|
79
|
+
|
|
80
|
+
## Related Rules
|
|
81
|
+
- [TG-SEC-001](./TG-SEC-001-hardcoded-secrets.md) - Hardcoded credential literals in source code
|
|
82
|
+
- [TG-DB-002](./TG-DB-002-privileged-database-credential.md) - Privileged DB credentials exposed in browser code
|
|
83
|
+
- [TG-DB-003](./TG-DB-003-frontend-admin-sdk.md) - Frontend use of admin/server-only SDKs
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# TG-SEC-003: Tracked Environment File
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Git repositories containing `.env`, `.env.local`, `.env.production`, or similar files
|
|
8
|
+
- Application backends, frontend builds, deployment scripts, and tooling
|
|
9
|
+
- Monorepos with per-package environment files
|
|
10
|
+
- Any tracked path where secrets can be stored in plain text
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Environment files are commonly used to store credentials, tokens, and connection strings.
|
|
14
|
+
When tracked by git, these values propagate to every clone, fork, mirror, and CI artifact.
|
|
15
|
+
Even if a file is later deleted, prior commits may retain sensitive data unless history is remediated.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- `.env*` files present in tracked source control history or current index
|
|
19
|
+
- Environment files committed outside approved template patterns
|
|
20
|
+
- Presence of sensitive key names in tracked env files:
|
|
21
|
+
- `*_SECRET`, `*_TOKEN`, `*_PASSWORD`, `DATABASE_URL`, `SERVICE_ROLE_KEY`
|
|
22
|
+
- Mismatch between `.gitignore` policy and tracked env artifacts
|
|
23
|
+
- Commits that introduce plaintext operational credentials
|
|
24
|
+
|
|
25
|
+
## Unsafe Example
|
|
26
|
+
```bash
|
|
27
|
+
# git status --short
|
|
28
|
+
A .env
|
|
29
|
+
M src/config.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```env
|
|
33
|
+
# .env
|
|
34
|
+
DATABASE_URL=postgres://report_user:R3portProdPass@db:5432/reports
|
|
35
|
+
JWT_SECRET=invoice_signing_secret_2026
|
|
36
|
+
REDIS_PASSWORD=cache_password_11
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```gitignore
|
|
41
|
+
# .gitignore
|
|
42
|
+
.env
|
|
43
|
+
.env.*
|
|
44
|
+
!.env.example
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```env
|
|
48
|
+
# .env.example
|
|
49
|
+
DATABASE_URL=
|
|
50
|
+
JWT_SECRET=
|
|
51
|
+
REDIS_PASSWORD=
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Remediation (numbered)
|
|
55
|
+
1. Remove tracked `.env*` files from git index while preserving local copies.
|
|
56
|
+
2. Add strict ignore rules for environment files in repository root and subprojects.
|
|
57
|
+
3. Replace committed env files with sanitized `.env.example` templates.
|
|
58
|
+
4. Rotate all credentials that existed in tracked environment files.
|
|
59
|
+
5. Audit commit history to determine exposure scope and retention obligations.
|
|
60
|
+
6. If required, perform approved history rewrite and coordinate downstream cleanup.
|
|
61
|
+
7. Enforce pre-commit and CI checks that block tracked secret-bearing env files.
|
|
62
|
+
|
|
63
|
+
## Verification
|
|
64
|
+
- Run git status and confirm `.env*` files are untracked (except approved templates).
|
|
65
|
+
- Check `.gitignore` patterns include root and nested environment file variants.
|
|
66
|
+
- Validate deployed systems use secure environment injection, not committed files.
|
|
67
|
+
- Confirm rotated values are active and old credentials are invalid.
|
|
68
|
+
- Review pull requests for accidental reintroduction of tracked env files.
|
|
69
|
+
|
|
70
|
+
## False Positives and Exceptions
|
|
71
|
+
- `.env.example` and `.env.template` are acceptable if they contain no real secrets.
|
|
72
|
+
- Test fixtures may include fake credentials only when clearly non-operational.
|
|
73
|
+
- Some repos intentionally track non-sensitive env files; exceptions need approval.
|
|
74
|
+
- Emergency temporary commits are still violations unless formally exempted.
|
|
75
|
+
|
|
76
|
+
## Related Rules
|
|
77
|
+
- [TG-SEC-001](./TG-SEC-001-hardcoded-secrets.md) - Hardcoded secrets in source files
|
|
78
|
+
- [TG-SEC-002](./TG-SEC-002-public-environment-secrets.md) - Secrets exposed through public env prefixes
|
|
79
|
+
- [TG-SEC-004](./TG-SEC-004-sensitive-logging.md) - Runtime leakage through sensitive logging
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# TG-SEC-004: Sensitive Information in Logs
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
Medium
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Application logs in backend services, workers, and serverless functions
|
|
8
|
+
- Client-side error logging and telemetry pipelines
|
|
9
|
+
- Authentication middleware and API gateway handlers
|
|
10
|
+
- Structured logs, plaintext logs, and third-party observability sinks
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Logs are broadly distributed across systems, retained for long periods, and frequently accessible to many operators.
|
|
14
|
+
If passwords, tokens, cookies, or authorization headers are logged, sensitive data can be replayed or abused.
|
|
15
|
+
Log leakage often bypasses normal secret handling controls because it happens after request processing.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Direct logging of request bodies containing credentials
|
|
19
|
+
- Logging of headers without redaction, especially `Authorization` and `Cookie`
|
|
20
|
+
- Serialization of auth/session objects that include tokens
|
|
21
|
+
- Error logs that concatenate secret values into exception messages
|
|
22
|
+
- Debug statements printing plaintext passwords, OTP codes, or API keys
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```ts
|
|
26
|
+
// src/middleware/login.ts
|
|
27
|
+
export async function loginHandler(req, res) {
|
|
28
|
+
console.info("Login payload", req.body);
|
|
29
|
+
console.info("Auth header", req.headers.authorization);
|
|
30
|
+
|
|
31
|
+
const token = await issueToken(req.body.email);
|
|
32
|
+
console.debug(`issued token=${token}`);
|
|
33
|
+
return res.json({ ok: true });
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Safe Example
|
|
38
|
+
```ts
|
|
39
|
+
// src/middleware/login.ts
|
|
40
|
+
function redactAuthHeader(value?: string) {
|
|
41
|
+
if (!value) return "missing";
|
|
42
|
+
return value.startsWith("Bearer ") ? "Bearer [REDACTED]" : "[REDACTED]";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function loginHandler(req, res) {
|
|
46
|
+
console.info("Login attempt", {
|
|
47
|
+
emailDomain: req.body.email?.split("@")[1] ?? "unknown",
|
|
48
|
+
hasPassword: Boolean(req.body.password),
|
|
49
|
+
auth: redactAuthHeader(req.headers.authorization),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const token = await issueToken(req.body.email);
|
|
53
|
+
console.debug("Issued session token", { token: "[REDACTED]" });
|
|
54
|
+
return res.json({ ok: true });
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Remediation (numbered)
|
|
59
|
+
1. Remove direct logging of request bodies and sensitive headers.
|
|
60
|
+
2. Implement centralized redaction for known secret fields and header keys.
|
|
61
|
+
3. Log metadata and security-relevant context without raw secret values.
|
|
62
|
+
4. Update logging wrappers to block unsafe keys by default.
|
|
63
|
+
5. Rotate credentials if logs already captured valid sensitive data.
|
|
64
|
+
6. Restrict log access and retention for security-sensitive services.
|
|
65
|
+
7. Add automated tests to assert redaction behavior in logging utilities.
|
|
66
|
+
|
|
67
|
+
## Verification
|
|
68
|
+
- Search logging calls for `password`, `token`, `authorization`, and `cookie` fields.
|
|
69
|
+
- Generate representative requests and inspect emitted logs for redaction.
|
|
70
|
+
- Confirm tracing/telemetry exporters do not reintroduce sensitive attributes.
|
|
71
|
+
- Validate historical logs for recent exposure and incident follow-up needs.
|
|
72
|
+
- Ensure secure logging guidance is included in service development standards.
|
|
73
|
+
|
|
74
|
+
## False Positives and Exceptions
|
|
75
|
+
- Logging token hashes or irreversible fingerprints may be acceptable for correlation.
|
|
76
|
+
- Masked values can still trigger detections; confirm full redaction depth.
|
|
77
|
+
- Security incident forensics may require temporary enhanced logs under strict controls.
|
|
78
|
+
- Exceptions must include expiration, owner, and explicit approval.
|
|
79
|
+
|
|
80
|
+
## Related Rules
|
|
81
|
+
- [TG-SEC-001](./TG-SEC-001-hardcoded-secrets.md) - Source-level hardcoded secret exposure
|
|
82
|
+
- [TG-SEC-003](./TG-SEC-003-tracked-env-file.md) - Secret leakage through tracked env files
|
|
83
|
+
- [TG-DB-002](./TG-DB-002-privileged-database-credential.md) - Privileged credentials exposed to clients
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# TG-AUTH-001: Weak Password Storage
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
Critical
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- User registration and login systems
|
|
8
|
+
- Password reset and credential update flows
|
|
9
|
+
- Legacy account import/migration jobs
|
|
10
|
+
- Identity providers that store local credentials
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Weak password storage enables catastrophic compromise when databases leak through attacks, backups, logs, or insider misuse.
|
|
14
|
+
Plaintext, reversible encryption, or fast unsalted hashes let attackers recover passwords quickly and reuse them across services.
|
|
15
|
+
Secure, adaptive hashing with per-password salt and optional pepper drastically reduces offline cracking feasibility.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Passwords stored as plaintext or encoded forms such as Base64.
|
|
19
|
+
- Use of outdated fast hashes (`MD5`, `SHA1`, bare `SHA256`) for password storage.
|
|
20
|
+
- Same hash value for identical passwords due to missing random salt.
|
|
21
|
+
- Manual cryptography routines instead of vetted password hashing libraries.
|
|
22
|
+
- Logging of raw passwords or hash inputs during authentication workflows.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
import crypto from "crypto";
|
|
27
|
+
|
|
28
|
+
app.post("/api/register", async (req, res) => {
|
|
29
|
+
const email = req.body.email;
|
|
30
|
+
const password = req.body.password;
|
|
31
|
+
|
|
32
|
+
// Fast hash with no salt and no work factor
|
|
33
|
+
const passwordHash = crypto.createHash("sha256").update(password).digest("hex");
|
|
34
|
+
|
|
35
|
+
await db.user.create({
|
|
36
|
+
data: { email, password_hash: passwordHash }
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
res.json({ ok: true });
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Safe Example
|
|
44
|
+
```js
|
|
45
|
+
import argon2 from "argon2";
|
|
46
|
+
|
|
47
|
+
app.post("/api/register", async (req, res) => {
|
|
48
|
+
const email = String(req.body.email || "");
|
|
49
|
+
const password = String(req.body.password || "");
|
|
50
|
+
|
|
51
|
+
if (password.length < 12) {
|
|
52
|
+
return res.status(400).json({ ok: false, error: "Password too short" });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const hash = await argon2.hash(password, {
|
|
56
|
+
type: argon2.argon2id,
|
|
57
|
+
memoryCost: 19456,
|
|
58
|
+
timeCost: 2,
|
|
59
|
+
parallelism: 1
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await db.user.create({
|
|
63
|
+
data: { email, password_hash: hash }
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
res.json({ ok: true });
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
app.post("/api/login", async (req, res) => {
|
|
70
|
+
const user = await db.user.findUnique({ where: { email: req.body.email } });
|
|
71
|
+
if (!user) return res.status(401).json({ ok: false });
|
|
72
|
+
|
|
73
|
+
const valid = await argon2.verify(user.password_hash, String(req.body.password || ""));
|
|
74
|
+
if (!valid) return res.status(401).json({ ok: false });
|
|
75
|
+
|
|
76
|
+
res.json({ ok: true });
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Remediation
|
|
81
|
+
1. Replace insecure password storage with Argon2id, bcrypt, or scrypt using recommended cost factors.
|
|
82
|
+
2. Ensure each password hash includes a unique random salt (handled by modern libraries).
|
|
83
|
+
3. Add optional application-level pepper stored in a secret manager, not in the database.
|
|
84
|
+
4. Remove password values from logs, traces, analytics events, and error telemetry.
|
|
85
|
+
5. Migrate existing hashes using rehash-on-login or controlled reset campaigns.
|
|
86
|
+
6. Periodically tune work factors based on current hardware and latency targets.
|
|
87
|
+
|
|
88
|
+
## Verification
|
|
89
|
+
- Inspect stored credential records and confirm they use adaptive hash formats.
|
|
90
|
+
- Verify identical passwords across test accounts produce different hash outputs.
|
|
91
|
+
- Benchmark login flow to ensure configured cost factors are actually applied.
|
|
92
|
+
- Attempt cracking tests on sample exported hashes to validate resistance assumptions.
|
|
93
|
+
- Review codebase for direct use of fast hash APIs in authentication modules.
|
|
94
|
+
|
|
95
|
+
## False Positives and Exceptions
|
|
96
|
+
- One-way hashes for non-password tokens may look similar but are separate controls.
|
|
97
|
+
- Temporary test fixtures can include static hashes only if isolated from production data paths.
|
|
98
|
+
- External identity providers reduce local password handling scope but do not exempt backup credential paths.
|
|
99
|
+
|
|
100
|
+
## Related Rules
|
|
101
|
+
- [TG-AUTH-005](./TG-AUTH-005-unsafe-password-reset.md)
|
|
102
|
+
- [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
|
|
103
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# TG-AUTH-002: Client-Only Authorization
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Single-page applications with protected routes
|
|
8
|
+
- Mobile apps that hide privileged UI actions
|
|
9
|
+
- APIs serving both user and admin clients
|
|
10
|
+
- Feature-flagged operations with role constraints
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Authorization enforced only in frontend code is not security control, because attackers can bypass the UI and call backend APIs directly.
|
|
14
|
+
If server endpoints trust client-supplied role flags or hidden form fields, privilege escalation becomes trivial.
|
|
15
|
+
Robust authorization must be verified on every sensitive backend action regardless of UI behavior.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Admin checks present in frontend components but absent in backend handlers.
|
|
19
|
+
- API routes that trust `role`, `isAdmin`, or similar flags from request body/query.
|
|
20
|
+
- Hidden buttons/menus used as the only barrier to privileged operations.
|
|
21
|
+
- Use of local storage role values for security decisions.
|
|
22
|
+
- Missing middleware or policy checks around destructive and high-impact endpoints.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
// Frontend blocks non-admin users from seeing delete button
|
|
27
|
+
if (currentUser.role === "admin") {
|
|
28
|
+
showDeleteUserButton();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Backend route does not verify authenticated role
|
|
32
|
+
app.post("/api/admin/delete-user", async (req, res) => {
|
|
33
|
+
const targetUserId = req.body.userId;
|
|
34
|
+
await db.user.delete({ where: { id: targetUserId } });
|
|
35
|
+
res.json({ ok: true });
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```js
|
|
41
|
+
function requireRole(...allowedRoles) {
|
|
42
|
+
return (req, res, next) => {
|
|
43
|
+
const role = req.auth?.role;
|
|
44
|
+
if (!allowedRoles.includes(role)) {
|
|
45
|
+
return res.status(403).json({ ok: false, error: "Forbidden" });
|
|
46
|
+
}
|
|
47
|
+
next();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
app.post("/api/admin/delete-user", requireAuth, requireRole("admin"), async (req, res) => {
|
|
52
|
+
const targetUserId = String(req.body.userId || "");
|
|
53
|
+
if (!/^[a-f0-9-]{36}$/.test(targetUserId)) {
|
|
54
|
+
return res.status(400).json({ ok: false, error: "Invalid user id" });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await db.user.delete({ where: { id: targetUserId } });
|
|
58
|
+
res.json({ ok: true });
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Remediation
|
|
63
|
+
1. Enforce authorization checks on the server for every protected action and resource.
|
|
64
|
+
2. Derive roles/permissions from authenticated server-side identity, not request payload flags.
|
|
65
|
+
3. Implement centralized policy middleware to reduce inconsistent endpoint protection.
|
|
66
|
+
4. Keep frontend role checks for UX only, never as the sole security mechanism.
|
|
67
|
+
5. Add audit logging for privileged operations including actor, target, and outcome.
|
|
68
|
+
6. Write regression tests that call endpoints directly without using the UI.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
- Call privileged endpoints with a non-admin token and verify consistent `403` responses.
|
|
72
|
+
- Remove/hide frontend restrictions in browser devtools and confirm backend still blocks access.
|
|
73
|
+
- Attempt sending forged `isAdmin: true` fields and verify they are ignored.
|
|
74
|
+
- Inspect route registrations to ensure protected middleware is applied universally.
|
|
75
|
+
- Review audit logs for denied authorization attempts.
|
|
76
|
+
|
|
77
|
+
## False Positives and Exceptions
|
|
78
|
+
- Public metadata endpoints may intentionally skip authorization if they contain no sensitive operations or data.
|
|
79
|
+
- Early prototypes often rely on frontend checks; production deployment must not.
|
|
80
|
+
- Internal admin APIs still require authorization controls unless isolated by strong network identity boundaries.
|
|
81
|
+
|
|
82
|
+
## Related Rules
|
|
83
|
+
- [TG-AUTH-003](./TG-AUTH-003-missing-object-authorization.md)
|
|
84
|
+
- [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
|
|
85
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# TG-AUTH-003: Missing Object-Level Authorization (IDOR)
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- APIs that fetch or modify records by ID
|
|
8
|
+
- File and document retrieval endpoints
|
|
9
|
+
- Multi-tenant systems with organization-scoped data
|
|
10
|
+
- Billing, messaging, and profile management resources
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
IDOR occurs when applications expose object identifiers but fail to verify that the requester is allowed to access that specific object.
|
|
14
|
+
Attackers can enumerate or guess IDs to read, modify, or delete other users' resources without needing elevated roles.
|
|
15
|
+
This creates severe confidentiality and integrity breaches, especially in multi-tenant products.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Endpoints reading `:id` or query IDs without ownership or tenant checks.
|
|
19
|
+
- `findUnique`/`getById` calls that do not include current user or tenant constraints.
|
|
20
|
+
- Access to files/records based solely on untrusted identifier parameters.
|
|
21
|
+
- Sequential numeric IDs exposed in URLs with missing authorization guards.
|
|
22
|
+
- Update/delete operations that authenticate user identity but skip object-level policy.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
app.get("/api/invoices/:invoiceId", requireAuth, async (req, res) => {
|
|
27
|
+
const invoiceId = req.params.invoiceId;
|
|
28
|
+
|
|
29
|
+
// Authenticated, but no check that invoice belongs to this user/tenant
|
|
30
|
+
const invoice = await db.invoice.findUnique({
|
|
31
|
+
where: { id: invoiceId }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!invoice) return res.status(404).json({ ok: false });
|
|
35
|
+
res.json({ ok: true, invoice });
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```js
|
|
41
|
+
app.get("/api/invoices/:invoiceId", requireAuth, async (req, res) => {
|
|
42
|
+
const invoiceId = String(req.params.invoiceId || "");
|
|
43
|
+
const userId = req.auth.userId;
|
|
44
|
+
const tenantId = req.auth.tenantId;
|
|
45
|
+
|
|
46
|
+
const invoice = await db.invoice.findFirst({
|
|
47
|
+
where: {
|
|
48
|
+
id: invoiceId,
|
|
49
|
+
tenant_id: tenantId,
|
|
50
|
+
customer_user_id: userId
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!invoice) {
|
|
55
|
+
return res.status(404).json({ ok: false, error: "Not found" });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
res.json({ ok: true, invoice });
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Remediation
|
|
63
|
+
1. Apply object-level authorization checks on every read, update, and delete path.
|
|
64
|
+
2. Scope data queries by authenticated user, tenant, account, or policy context.
|
|
65
|
+
3. Centralize authorization policies so object checks are consistent across endpoints.
|
|
66
|
+
4. Avoid exposing predictable identifiers when not required; consider opaque IDs.
|
|
67
|
+
5. Log access denials and anomalous ID probing attempts for detection.
|
|
68
|
+
6. Add tests that attempt cross-user and cross-tenant access with valid credentials.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
- Authenticate as User A and request User B resources by changing IDs.
|
|
72
|
+
- Confirm unauthorized object access returns `404` or `403` consistently without data leakage.
|
|
73
|
+
- Test update and delete endpoints, not only read endpoints.
|
|
74
|
+
- Validate background jobs and export endpoints enforce tenant/object constraints too.
|
|
75
|
+
- Inspect ORM/database queries for required ownership predicates.
|
|
76
|
+
|
|
77
|
+
## False Positives and Exceptions
|
|
78
|
+
- Public resources intentionally shared across tenants should be explicitly labeled and policy-reviewed.
|
|
79
|
+
- Some administrative roles can access cross-tenant objects, but this must be explicit and auditable.
|
|
80
|
+
- Random UUID usage alone does not remove need for object authorization.
|
|
81
|
+
|
|
82
|
+
## Related Rules
|
|
83
|
+
- [TG-AUTH-002](./TG-AUTH-002-client-only-authorization.md)
|
|
84
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
85
|
+
- [TG-INPUT-002](./TG-INPUT-002-raw-sql-concatenation.md)
|