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
|
@@ -15,12 +15,39 @@ from pathlib import Path
|
|
|
15
15
|
from typing import Dict, List, Any, Optional
|
|
16
16
|
|
|
17
17
|
BYPASS_PATTERNS = [
|
|
18
|
-
(re.compile(r'(
|
|
18
|
+
(re.compile(r'(?:#|//|/\*)\s*(?:TODO\s*:?\s*)?(?:bypass|skip|disable)[_\s]*(?:auth|security|check|guard|filter|csrf|tenant)', re.IGNORECASE), "Suspicious authentication or security check bypass comment"),
|
|
19
|
+
# TLS / Certificate validation bypasses across Python, Go, Node, Java, C#, PHP, Rust
|
|
19
20
|
(re.compile(r'\bverify\s*=\s*False\b'), "Disabled TLS certificate verification (verify=False)"),
|
|
21
|
+
(re.compile(r'\bInsecureSkipVerify\s*:\s*true\b'), "Disabled Go TLS certificate verification (InsecureSkipVerify: true)"),
|
|
22
|
+
(re.compile(r'\bNODE_TLS_REJECT_UNAUTHORIZED\s*=\s*[\'"]?0[\'"]?'), "Disabled Node.js TLS verification (NODE_TLS_REJECT_UNAUTHORIZED=0)"),
|
|
23
|
+
(re.compile(r'\brejectUnauthorized\s*:\s*false\b'), "Disabled Node.js TLS rejectUnauthorized"),
|
|
24
|
+
(re.compile(r'\b(?:TrustAllStrategy|NoopHostnameVerifier|DangerousAcceptAnyServerCertificateValidator)\b'), "Disabled Java / C# TLS certificate validation"),
|
|
25
|
+
(re.compile(r'\bServerCertificateCustomValidationCallback\s*=\s*(?:\([^)]*\)\s*=>\s*true|HttpClientHandler\.DangerousAcceptAnyServerCertificateValidator)'), "Disabled C# TLS certificate callback"),
|
|
26
|
+
(re.compile(r'\bCURLOPT_SSL_VERIFYPEER\s*(?:=>|,)\s*(?:false|0)\b', re.IGNORECASE), "Disabled PHP curl SSL verification (CURLOPT_SSL_VERIFYPEER => false)"),
|
|
27
|
+
(re.compile(r'\bdanger_accept_invalid_certs\s*\(\s*true\s*\)'), "Disabled Rust reqwest TLS certificate validation"),
|
|
28
|
+
# Auth & CSRF bypasses
|
|
20
29
|
(re.compile(r'\b(?:skip_auth|bypass_auth|disable_auth|allow_all|permit_all)\s*=\s*True\b', re.IGNORECASE), "Explicit security bypass flag enabled"),
|
|
21
30
|
(re.compile(r'@(?:csrf_exempt|allow_anonymous|disable_token_check)\b'), "Decorator disabling route-level security or CSRF protection"),
|
|
31
|
+
(re.compile(r'\[(?:AllowAnonymous|Authorize\s*\(\s*Roles\s*=\s*"\*"\s*\))\]'), "Attribute disabling ASP.NET authentication or authorization"),
|
|
32
|
+
(re.compile(r'\.csrf\(\)\.disable\(\)|\.csrf\([^)]*AbstractHttpConfigurer::disable\)'), "Spring Security CSRF protection explicitly disabled"),
|
|
33
|
+
# CORS wildcard with credentials
|
|
22
34
|
(re.compile(r'\bCORS_ALLOW_ALL_ORIGINS\s*=\s*True\b'), "Wildcard CORS origin enabled in patch"),
|
|
23
|
-
(re.compile(r'(
|
|
35
|
+
(re.compile(r'@CrossOrigin\s*\(\s*(?:origins\s*=\s*)?["\']\*["\']'), "Wildcard CORS origin annotation in Java/Spring"),
|
|
36
|
+
# Native dangerous constructs
|
|
37
|
+
(re.compile(r'\bextract\s*\(\s*\$_(?:POST|GET|REQUEST)\s*\)'), "Dangerous PHP extract() on untrusted user input"),
|
|
38
|
+
(re.compile(r'\bunsafe\s*\{'), "Unvetted Rust unsafe block introduced in patch"),
|
|
39
|
+
# Polyglot additional security bypasses (Python, Ruby, Java, Kotlin, Elixir, Dart, C++)
|
|
40
|
+
(re.compile(r'\bSESSION_COOKIE_SECURE\s*=\s*False\b'), "Session cookie secure flag disabled"),
|
|
41
|
+
(re.compile(r'\bparams\.permit!'), "Rails strong parameters mass assignment bypass (params.permit!)"),
|
|
42
|
+
(re.compile(r'\b(?:csrf(?:\(\))?\.disable\(\)|\.csrf\(\)\.disable\(\)|\.csrf\([^)]*AbstractHttpConfigurer::disable\))'), "CSRF protection explicitly disabled"),
|
|
43
|
+
(re.compile(r'\b(?:verify_peer\s*:\s*false|verify\s*:\s*:verify_none)\b'), "Disabled Elixir TLS certificate verification"),
|
|
44
|
+
(re.compile(r'\bbadCertificateCallback\s*='), "Disabled Dart/Flutter badCertificateCallback validation"),
|
|
45
|
+
(re.compile(r'\bSSL_VERIFY_NONE\b'), "Disabled C/C++ OpenSSL certificate verification (SSL_VERIFY_NONE)"),
|
|
46
|
+
(re.compile(r'\bpermitAll\(\)'), "Unrestricted access granted via permitAll()"),
|
|
47
|
+
(re.compile(r'\bverify\s*(?:=>|=)\s*false\b', re.IGNORECASE), "Disabled TLS/HTTP client verification (verify => false)"),
|
|
48
|
+
# Linters and scanners suppressions
|
|
49
|
+
(re.compile(r'(?:#|//|/\*)\s*nosec\b', re.IGNORECASE), "Suppression comment (nosec) hiding potential vulnerability"),
|
|
50
|
+
(re.compile(r'@SuppressWarnings\s*\(\s*["\'](?:security|all)["\']\s*\)'), "Java security suppression annotation")
|
|
24
51
|
]
|
|
25
52
|
|
|
26
53
|
SECRET_PATTERNS = [
|
|
@@ -35,7 +62,10 @@ TENANT_FILTER_PATTERNS = [
|
|
|
35
62
|
re.compile(r'\.filter\([^)]*\btenant\s*='),
|
|
36
63
|
re.compile(r'\.filter_by\([^)]*\btenant\s*='),
|
|
37
64
|
re.compile(r'\bwhere\s+tenant_id\s*='),
|
|
38
|
-
re.compile(r'\btenant_id\s*==?')
|
|
65
|
+
re.compile(r'\btenant_id\s*==?'),
|
|
66
|
+
re.compile(r'\btenantId\s*:'),
|
|
67
|
+
re.compile(r'\.Where\([^)]*(?:tenant_id|TenantId)'),
|
|
68
|
+
re.compile(r'\bwhere\s*:\s*\{[^}]*tenant')
|
|
39
69
|
]
|
|
40
70
|
|
|
41
71
|
|
|
@@ -87,6 +117,50 @@ def check_memory_regressions(
|
|
|
87
117
|
return violations
|
|
88
118
|
|
|
89
119
|
|
|
120
|
+
def is_exempt_diff_path(file_path: Optional[str]) -> bool:
|
|
121
|
+
"""
|
|
122
|
+
Detects whether a file path is exempt from diff guard checks.
|
|
123
|
+
Documentation, rule manifests, AI editor prompts, test fixtures, and scanner
|
|
124
|
+
definitions are exempt to prevent false alarms on security instructions and mock data.
|
|
125
|
+
"""
|
|
126
|
+
if not file_path:
|
|
127
|
+
return False
|
|
128
|
+
clean = file_path.replace("\\", "/").lower().strip()
|
|
129
|
+
if clean in ("unknown", "", "none"):
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
# Documentation, changelogs, markdown, plain text
|
|
133
|
+
if clean.endswith((".md", ".txt", ".rst", ".jsonl")):
|
|
134
|
+
return True
|
|
135
|
+
|
|
136
|
+
# AI editor prompt and rule instruction files
|
|
137
|
+
if clean.endswith((".cursorrules", ".windsurfrules")) or clean in ("claude.md", "agents.md"):
|
|
138
|
+
return True
|
|
139
|
+
if ".agent/rules" in clean or ".cursor/rules" in clean:
|
|
140
|
+
return True
|
|
141
|
+
|
|
142
|
+
# Security rule catalog, schemas, and cryptographic manifests
|
|
143
|
+
if "/rules/" in clean or clean.startswith("rules/") or "/schemas/" in clean or clean.startswith("schemas/"):
|
|
144
|
+
return True
|
|
145
|
+
if clean.endswith((".schema.json", ".manifest.json")):
|
|
146
|
+
return True
|
|
147
|
+
|
|
148
|
+
# Test fixtures, test suites, mocks, and test harness
|
|
149
|
+
test_markers = [
|
|
150
|
+
"/test/", "/tests/", "/spec/", "/specs/", "/fixtures/", "/mock/", "/mocks/",
|
|
151
|
+
"/e2e/", "__tests__", "test_", "_test.", ".test.", ".spec.", "testcase",
|
|
152
|
+
"harness/"
|
|
153
|
+
]
|
|
154
|
+
if any(m in clean for m in test_markers) or clean.endswith(("_test.go", "test.java", "test.py", ".spec.ts", ".test.ts", ".spec.js", ".test.js")):
|
|
155
|
+
return True
|
|
156
|
+
|
|
157
|
+
# TorusGuard security engine scripts that define scanner regexes / templates
|
|
158
|
+
if ("/scripts/" in clean or clean.startswith("scripts/")) and any(s in clean for s in ("diff_guard", "harden_runner", "finding_scorer", "rules_sync", "memory_engine", "audit_runner", "apply_runner", "recheck_runner", "manifest_builder")):
|
|
159
|
+
return True
|
|
160
|
+
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
|
|
90
164
|
def audit_diff(
|
|
91
165
|
diff_content: str,
|
|
92
166
|
check_memory: bool = False,
|
|
@@ -103,7 +177,7 @@ def audit_diff(
|
|
|
103
177
|
current_line = 0
|
|
104
178
|
|
|
105
179
|
additions: List[tuple[int, str]] = []
|
|
106
|
-
deletions: List[tuple[int, str]] = []
|
|
180
|
+
deletions: List[tuple[str, int, str]] = []
|
|
107
181
|
|
|
108
182
|
for line_idx, line in enumerate(lines, 1):
|
|
109
183
|
if line.startswith('+++ b/'):
|
|
@@ -123,6 +197,9 @@ def audit_diff(
|
|
|
123
197
|
added_content = line[1:]
|
|
124
198
|
additions.append((current_line, added_content))
|
|
125
199
|
|
|
200
|
+
if is_exempt_diff_path(current_file):
|
|
201
|
+
continue
|
|
202
|
+
|
|
126
203
|
# Check bypass patterns
|
|
127
204
|
for pat, desc in BYPASS_PATTERNS:
|
|
128
205
|
if pat.search(added_content):
|
|
@@ -156,10 +233,11 @@ def audit_diff(
|
|
|
156
233
|
|
|
157
234
|
elif line.startswith('-') and not line.startswith('---'):
|
|
158
235
|
deleted_content = line[1:]
|
|
159
|
-
|
|
236
|
+
if not is_exempt_diff_path(current_file):
|
|
237
|
+
deletions.append((current_file, line_idx, deleted_content))
|
|
160
238
|
|
|
161
239
|
# Check for tenant filter deletion without replacement
|
|
162
|
-
for del_idx, del_line in deletions:
|
|
240
|
+
for del_file, del_idx, del_line in deletions:
|
|
163
241
|
for t_pat in TENANT_FILTER_PATTERNS:
|
|
164
242
|
if t_pat.search(del_line):
|
|
165
243
|
# Verify if an equivalent tenant filter exists in additions
|
|
@@ -169,7 +247,7 @@ def audit_diff(
|
|
|
169
247
|
"rule_id": "TG-DIFF-003",
|
|
170
248
|
"category": "Tenant Filter Removal",
|
|
171
249
|
"severity": "HIGH",
|
|
172
|
-
"file":
|
|
250
|
+
"file": del_file,
|
|
173
251
|
"line": del_idx,
|
|
174
252
|
"content": del_line.strip(),
|
|
175
253
|
"description": "Tenant isolation filter was removed without being restored in additions"
|
|
@@ -198,14 +276,110 @@ def audit_diff_file(file_path: str, check_memory: bool = False, root_dir: Option
|
|
|
198
276
|
return audit_diff(content, check_memory=check_memory, root_dir=root_dir)
|
|
199
277
|
|
|
200
278
|
|
|
279
|
+
def check_diff_content(diff_content: str, file_path: str = "") -> List[Dict[str, Any]]:
|
|
280
|
+
"""Convenience helper to audit diff string directly and return list of violations."""
|
|
281
|
+
res = audit_diff(diff_content)
|
|
282
|
+
return res.get("violations", [])
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def install_pre_commit_hook(root_dir: Optional[Path] = None) -> bool:
|
|
286
|
+
"""Install TorusGuard pre-commit security hook into .git/hooks/pre-commit."""
|
|
287
|
+
base = Path(root_dir or Path.cwd()).resolve()
|
|
288
|
+
git_dir = base / ".git"
|
|
289
|
+
if not git_dir.exists():
|
|
290
|
+
for parent in base.parents:
|
|
291
|
+
if (parent / ".git").exists():
|
|
292
|
+
git_dir = parent / ".git"
|
|
293
|
+
break
|
|
294
|
+
if not git_dir.exists():
|
|
295
|
+
print("[ERROR] Diff Guard: Not a git repository (no .git directory found).", file=sys.stderr)
|
|
296
|
+
return False
|
|
297
|
+
|
|
298
|
+
hooks_dir = git_dir / "hooks"
|
|
299
|
+
hooks_dir.mkdir(parents=True, exist_ok=True)
|
|
300
|
+
hook_file = hooks_dir / "pre-commit"
|
|
301
|
+
|
|
302
|
+
hook_script = """#!/usr/bin/env sh
|
|
303
|
+
# TorusGuard Pre-Commit Security Diff Guard
|
|
304
|
+
# Automatically blocks commits containing security bypasses, secret leaks, or tenant stripping.
|
|
305
|
+
python .torusguard/scripts/diff_guard.py --pre-commit
|
|
306
|
+
"""
|
|
307
|
+
try:
|
|
308
|
+
hook_file.write_text(hook_script, encoding="utf-8")
|
|
309
|
+
if os.name != "nt":
|
|
310
|
+
import stat
|
|
311
|
+
os.chmod(hook_file, hook_file.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
312
|
+
print(f"[SUCCESS] Installed TorusGuard pre-commit hook at: {hook_file}")
|
|
313
|
+
return True
|
|
314
|
+
except Exception as e:
|
|
315
|
+
print(f"[ERROR] Diff Guard: Failed to install pre-commit hook: {e}", file=sys.stderr)
|
|
316
|
+
return False
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def uninstall_pre_commit_hook(root_dir: Optional[Path] = None) -> bool:
|
|
320
|
+
"""Uninstall TorusGuard pre-commit hook from .git/hooks/pre-commit."""
|
|
321
|
+
base = Path(root_dir or Path.cwd()).resolve()
|
|
322
|
+
git_dir = base / ".git"
|
|
323
|
+
if not git_dir.exists():
|
|
324
|
+
for parent in base.parents:
|
|
325
|
+
if (parent / ".git").exists():
|
|
326
|
+
git_dir = parent / ".git"
|
|
327
|
+
break
|
|
328
|
+
if not git_dir.exists():
|
|
329
|
+
print("[WARN] Diff Guard: No .git directory found.", file=sys.stderr)
|
|
330
|
+
return False
|
|
331
|
+
|
|
332
|
+
hook_file = git_dir / "hooks" / "pre-commit"
|
|
333
|
+
if hook_file.exists():
|
|
334
|
+
try:
|
|
335
|
+
hook_file.unlink()
|
|
336
|
+
print("[SUCCESS] Uninstalled TorusGuard pre-commit hook.")
|
|
337
|
+
return True
|
|
338
|
+
except Exception as e:
|
|
339
|
+
print(f"[ERROR] Diff Guard: Failed to delete hook file: {e}", file=sys.stderr)
|
|
340
|
+
return False
|
|
341
|
+
else:
|
|
342
|
+
print("[INFO] Diff Guard: No pre-commit hook currently installed.")
|
|
343
|
+
return True
|
|
344
|
+
|
|
345
|
+
|
|
201
346
|
def main():
|
|
202
347
|
parser = argparse.ArgumentParser(description="TorusGuard Unified Diff Security Scanner")
|
|
203
348
|
parser.add_argument("diff_path", nargs="?", help="Path to unified diff file (or read stdin if omitted)")
|
|
204
349
|
parser.add_argument("--check-memory", action="store_true", help="Check additions against persistent memory regression watch patterns")
|
|
350
|
+
parser.add_argument("--pre-commit", action="store_true", help="Audit git staged diff (--cached) for pre-commit hook")
|
|
351
|
+
parser.add_argument("--install-hook", action="store_true", help="Install TorusGuard pre-commit hook into .git/hooks/pre-commit")
|
|
352
|
+
parser.add_argument("--uninstall-hook", action="store_true", help="Uninstall TorusGuard pre-commit hook")
|
|
205
353
|
parser.add_argument("--json", action="store_true", help="Output results as JSON")
|
|
206
354
|
args = parser.parse_args()
|
|
207
355
|
|
|
208
|
-
if args.
|
|
356
|
+
if args.install_hook:
|
|
357
|
+
sys.exit(0 if install_pre_commit_hook() else 1)
|
|
358
|
+
|
|
359
|
+
if args.uninstall_hook:
|
|
360
|
+
sys.exit(0 if uninstall_pre_commit_hook() else 1)
|
|
361
|
+
|
|
362
|
+
if args.pre_commit:
|
|
363
|
+
import subprocess
|
|
364
|
+
try:
|
|
365
|
+
res_git = subprocess.run(
|
|
366
|
+
["git", "diff", "--cached"],
|
|
367
|
+
capture_output=True,
|
|
368
|
+
text=True,
|
|
369
|
+
encoding="utf-8",
|
|
370
|
+
errors="replace"
|
|
371
|
+
)
|
|
372
|
+
diff_text = res_git.stdout
|
|
373
|
+
except Exception as e:
|
|
374
|
+
print(f"[ERROR] Diff Guard: Could not read git staged diff: {e}", file=sys.stderr)
|
|
375
|
+
sys.exit(1)
|
|
376
|
+
|
|
377
|
+
if not diff_text.strip():
|
|
378
|
+
print("[PASS] Diff Guard (pre-commit): No staged changes detected.")
|
|
379
|
+
sys.exit(0)
|
|
380
|
+
|
|
381
|
+
res = audit_diff(diff_text, check_memory=True)
|
|
382
|
+
elif args.diff_path:
|
|
209
383
|
res = audit_diff_file(args.diff_path, check_memory=args.check_memory)
|
|
210
384
|
else:
|
|
211
385
|
if sys.stdin.isatty():
|
|
@@ -229,3 +403,4 @@ def main():
|
|
|
229
403
|
|
|
230
404
|
if __name__ == "__main__":
|
|
231
405
|
main()
|
|
406
|
+
|
|
@@ -44,11 +44,13 @@ def compute_memory_boost(
|
|
|
44
44
|
try:
|
|
45
45
|
with open(patterns_file, "r", encoding="utf-8") as f:
|
|
46
46
|
patterns = json.load(f)
|
|
47
|
-
except
|
|
47
|
+
except (json.JSONDecodeError, OSError, UnicodeDecodeError):
|
|
48
48
|
return 0
|
|
49
49
|
|
|
50
50
|
boost = 0
|
|
51
51
|
matched_file = False
|
|
52
|
+
matched_dir = False
|
|
53
|
+
target_path = Path(file_path) if file_path else None
|
|
52
54
|
|
|
53
55
|
for pat in patterns:
|
|
54
56
|
if pat.get("rule_id") == rule_id:
|
|
@@ -62,18 +64,37 @@ def compute_memory_boost(
|
|
|
62
64
|
elif ptype == "security_idiom":
|
|
63
65
|
boost += 5
|
|
64
66
|
|
|
65
|
-
# File-specific correlation bonus
|
|
66
|
-
|
|
67
|
+
# File-specific and directory-level correlation bonus
|
|
68
|
+
affected = pat.get("affected_files", [])
|
|
69
|
+
if file_path and file_path in affected:
|
|
67
70
|
matched_file = True
|
|
71
|
+
elif target_path and any(target_path.parent == Path(af).parent for af in affected if af):
|
|
72
|
+
matched_dir = True
|
|
68
73
|
|
|
69
74
|
if matched_file and boost > 0:
|
|
70
75
|
boost += 5
|
|
71
76
|
elif matched_file and boost < 0:
|
|
72
77
|
boost -= 10
|
|
78
|
+
elif matched_dir and boost > 0:
|
|
79
|
+
boost += 2
|
|
80
|
+
elif matched_dir and boost < 0:
|
|
81
|
+
boost -= 4
|
|
73
82
|
|
|
74
83
|
return boost
|
|
75
84
|
|
|
76
85
|
|
|
86
|
+
def is_test_path(file_path: Optional[str]) -> bool:
|
|
87
|
+
"""Detects whether a file path belongs to a test suite, fixture, or mock."""
|
|
88
|
+
if not file_path:
|
|
89
|
+
return False
|
|
90
|
+
clean = file_path.replace("\\", "/").lower()
|
|
91
|
+
test_markers = [
|
|
92
|
+
"/test/", "/tests/", "/spec/", "/specs/", "/fixtures/", "/mock/", "/mocks/",
|
|
93
|
+
"/e2e/", "__tests__", "test_", "_test.", ".test.", ".spec.", "testcase"
|
|
94
|
+
]
|
|
95
|
+
return any(marker in clean for marker in test_markers) or clean.endswith(("_test.go", "test.java", "test.py", ".spec.ts", ".test.ts", ".spec.js", ".test.js"))
|
|
96
|
+
|
|
97
|
+
|
|
77
98
|
def compute_confidence_score(
|
|
78
99
|
evidence_quality: int = 35,
|
|
79
100
|
reproduction_success: int = 0,
|
|
@@ -84,7 +105,7 @@ def compute_confidence_score(
|
|
|
84
105
|
rule_id: Optional[str] = None,
|
|
85
106
|
file_path: Optional[str] = None,
|
|
86
107
|
root_dir: Optional[Path] = None
|
|
87
|
-
) -> Tuple[int, str, Dict[str,
|
|
108
|
+
) -> Tuple[int, str, Dict[str, Any]]:
|
|
88
109
|
"""
|
|
89
110
|
Computes total score and assigns confidence band.
|
|
90
111
|
Max points:
|
|
@@ -94,6 +115,7 @@ def compute_confidence_score(
|
|
|
94
115
|
- environmental_clarity: 15
|
|
95
116
|
- manual_review_status: 10
|
|
96
117
|
- memory_boost: -30 to +20 (modifier from persistent memory)
|
|
118
|
+
- test_deduction: -30 if file is located in a test/mock path
|
|
97
119
|
Total is clamped to [0, 100].
|
|
98
120
|
"""
|
|
99
121
|
eq = min(max(evidence_quality, 0), 35)
|
|
@@ -107,7 +129,11 @@ def compute_confidence_score(
|
|
|
107
129
|
if rule_id and eff_mem_boost == 0:
|
|
108
130
|
eff_mem_boost = compute_memory_boost(rule_id, file_path=file_path, root_dir=root_dir)
|
|
109
131
|
|
|
110
|
-
|
|
132
|
+
# Test path noise suppression: -30 deduction for test mocks/fixtures
|
|
133
|
+
is_test = is_test_path(file_path)
|
|
134
|
+
test_deduction = -30 if is_test else 0
|
|
135
|
+
|
|
136
|
+
raw_total = eq + rs + ic + ec + mr + eff_mem_boost + test_deduction
|
|
111
137
|
total = min(max(raw_total, 0), 100)
|
|
112
138
|
|
|
113
139
|
if total >= 90:
|
|
@@ -126,6 +152,8 @@ def compute_confidence_score(
|
|
|
126
152
|
"environmental_clarity": ec,
|
|
127
153
|
"manual_review_status": mr,
|
|
128
154
|
"memory_boost": eff_mem_boost,
|
|
155
|
+
"test_exemption": is_test,
|
|
156
|
+
"test_deduction": test_deduction,
|
|
129
157
|
"total_score": total,
|
|
130
158
|
"classification_band": band
|
|
131
159
|
}
|
|
@@ -134,6 +162,8 @@ def compute_confidence_score(
|
|
|
134
162
|
|
|
135
163
|
def main():
|
|
136
164
|
parser = argparse.ArgumentParser(description="TorusGuard Confidence Scorer")
|
|
165
|
+
parser.add_argument("--dir", type=str, help="Target project root directory to scan and score")
|
|
166
|
+
parser.add_argument("--run", type=str, help="Path to run directory to evaluate/score")
|
|
137
167
|
parser.add_argument("--eq", type=int, default=35, help="Evidence quality score (0-35)")
|
|
138
168
|
parser.add_argument("--rs", type=int, default=0, help="Reproduction success score (0-25)")
|
|
139
169
|
parser.add_argument("--ic", type=int, default=5, help="Independent confirmations score (0-15)")
|
|
@@ -145,6 +175,62 @@ def main():
|
|
|
145
175
|
parser.add_argument("--json", action="store_true", help="Output JSON")
|
|
146
176
|
args = parser.parse_args()
|
|
147
177
|
|
|
178
|
+
# Bridge: when --dir is provided, delegate to audit_runner
|
|
179
|
+
if args.dir:
|
|
180
|
+
scripts_dir = Path(__file__).resolve().parent
|
|
181
|
+
if str(scripts_dir) not in sys.path:
|
|
182
|
+
sys.path.insert(0, str(scripts_dir))
|
|
183
|
+
try:
|
|
184
|
+
import audit_runner
|
|
185
|
+
res = audit_runner.execute_audit(Path(args.dir), json_output=args.json)
|
|
186
|
+
sys.exit(0 if res.get("critical_count", 0) == 0 else 1)
|
|
187
|
+
except Exception as e:
|
|
188
|
+
print(f"[ERROR] Finding Scorer: Failed to run audit on {args.dir}: {e}", file=sys.stderr)
|
|
189
|
+
sys.exit(1)
|
|
190
|
+
|
|
191
|
+
# Bridge: when --run is provided, score findings in run folder
|
|
192
|
+
if args.run:
|
|
193
|
+
run_p = Path(args.run).resolve()
|
|
194
|
+
f_file = run_p / "findings.json"
|
|
195
|
+
if not f_file.is_file():
|
|
196
|
+
print(f"[ERROR] Run findings not found at: {f_file}", file=sys.stderr)
|
|
197
|
+
sys.exit(1)
|
|
198
|
+
try:
|
|
199
|
+
with open(f_file, "r", encoding="utf-8") as f:
|
|
200
|
+
findings_data = json.load(f)
|
|
201
|
+
except Exception as e:
|
|
202
|
+
print(f"[ERROR] Malformed findings JSON: {e}", file=sys.stderr)
|
|
203
|
+
sys.exit(1)
|
|
204
|
+
|
|
205
|
+
total_score = 0
|
|
206
|
+
scored_items = []
|
|
207
|
+
for item in findings_data:
|
|
208
|
+
s, b, factors = compute_confidence_score(
|
|
209
|
+
evidence_quality=item.get("evidence_quality", 35),
|
|
210
|
+
reproduction_success=item.get("reproduction_success", 0),
|
|
211
|
+
independent_confirmations=item.get("independent_confirmations", 5),
|
|
212
|
+
environmental_clarity=item.get("environmental_clarity", 15),
|
|
213
|
+
manual_review_status=item.get("manual_review_status", 0),
|
|
214
|
+
rule_id=item.get("rule_id"),
|
|
215
|
+
file_path=item.get("file_path")
|
|
216
|
+
)
|
|
217
|
+
item["confidence_score"] = s
|
|
218
|
+
item["confidence_band"] = b
|
|
219
|
+
item["confidence_factors"] = factors
|
|
220
|
+
scored_items.append(item)
|
|
221
|
+
total_score += s
|
|
222
|
+
|
|
223
|
+
avg_score = int(total_score / max(1, len(scored_items)))
|
|
224
|
+
with open(f_file, "w", encoding="utf-8") as f:
|
|
225
|
+
json.dump(scored_items, f, indent=2)
|
|
226
|
+
|
|
227
|
+
if args.json:
|
|
228
|
+
print(json.dumps({"run": str(run_p), "findings_count": len(scored_items), "average_confidence": avg_score}, indent=2))
|
|
229
|
+
else:
|
|
230
|
+
print(f"[SUCCESS] Scored {len(scored_items)} findings in {run_p.name}")
|
|
231
|
+
print(f"Average Confidence: {avg_score}/100")
|
|
232
|
+
sys.exit(0)
|
|
233
|
+
|
|
148
234
|
total, band, factors = compute_confidence_score(
|
|
149
235
|
evidence_quality=args.eq,
|
|
150
236
|
reproduction_success=args.rs,
|