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,321 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
TorusGuard AI IDE Rules Auto-Sync Engine (v1.2.0)
|
|
4
|
+
Compiles project security memory, golden fix recipes, and active guardrails
|
|
5
|
+
into prompt-optimized rule files for Cursor, Claude Code, Antigravity, and Windsurf.
|
|
6
|
+
Non-destructive: preserves existing user rules via demarcated comment fences.
|
|
7
|
+
Zero external dependencies (Python 3.10+ stdlib).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
import argparse
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
# Windows console UTF-8 support
|
|
18
|
+
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
19
|
+
try:
|
|
20
|
+
getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
|
|
21
|
+
except (AttributeError, OSError):
|
|
22
|
+
pass
|
|
23
|
+
if sys.stderr and hasattr(sys.stderr, "reconfigure"):
|
|
24
|
+
try:
|
|
25
|
+
getattr(sys.stderr, "reconfigure")(encoding="utf-8", errors="replace")
|
|
26
|
+
except (AttributeError, OSError):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
START_MARKER = "<!-- TORUSGUARD-SECURITY-GUARDRAILS:START -->"
|
|
30
|
+
END_MARKER = "<!-- TORUSGUARD-SECURITY-GUARDRAILS:END -->"
|
|
31
|
+
MAX_PROMPT_TOKENS = 400
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def find_project_root(start_dir: str | Path | None = None) -> Path:
|
|
35
|
+
"""Detect project root directory."""
|
|
36
|
+
current = Path(start_dir or Path.cwd()).resolve()
|
|
37
|
+
markers = [".git", "package.json", "pyproject.toml", ".torusguard"]
|
|
38
|
+
for m in markers:
|
|
39
|
+
if (current / m).exists():
|
|
40
|
+
return current
|
|
41
|
+
for parent in current.parents:
|
|
42
|
+
for m in markers:
|
|
43
|
+
if (parent / m).exists():
|
|
44
|
+
return parent
|
|
45
|
+
return current
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def load_security_context(root_dir: Path) -> dict[str, Any]:
|
|
49
|
+
"""Load security profile and patterns from memory subsystem."""
|
|
50
|
+
tg_dir = root_dir / ".torusguard"
|
|
51
|
+
memory_dir = tg_dir / "memory"
|
|
52
|
+
|
|
53
|
+
context_file = memory_dir / "context.json"
|
|
54
|
+
patterns_file = memory_dir / "patterns.json"
|
|
55
|
+
profile_file = memory_dir / "profile.json"
|
|
56
|
+
|
|
57
|
+
context_data: dict[str, Any] = {}
|
|
58
|
+
patterns: list[dict[str, Any]] = []
|
|
59
|
+
profile: dict[str, Any] = {}
|
|
60
|
+
|
|
61
|
+
if context_file.exists():
|
|
62
|
+
try:
|
|
63
|
+
context_data = json.loads(context_file.read_text(encoding="utf-8"))
|
|
64
|
+
except (json.JSONDecodeError, OSError):
|
|
65
|
+
context_data = {}
|
|
66
|
+
|
|
67
|
+
if patterns_file.exists():
|
|
68
|
+
try:
|
|
69
|
+
patterns = json.loads(patterns_file.read_text(encoding="utf-8"))
|
|
70
|
+
except (json.JSONDecodeError, OSError):
|
|
71
|
+
patterns = []
|
|
72
|
+
|
|
73
|
+
if profile_file.exists():
|
|
74
|
+
try:
|
|
75
|
+
profile = json.loads(profile_file.read_text(encoding="utf-8"))
|
|
76
|
+
except (json.JSONDecodeError, OSError):
|
|
77
|
+
profile = {}
|
|
78
|
+
|
|
79
|
+
cfg_file = tg_dir / "config" / "torusguard.json"
|
|
80
|
+
if cfg_file.exists():
|
|
81
|
+
try:
|
|
82
|
+
cfg = json.loads(cfg_file.read_text(encoding="utf-8"))
|
|
83
|
+
det = cfg.get("detected_stack", {})
|
|
84
|
+
if not profile.get("stack"):
|
|
85
|
+
lang = det.get("language")
|
|
86
|
+
fw = det.get("framework")
|
|
87
|
+
if lang and lang != "Unknown":
|
|
88
|
+
stk = [lang]
|
|
89
|
+
if fw and fw != "None":
|
|
90
|
+
stk.append(fw)
|
|
91
|
+
profile["stack"] = stk
|
|
92
|
+
except (json.JSONDecodeError, OSError):
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
# Dynamic fallback to stack_detect if stack is still unknown
|
|
96
|
+
if not profile.get("stack"):
|
|
97
|
+
try:
|
|
98
|
+
import stack_detect # type: ignore
|
|
99
|
+
det_stk = stack_detect.detect_stack(root_dir)
|
|
100
|
+
lang = det_stk.get("language")
|
|
101
|
+
fw = det_stk.get("framework")
|
|
102
|
+
if lang and lang != "Unknown":
|
|
103
|
+
stk = [lang]
|
|
104
|
+
if fw and fw != "None":
|
|
105
|
+
stk.append(fw)
|
|
106
|
+
profile["stack"] = stk
|
|
107
|
+
except Exception:
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
"context": context_data,
|
|
112
|
+
"patterns": patterns,
|
|
113
|
+
"profile": profile
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def format_dense_security_rules(sec_data: dict[str, Any]) -> str:
|
|
118
|
+
"""
|
|
119
|
+
Format active security memory into a dense, token-budgeted markdown block (<=400 tokens),
|
|
120
|
+
dynamically tailored to the detected language and framework family.
|
|
121
|
+
"""
|
|
122
|
+
patterns = sec_data.get("patterns", [])
|
|
123
|
+
profile = sec_data.get("profile", {})
|
|
124
|
+
stack = profile.get("stack", [])
|
|
125
|
+
|
|
126
|
+
golden_recipes: list[dict[str, Any]] = []
|
|
127
|
+
regressions: list[dict[str, Any]] = []
|
|
128
|
+
common_vulns: list[dict[str, Any]] = []
|
|
129
|
+
|
|
130
|
+
for p in patterns:
|
|
131
|
+
ptype = p.get("pattern_type")
|
|
132
|
+
if ptype == "golden_fix_recipe":
|
|
133
|
+
golden_recipes.append(p)
|
|
134
|
+
elif ptype == "regression_watch":
|
|
135
|
+
regressions.append(p)
|
|
136
|
+
elif ptype in ("common_vulnerability", "recurring_fix"):
|
|
137
|
+
common_vulns.append(p)
|
|
138
|
+
|
|
139
|
+
lines: list[str] = [
|
|
140
|
+
START_MARKER,
|
|
141
|
+
"## 🛡️ TorusGuard Active Project Security Invariants",
|
|
142
|
+
"> Auto-synced from `.torusguard/memory/`. Adhere to these guardrails in all generated code.",
|
|
143
|
+
""
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
if stack:
|
|
147
|
+
lines.append(f"**Detected Stack:** {', '.join(stack)}")
|
|
148
|
+
lines.append("")
|
|
149
|
+
|
|
150
|
+
# Core Behavioral Invariants (Stack-Adaptive & Token-Optimized)
|
|
151
|
+
stack_lower = " ".join(stack).lower()
|
|
152
|
+
sql_guards = []
|
|
153
|
+
bypass_guards = []
|
|
154
|
+
|
|
155
|
+
if "go" in stack_lower:
|
|
156
|
+
sql_guards.append("`db.Query(..., args)` / GORM")
|
|
157
|
+
bypass_guards.append("`InsecureSkipVerify: true`")
|
|
158
|
+
if "rust" in stack_lower:
|
|
159
|
+
sql_guards.append("`sqlx::query!` / Diesel")
|
|
160
|
+
bypass_guards.append("`unsafe { ... }`")
|
|
161
|
+
if "java" in stack_lower or "kotlin" in stack_lower:
|
|
162
|
+
sql_guards.append("JPA / PreparedStatement")
|
|
163
|
+
bypass_guards.append("`csrf().disable()`")
|
|
164
|
+
if "c#" in stack_lower or "dotnet" in stack_lower:
|
|
165
|
+
sql_guards.append("EF Core LINQ / `FromSqlInterpolated`")
|
|
166
|
+
bypass_guards.append("`[AllowAnonymous]`")
|
|
167
|
+
if "php" in stack_lower:
|
|
168
|
+
sql_guards.append("PDO prepared statements / Eloquent")
|
|
169
|
+
bypass_guards.append("`CURLOPT_SSL_VERIFYPEER => false`")
|
|
170
|
+
if "typescript" in stack_lower or "javascript" in stack_lower or "next" in stack_lower or "express" in stack_lower:
|
|
171
|
+
sql_guards.append("Prisma / Drizzle binders")
|
|
172
|
+
bypass_guards.append("`rejectUnauthorized: false`")
|
|
173
|
+
|
|
174
|
+
if not sql_guards:
|
|
175
|
+
sql_rule = "1. **Zero Raw SQL / String Formats:** Always use parameterized queries (e.g. `%s`, `?`, or ORM bound params)."
|
|
176
|
+
else:
|
|
177
|
+
sql_rule = f"1. **Zero Raw SQL:** Always use parameterized queries ({' / '.join(sql_guards[:2])})."
|
|
178
|
+
|
|
179
|
+
if not bypass_guards:
|
|
180
|
+
bypass_rule = "4. **No Security Bypasses:** Never insert `# nosec`, `verify=False`, `@csrf_exempt`, or `bypass_auth=True`."
|
|
181
|
+
else:
|
|
182
|
+
bypass_rule = f"4. **No Security Bypasses:** Never insert `# nosec`, `verify=False`, or {', '.join(bypass_guards[:2])}."
|
|
183
|
+
|
|
184
|
+
lines.extend([
|
|
185
|
+
"### Universal Guardrails",
|
|
186
|
+
sql_rule,
|
|
187
|
+
"2. **Tenant Isolation:** Enforce tenant/owner filtering on every database lookup (never query without `tenant_id` or owner scope).",
|
|
188
|
+
"3. **Ponytail Bound Rule:** Remediation patches must be minimal (<= 35 additions, <= 25 deletions).",
|
|
189
|
+
bypass_rule,
|
|
190
|
+
""
|
|
191
|
+
])
|
|
192
|
+
|
|
193
|
+
# Golden Fix Recipes (Top 2 to preserve tokens)
|
|
194
|
+
if golden_recipes:
|
|
195
|
+
lines.append("### Verified Golden Fix Patterns")
|
|
196
|
+
for rec in golden_recipes[:2]:
|
|
197
|
+
rule = rec.get("rule_id", "TG-SEC")
|
|
198
|
+
desc = rec.get("description", "Verified AST fix")
|
|
199
|
+
r_data = rec.get("recipe_data", {})
|
|
200
|
+
before = r_data.get("before_snippet", "")
|
|
201
|
+
after = r_data.get("after_snippet", "")
|
|
202
|
+
lines.append(f"- **{rule}** ({desc}):")
|
|
203
|
+
if before and after:
|
|
204
|
+
lines.append(f" - ❌ Avoid: `{before[:70]}`")
|
|
205
|
+
lines.append(f" - ✅ Prefer: `{after[:70]}`")
|
|
206
|
+
lines.append("")
|
|
207
|
+
|
|
208
|
+
# High-Risk Regression Watches
|
|
209
|
+
if regressions:
|
|
210
|
+
lines.append("### Active Regression Watches (Do Not Re-Introduce)")
|
|
211
|
+
for reg in regressions[:3]:
|
|
212
|
+
rule = reg.get("rule_id", "TG-REG")
|
|
213
|
+
files = ", ".join(reg.get("affected_files", [])[:2]) or "tracked files"
|
|
214
|
+
lines.append(f"- **{rule}**: Recurrence risk in `{files}`.")
|
|
215
|
+
lines.append("")
|
|
216
|
+
|
|
217
|
+
lines.append(END_MARKER)
|
|
218
|
+
return "\n".join(lines)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def inject_rules_into_file(file_path: Path, rules_block: str) -> bool:
|
|
222
|
+
"""
|
|
223
|
+
Non-destructively inject or replace the TorusGuard block in a target rules file.
|
|
224
|
+
Creates parent directories if necessary.
|
|
225
|
+
"""
|
|
226
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
227
|
+
existing_content = ""
|
|
228
|
+
|
|
229
|
+
if file_path.exists():
|
|
230
|
+
try:
|
|
231
|
+
existing_content = file_path.read_text(encoding="utf-8")
|
|
232
|
+
except OSError:
|
|
233
|
+
existing_content = ""
|
|
234
|
+
|
|
235
|
+
pattern = re.compile(
|
|
236
|
+
rf"{re.escape(START_MARKER)}.*?{re.escape(END_MARKER)}",
|
|
237
|
+
re.DOTALL
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
if pattern.search(existing_content):
|
|
241
|
+
updated_content = pattern.sub(rules_block, existing_content)
|
|
242
|
+
else:
|
|
243
|
+
if existing_content.strip():
|
|
244
|
+
updated_content = existing_content.rstrip() + "\n\n" + rules_block + "\n"
|
|
245
|
+
else:
|
|
246
|
+
updated_content = rules_block + "\n"
|
|
247
|
+
|
|
248
|
+
try:
|
|
249
|
+
file_path.write_text(updated_content, encoding="utf-8")
|
|
250
|
+
return True
|
|
251
|
+
except OSError as err:
|
|
252
|
+
print(f"Error writing rules to {file_path}: {err}", file=sys.stderr)
|
|
253
|
+
return False
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def sync_rules(
|
|
257
|
+
target_format: str = "all",
|
|
258
|
+
root_dir: str | Path | None = None
|
|
259
|
+
) -> dict[str, Any]:
|
|
260
|
+
"""
|
|
261
|
+
Synchronize project security invariants into target IDE rules files.
|
|
262
|
+
Supported targets: 'cursor', 'claude', 'agent', 'windsurf', 'all'.
|
|
263
|
+
"""
|
|
264
|
+
root = Path(root_dir or find_project_root()).resolve()
|
|
265
|
+
sec_data = load_security_context(root)
|
|
266
|
+
rules_block = format_dense_security_rules(sec_data)
|
|
267
|
+
|
|
268
|
+
target_files: dict[str, Path] = {
|
|
269
|
+
"cursor": root / ".cursorrules",
|
|
270
|
+
"claude": root / "CLAUDE.md",
|
|
271
|
+
"agent": root / ".agent" / "rules" / "torusguard.md",
|
|
272
|
+
"windsurf": root / ".windsurfrules"
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
synced_targets: list[str] = []
|
|
276
|
+
formats_to_sync = list(target_files.keys()) if target_format == "all" else [target_format]
|
|
277
|
+
|
|
278
|
+
for fmt in formats_to_sync:
|
|
279
|
+
if fmt in target_files:
|
|
280
|
+
target_path = target_files[fmt]
|
|
281
|
+
success = inject_rules_into_file(target_path, rules_block)
|
|
282
|
+
if success:
|
|
283
|
+
synced_targets.append(str(target_path.relative_to(root)))
|
|
284
|
+
|
|
285
|
+
# Estimate token overhead (approx 4 chars/token)
|
|
286
|
+
token_est = max(1, len(rules_block) // 4)
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
"status": "success" if synced_targets else "skipped",
|
|
290
|
+
"synced_files": synced_targets,
|
|
291
|
+
"token_estimate": token_est,
|
|
292
|
+
"within_budget": token_est <= MAX_PROMPT_TOKENS
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def main():
|
|
297
|
+
parser = argparse.ArgumentParser(description="TorusGuard AI IDE Rules Auto-Sync Engine")
|
|
298
|
+
parser.add_argument(
|
|
299
|
+
"--format",
|
|
300
|
+
choices=["all", "cursor", "claude", "agent", "windsurf"],
|
|
301
|
+
default="all",
|
|
302
|
+
help="Target AI IDE rules format to sync"
|
|
303
|
+
)
|
|
304
|
+
parser.add_argument("--root", help="Project root override")
|
|
305
|
+
parser.add_argument("--json", action="store_true", help="Output raw JSON")
|
|
306
|
+
|
|
307
|
+
args = parser.parse_args()
|
|
308
|
+
root = Path(args.root).resolve() if args.root else None
|
|
309
|
+
|
|
310
|
+
result = sync_rules(target_format=args.format, root_dir=root)
|
|
311
|
+
if args.json:
|
|
312
|
+
print(json.dumps(result, indent=2))
|
|
313
|
+
else:
|
|
314
|
+
print(f"[SUCCESS] Synced TorusGuard security invariants to {len(result['synced_files'])} file(s):")
|
|
315
|
+
for f in result["synced_files"]:
|
|
316
|
+
print(f" - {f}")
|
|
317
|
+
print(f"Token estimate: ~{result['token_estimate']} tokens (budget <= {MAX_PROMPT_TOKENS})")
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
if __name__ == "__main__":
|
|
321
|
+
main()
|
|
@@ -13,8 +13,17 @@ from pathlib import Path
|
|
|
13
13
|
from typing import Dict, Any, List, Optional
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
# ─── Timezone Configuration: Indian Standard Time (IST, UTC+05:30) ───────────
|
|
17
|
+
IST = datetime.timezone(datetime.timedelta(hours=5, minutes=30), name="IST")
|
|
18
|
+
|
|
19
|
+
def get_ist_now() -> datetime.datetime:
|
|
20
|
+
"""Return timezone-aware datetime strictly in Indian Standard Time (IST)."""
|
|
21
|
+
return datetime.datetime.now(IST)
|
|
22
|
+
|
|
23
|
+
|
|
16
24
|
def create_run(base_dir: Path, command: str, target_name: str = "project") -> Path:
|
|
17
|
-
|
|
25
|
+
now_ist = get_ist_now()
|
|
26
|
+
timestamp = now_ist.strftime("%Y%m%d-%H%M%S")
|
|
18
27
|
run_id = f"run-{timestamp}-{command}"
|
|
19
28
|
run_folder = base_dir / run_id
|
|
20
29
|
run_folder.mkdir(parents=True, exist_ok=True)
|
|
@@ -23,9 +32,10 @@ def create_run(base_dir: Path, command: str, target_name: str = "project") -> Pa
|
|
|
23
32
|
"run_id": run_id,
|
|
24
33
|
"command": command,
|
|
25
34
|
"target_name": target_name,
|
|
26
|
-
"created_at":
|
|
35
|
+
"created_at": now_ist.strftime("%Y-%m-%d %H:%M:%S IST"),
|
|
36
|
+
"created_at_iso": now_ist.isoformat(),
|
|
27
37
|
"status": "in_progress",
|
|
28
|
-
"torusguard_version": "1.
|
|
38
|
+
"torusguard_version": "1.3.0",
|
|
29
39
|
"findings_count": 0,
|
|
30
40
|
"confirmed_fixed_count": 0,
|
|
31
41
|
"regressed_count": 0
|
|
@@ -136,7 +146,8 @@ def main():
|
|
|
136
146
|
subparsers = parser.add_subparsers(dest="subcommand")
|
|
137
147
|
|
|
138
148
|
create_p = subparsers.add_parser("create")
|
|
139
|
-
create_p.add_argument("
|
|
149
|
+
create_p.add_argument("cmd_pos", nargs="?", default=None, help="TorusGuard command (positional)")
|
|
150
|
+
create_p.add_argument("--command", "-c", default=None, help="TorusGuard command (audit, web-validate, harden, etc.)")
|
|
140
151
|
create_p.add_argument("--target", "-t", default="project", help="Target project name")
|
|
141
152
|
create_p.add_argument("--dir", "-d", default=".torusguard/runs", help="Base runs directory")
|
|
142
153
|
|
|
@@ -150,7 +161,8 @@ def main():
|
|
|
150
161
|
args = parser.parse_args()
|
|
151
162
|
|
|
152
163
|
if args.subcommand == "create":
|
|
153
|
-
|
|
164
|
+
eff_command = args.cmd_pos or args.command or "audit"
|
|
165
|
+
folder = create_run(Path(args.dir), eff_command, args.target)
|
|
154
166
|
print(f"Created run folder: {folder}")
|
|
155
167
|
elif args.subcommand == "list":
|
|
156
168
|
runs = list_runs(Path(args.dir))
|