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.
Files changed (411) hide show
  1. package/.torusguard/.manifest.json +196 -78
  2. package/.torusguard/references/csharp-security.md +41 -0
  3. package/.torusguard/references/go-security.md +41 -0
  4. package/.torusguard/references/java-security.md +40 -0
  5. package/.torusguard/references/polyglot-security-matrix.md +25 -0
  6. package/.torusguard/references/rust-security.md +40 -0
  7. package/.torusguard/rules/README.md +93 -62
  8. package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
  9. package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
  10. package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
  11. package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
  12. package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
  13. package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
  14. package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  15. package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
  16. package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
  17. package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
  18. package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  19. package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
  20. package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  21. package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  22. package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  23. package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  24. package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  25. package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  26. package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
  27. package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  28. package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  29. package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  30. package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  31. package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  32. package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
  33. package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
  34. package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
  35. package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
  36. package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
  37. package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
  38. package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
  39. package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
  40. package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
  41. package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
  42. package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  43. package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
  44. package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
  45. package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
  46. package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  47. package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
  48. package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  49. package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  50. package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  51. package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  52. package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  53. package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  54. package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
  55. package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  56. package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  57. package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  58. package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  59. package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  60. package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
  61. package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
  62. package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
  63. package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
  64. package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
  65. package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
  66. package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
  67. package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
  68. package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
  69. package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
  70. package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
  71. package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
  72. package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
  73. package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
  74. package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
  75. package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
  76. package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
  77. package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
  78. package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
  79. package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
  80. package/.torusguard/rules/custom/.gitkeep +1 -0
  81. package/.torusguard/rules/custom/README.md +30 -0
  82. package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
  83. package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
  84. package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
  85. package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
  86. package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
  87. package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
  88. package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
  89. package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
  90. package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
  91. package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
  92. package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
  93. package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
  94. package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
  95. package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
  96. package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
  97. package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
  98. package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
  99. package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
  100. package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
  101. package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
  102. package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
  103. package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
  104. package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
  105. package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
  106. package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
  107. package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
  108. package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
  109. package/.torusguard/runs/report-latest.html +370 -0
  110. package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
  111. package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
  112. package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
  113. package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
  114. package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
  115. package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
  116. package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
  117. package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
  118. package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
  119. package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
  120. package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
  121. package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
  122. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
  123. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
  124. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
  125. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
  126. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
  127. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
  128. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
  129. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
  130. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
  131. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
  132. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
  133. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
  134. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
  135. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
  136. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
  137. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
  138. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
  139. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
  140. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
  141. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
  142. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
  143. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
  144. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
  145. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
  146. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
  147. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
  148. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
  149. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
  150. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
  151. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
  152. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
  153. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
  154. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
  155. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
  156. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
  157. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
  158. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
  159. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
  160. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
  161. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
  162. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
  163. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
  164. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
  165. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
  166. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
  167. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
  168. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
  169. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
  170. package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
  171. package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
  172. package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
  173. package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
  174. package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
  175. package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
  176. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
  177. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
  178. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
  179. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
  180. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
  181. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
  182. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
  183. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
  184. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
  185. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
  186. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
  187. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
  188. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
  189. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
  190. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
  191. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
  192. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
  193. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
  194. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
  195. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
  196. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
  197. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
  198. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
  199. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
  200. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
  201. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
  202. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
  203. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
  204. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
  205. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
  206. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
  207. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
  208. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
  209. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
  210. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
  211. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
  212. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
  213. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
  214. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
  215. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
  216. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
  217. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
  218. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
  219. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
  220. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
  221. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
  222. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
  223. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
  224. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
  225. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
  226. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
  227. package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
  228. package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
  229. package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
  230. package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
  231. package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
  232. package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
  233. package/.torusguard/runs/run-20260908-115240-audit/summary.md +5 -0
  234. package/.torusguard/schemas/golden-recipe.schema.json +75 -0
  235. package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
  236. package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
  237. package/.torusguard/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
  238. package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
  239. package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
  240. package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
  241. package/.torusguard/scripts/apply_runner.py +332 -0
  242. package/.torusguard/scripts/audit_runner.py +550 -0
  243. package/.torusguard/scripts/diff_guard.py +183 -8
  244. package/.torusguard/scripts/finding_scorer.py +91 -5
  245. package/.torusguard/scripts/harden_runner.py +353 -0
  246. package/.torusguard/scripts/html_reporter.py +643 -0
  247. package/.torusguard/scripts/manifest_builder.py +7 -5
  248. package/.torusguard/scripts/memory_engine.py +525 -99
  249. package/.torusguard/scripts/monorepo_detector.py +123 -10
  250. package/.torusguard/scripts/recheck_runner.py +221 -0
  251. package/.torusguard/scripts/recipes_runner.py +130 -0
  252. package/.torusguard/scripts/rules_sync.py +321 -0
  253. package/.torusguard/scripts/run_manager.py +17 -5
  254. package/.torusguard/scripts/stack_detect.py +458 -26
  255. package/.torusguard/skills/torusguard/SKILL.md +42 -42
  256. package/.torusguard/skills/torusguard/references/csharp-security.md +41 -0
  257. package/.torusguard/skills/torusguard/references/go-security.md +41 -0
  258. package/.torusguard/skills/torusguard/references/java-security.md +40 -0
  259. package/.torusguard/skills/torusguard/references/polyglot-security-matrix.md +25 -0
  260. package/.torusguard/skills/torusguard/references/rust-security.md +40 -0
  261. package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
  262. package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
  263. package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
  264. package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
  265. package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
  266. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
  267. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
  268. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
  269. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
  270. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
  271. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
  272. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
  273. package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
  274. package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
  275. package/README.md +344 -410
  276. package/bin/torusguard.js +195 -21
  277. package/package.json +1 -1
  278. package/skills/torusguard/SKILL.md +42 -42
  279. package/skills/torusguard/bootstrap.py +149 -70
  280. package/skills/torusguard/payload/.manifest.json +196 -78
  281. package/skills/torusguard/payload/references/csharp-security.md +41 -0
  282. package/skills/torusguard/payload/references/go-security.md +41 -0
  283. package/skills/torusguard/payload/references/java-security.md +40 -0
  284. package/skills/torusguard/payload/references/polyglot-security-matrix.md +25 -0
  285. package/skills/torusguard/payload/references/rust-security.md +40 -0
  286. package/skills/torusguard/payload/rules/README.md +93 -62
  287. package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
  288. package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
  289. package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
  290. package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
  291. package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
  292. package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
  293. package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  294. package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
  295. package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
  296. package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
  297. package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  298. package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
  299. package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  300. package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  301. package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  302. package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  303. package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  304. package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  305. package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
  306. package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  307. package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  308. package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  309. package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  310. package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  311. package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
  312. package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
  313. package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
  314. package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
  315. package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
  316. package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
  317. package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
  318. package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
  319. package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
  320. package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
  321. package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  322. package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
  323. package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
  324. package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
  325. package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  326. package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
  327. package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  328. package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  329. package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  330. package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  331. package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  332. package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  333. package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
  334. package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  335. package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  336. package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  337. package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  338. package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  339. package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
  340. package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
  341. package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
  342. package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
  343. package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
  344. package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
  345. package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
  346. package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
  347. package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
  348. package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
  349. package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
  350. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
  351. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
  352. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
  353. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
  354. package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
  355. package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
  356. package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
  357. package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
  358. package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
  359. package/skills/torusguard/payload/rules/custom/.gitkeep +1 -0
  360. package/skills/torusguard/payload/rules/custom/README.md +30 -0
  361. package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
  362. package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
  363. package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
  364. package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
  365. package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
  366. package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
  367. package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
  368. package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
  369. package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
  370. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
  371. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
  372. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
  373. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
  374. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
  375. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
  376. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
  377. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
  378. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
  379. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
  380. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
  381. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
  382. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
  383. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
  384. package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
  385. package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
  386. package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
  387. package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
  388. package/skills/torusguard/payload/schemas/golden-recipe.schema.json +75 -0
  389. package/skills/torusguard/payload/scripts/apply_runner.py +332 -0
  390. package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
  391. package/skills/torusguard/payload/scripts/diff_guard.py +183 -8
  392. package/skills/torusguard/payload/scripts/finding_scorer.py +91 -5
  393. package/skills/torusguard/payload/scripts/harden_runner.py +353 -0
  394. package/skills/torusguard/payload/scripts/html_reporter.py +643 -0
  395. package/skills/torusguard/payload/scripts/manifest_builder.py +7 -5
  396. package/skills/torusguard/payload/scripts/memory_engine.py +525 -99
  397. package/skills/torusguard/payload/scripts/monorepo_detector.py +123 -10
  398. package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
  399. package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
  400. package/skills/torusguard/payload/scripts/rules_sync.py +321 -0
  401. package/skills/torusguard/payload/scripts/run_manager.py +17 -5
  402. package/skills/torusguard/payload/scripts/stack_detect.py +458 -26
  403. package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
  404. package/skills/torusguard/payload/skills/torusguard/bootstrap.py +149 -70
  405. package/skills/torusguard/payload/skills/torusguard/references/csharp-security.md +41 -0
  406. package/skills/torusguard/payload/skills/torusguard/references/go-security.md +41 -0
  407. package/skills/torusguard/payload/skills/torusguard/references/java-security.md +40 -0
  408. package/skills/torusguard/payload/skills/torusguard/references/polyglot-security-matrix.md +25 -0
  409. package/skills/torusguard/payload/skills/torusguard/references/rust-security.md +40 -0
  410. package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
  411. package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
@@ -26,7 +26,7 @@ def detect_package_info(abs_pkg_dir: Path, root: Path) -> Dict[str, Any]:
26
26
  # Check typescript / javascript
27
27
  package_json = pkg_dir / "package.json"
28
28
  if package_json.is_file() or list(pkg_dir.glob("*.ts")) or list(pkg_dir.glob("*.js")):
29
- language = "typescript"
29
+ language = "TypeScript" if (list(pkg_dir.glob("*.ts")) or list(pkg_dir.glob("**/*.ts"))) else "JavaScript"
30
30
  if package_json.is_file():
31
31
  try:
32
32
  with open(package_json, "r", encoding="utf-8") as f:
@@ -35,6 +35,8 @@ def detect_package_info(abs_pkg_dir: Path, root: Path) -> Dict[str, Any]:
35
35
  deps = {**pj.get("dependencies", {}), **pj.get("devDependencies", {})}
36
36
  if "next" in deps:
37
37
  framework = "nextjs"
38
+ elif "@nestjs/core" in deps:
39
+ framework = "nestjs"
38
40
  elif "express" in deps:
39
41
  framework = "express"
40
42
  elif "react" in deps:
@@ -51,7 +53,7 @@ def detect_package_info(abs_pkg_dir: Path, root: Path) -> Dict[str, Any]:
51
53
  reqs = pkg_dir / "requirements.txt"
52
54
  if pyproject.is_file() or reqs.is_file() or list(pkg_dir.glob("*.py")):
53
55
  if language == "unknown":
54
- language = "python"
56
+ language = "Python"
55
57
  content = ""
56
58
  if pyproject.is_file():
57
59
  content += pyproject.read_text(encoding="utf-8", errors="replace").lower()
@@ -61,17 +63,116 @@ def detect_package_info(abs_pkg_dir: Path, root: Path) -> Dict[str, Any]:
61
63
  content += pyf.read_text(encoding="utf-8", errors="replace").lower()
62
64
 
63
65
  if "fastapi" in content or "fastapi" in pkg_dir.name:
64
- framework = "fastapi"
66
+ framework = "FastAPI"
65
67
  elif "django" in content or "django" in pkg_dir.name:
66
- framework = "django"
68
+ framework = "Django"
67
69
  elif "flask" in content or "flask" in pkg_dir.name:
68
- framework = "flask"
70
+ framework = "Flask"
71
+
72
+ # Check Go
73
+ go_mod = pkg_dir / "go.mod"
74
+ if go_mod.is_file() or list(pkg_dir.glob("*.go")):
75
+ if language == "unknown":
76
+ language = "Go"
77
+ if go_mod.is_file():
78
+ try:
79
+ gc = go_mod.read_text(encoding="utf-8", errors="replace")
80
+ if "gin-gonic/gin" in gc:
81
+ framework = "Gin"
82
+ elif "gofiber/fiber" in gc:
83
+ framework = "Fiber"
84
+ elif "go-chi/chi" in gc:
85
+ framework = "Chi"
86
+ except Exception:
87
+ pass
88
+
89
+ # Check Rust
90
+ cargo_toml = pkg_dir / "Cargo.toml"
91
+ if cargo_toml.is_file() or list(pkg_dir.glob("*.rs")):
92
+ if language == "unknown":
93
+ language = "Rust"
94
+ if cargo_toml.is_file():
95
+ try:
96
+ cc = cargo_toml.read_text(encoding="utf-8", errors="replace")
97
+ if "actix-web" in cc:
98
+ framework = "Actix-web"
99
+ elif "axum" in cc:
100
+ framework = "Axum"
101
+ elif "rocket" in cc:
102
+ framework = "Rocket"
103
+ except Exception:
104
+ pass
105
+
106
+ # Check Java / Kotlin
107
+ pom_xml = pkg_dir / "pom.xml"
108
+ b_gradle = pkg_dir / "build.gradle"
109
+ b_gradle_kts = pkg_dir / "build.gradle.kts"
110
+ if pom_xml.is_file() or b_gradle.is_file() or b_gradle_kts.is_file() or list(pkg_dir.glob("**/*.java")) or list(pkg_dir.glob("**/*.kt")):
111
+ if language == "unknown":
112
+ language = "Kotlin" if (b_gradle_kts.is_file() or list(pkg_dir.glob("**/*.kt"))) else "Java"
113
+ jc = ""
114
+ for jf in [pom_xml, b_gradle, b_gradle_kts]:
115
+ if jf.is_file():
116
+ try:
117
+ jc += jf.read_text(encoding="utf-8", errors="replace") + "\n"
118
+ except Exception:
119
+ pass
120
+ if "spring-boot" in jc or "springframework" in jc:
121
+ framework = "Spring Boot"
122
+ elif "quarkus" in jc:
123
+ framework = "Quarkus"
124
+ elif "ktor" in jc:
125
+ framework = "Ktor"
126
+
127
+ # Check C#
128
+ csprojs = list(pkg_dir.glob("*.csproj")) + list(pkg_dir.glob("**/*.csproj"))
129
+ if csprojs or list(pkg_dir.glob("*.sln")) or list(pkg_dir.glob("*.cs")):
130
+ if language == "unknown":
131
+ language = "C#"
132
+ csc = ""
133
+ for cf in csprojs[:5]:
134
+ try:
135
+ csc += cf.read_text(encoding="utf-8", errors="replace") + "\n"
136
+ except Exception:
137
+ pass
138
+ if "Microsoft.NET.Sdk.Web" in csc or "Microsoft.AspNetCore" in csc or "Swashbuckle" in csc:
139
+ framework = "ASP.NET Core"
140
+
141
+ # Check PHP
142
+ composer_json = pkg_dir / "composer.json"
143
+ if composer_json.is_file() or list(pkg_dir.glob("*.php")):
144
+ if language == "unknown":
145
+ language = "PHP"
146
+ if composer_json.is_file():
147
+ try:
148
+ with open(composer_json, "r", encoding="utf-8") as f:
149
+ c_data = json.load(f)
150
+ reqs = {**c_data.get("require", {}), **c_data.get("require-dev", {})}
151
+ if "laravel/framework" in reqs:
152
+ framework = "Laravel"
153
+ elif any("symfony" in k for k in reqs):
154
+ framework = "Symfony"
155
+ except Exception:
156
+ pass
157
+
158
+ # Check Ruby
159
+ gemfile = pkg_dir / "Gemfile"
160
+ if gemfile.is_file() or list(pkg_dir.glob("*.rb")):
161
+ if language == "unknown":
162
+ language = "Ruby"
163
+ if gemfile.is_file():
164
+ try:
165
+ gc = gemfile.read_text(encoding="utf-8", errors="replace")
166
+ if "rails" in gc:
167
+ framework = "Ruby on Rails"
168
+ except Exception:
169
+ pass
69
170
 
70
171
  return {
71
172
  "name": name,
72
173
  "path": rel_path,
73
- "language": language,
74
- "framework": framework
174
+ "language": language.lower(),
175
+ "framework": framework.lower()
75
176
  }
76
177
 
77
178
 
@@ -102,21 +203,33 @@ def scan_workspace(root_dir: str = ".") -> Dict[str, Any]:
102
203
  pass
103
204
 
104
205
  # Scan common monorepo container directories and direct project subfolders
105
- candidate_folders = ["apps", "packages", "services", "libs", "modules"]
206
+ candidate_folders = ["apps", "packages", "services", "src", "libs", "modules"]
207
+ manifest_names = [
208
+ "package.json", "pyproject.toml", "requirements.txt", "setup.py", "Cargo.toml",
209
+ "go.mod", "pom.xml", "build.gradle", "build.gradle.kts", "composer.json",
210
+ "Gemfile", "mix.exs", "pubspec.yaml", "CMakeLists.txt", "main.py", "main.go", "actions.ts"
211
+ ]
106
212
  found_dirs = []
107
213
 
214
+ def has_manifest(d: Path) -> bool:
215
+ if any((d / m).exists() for m in manifest_names):
216
+ return True
217
+ if list(d.glob("*.csproj")) or list(d.glob("*/*.csproj")):
218
+ return True
219
+ return False
220
+
108
221
  for cf in candidate_folders:
109
222
  container = root / cf
110
223
  if container.is_dir():
111
224
  for child in container.iterdir():
112
225
  if child.is_dir() and not child.name.startswith(('.', '_')):
113
- if any((child / m).exists() for m in ["package.json", "pyproject.toml", "requirements.txt", "setup.py", "Cargo.toml", "main.py"]):
226
+ if has_manifest(child):
114
227
  found_dirs.append(child)
115
228
 
116
229
  # Also scan direct subdirectories if not already captured
117
230
  for child in root.iterdir():
118
231
  if child.is_dir() and not child.name.startswith(('.', '_')) and child.name not in candidate_folders:
119
- if any((child / m).exists() for m in ["package.json", "pyproject.toml", "requirements.txt", "setup.py", "Cargo.toml", "main.py", "actions.ts"]):
232
+ if has_manifest(child):
120
233
  if child not in found_dirs:
121
234
  found_dirs.append(child)
122
235
 
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ TorusGuard Targeted Differential Recheck Engine (v1.3.0)
4
+ Executes scoped differential re-audits verifying only impacted files and adjacent boundaries.
5
+ Evaluates formal status transitions (Confirmed Fixed vs Regressed), updates run manifest,
6
+ and records verification telemetry in the persistent security memory subsystem.
7
+
8
+ Pure Python 3.10+ standard library (zero external dependencies).
9
+ """
10
+
11
+ import sys
12
+ import os
13
+ import re
14
+ import json
15
+ import argparse
16
+ import datetime
17
+ import unicodedata
18
+ from pathlib import Path
19
+ from typing import Dict, List, Any, Optional, Tuple
20
+
21
+ # Windows console UTF-8 support
22
+ if sys.stdout and hasattr(sys.stdout, "reconfigure"):
23
+ try:
24
+ getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
25
+ except Exception:
26
+ pass
27
+
28
+ # ─── Timezone Configuration: Indian Standard Time (IST, UTC+05:30) ───────────
29
+ IST = datetime.timezone(datetime.timedelta(hours=5, minutes=30), name="IST")
30
+
31
+ def get_ist_now() -> datetime.datetime:
32
+ return datetime.datetime.now(IST)
33
+
34
+ # ─── ANSI Colors & Formatter ───────────────────────────────────────────────────
35
+ BOLD = "\033[1m"
36
+ DIM = "\033[2m"
37
+ RESET = "\033[0m"
38
+ CYAN = "\033[36m"
39
+ GREEN = "\033[32m"
40
+ YELLOW = "\033[33m"
41
+ WHITE = "\033[97m"
42
+ GRAY = "\033[90m"
43
+ RED = "\033[31m"
44
+
45
+ ANSI_REGEX = re.compile(r'\033\[[0-9;]*m')
46
+
47
+ def get_visual_width(text: str) -> int:
48
+ clean = ANSI_REGEX.sub('', text)
49
+ width = 0
50
+ for ch in clean:
51
+ ea = unicodedata.east_asian_width(ch)
52
+ if ea in ('W', 'F'):
53
+ width += 2
54
+ elif ord(ch) >= 0x1F300:
55
+ width += 2
56
+ else:
57
+ width += 1
58
+ return width
59
+
60
+ def format_box_line(content: str, width: int = 71, border: str = "│", border_color: str = CYAN) -> str:
61
+ vis = get_visual_width(content)
62
+ pad = " " * max(0, width - vis)
63
+ return f" {border_color}{border}{RESET} {content}{pad}{border_color}{border}{RESET}"
64
+
65
+
66
+ def find_latest_audit_run(runs_dir: Path) -> Optional[Path]:
67
+ if not runs_dir.is_dir():
68
+ return None
69
+ runs = sorted(runs_dir.glob("run-*-audit"), key=lambda p: p.stat().st_mtime, reverse=True)
70
+ return runs[0] if runs else None
71
+
72
+
73
+ def execute_recheck(target_root: Path, run_id_arg: Optional[str] = None) -> Dict[str, Any]:
74
+ runs_dir = target_root / ".torusguard" / "runs"
75
+ if run_id_arg:
76
+ run_folder = runs_dir / run_id_arg
77
+ else:
78
+ run_folder = find_latest_audit_run(runs_dir)
79
+
80
+ if not run_folder or not run_folder.is_dir():
81
+ print(f"\n {RED}✖ No audit run found to recheck.{RESET}\n")
82
+ sys.exit(1)
83
+
84
+ # Import audit scanner and memory engine
85
+ scripts_dir = Path(__file__).resolve().parent
86
+ if str(scripts_dir) not in sys.path:
87
+ sys.path.insert(0, str(scripts_dir))
88
+ import audit_runner
89
+ import memory_engine
90
+
91
+ bundles_dir = run_folder / "bundles"
92
+ bundle_meta_files = list(bundles_dir.glob("*/metadata.json")) if bundles_dir.is_dir() else []
93
+
94
+ # Header Card
95
+ print(f"\n {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}")
96
+ print(f" {CYAN}│ │{RESET}")
97
+ print(format_box_line(f"{BOLD}🛡️ TORUSGUARD DIFFERENTIAL RECHECK ENGINE v1.3.0{RESET}", border_color=CYAN))
98
+ print(format_box_line(f"{DIM}Targeted Differential AST Scan & Regression Verification{RESET}", border_color=CYAN))
99
+ print(f" {CYAN}│ │{RESET}")
100
+ print(f" {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}\n")
101
+
102
+ print(f" {CYAN}┌─ Recheck Verification Scope ────────────────────────────────────────────┐{RESET}")
103
+ print(format_box_line(f"Active Run: {WHITE}{run_folder.name}{RESET}"))
104
+ print(format_box_line(f"Target Root: {WHITE}{target_root}{RESET}"))
105
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
106
+
107
+ recheck_results = []
108
+ confirmed_count = 0
109
+ regressed_count = 0
110
+ unresolved_count = 0
111
+
112
+ recheck_md_lines = [
113
+ f"# TorusGuard Differential Recheck Report",
114
+ f"**Run ID:** `{run_folder.name}` ",
115
+ f"**Timestamp:** `{get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}` \n",
116
+ "---",
117
+ "## Recheck Transition Catalog\n"
118
+ ]
119
+
120
+ for mf in bundle_meta_files:
121
+ try:
122
+ bdata = json.loads(mf.read_text(encoding="utf-8"))
123
+ except Exception:
124
+ continue
125
+
126
+ rule_id = bdata.get("rule_id", "")
127
+ rel_path = bdata.get("target_file", "")
128
+ target_path = target_root / rel_path
129
+
130
+ if not target_path.is_file():
131
+ continue
132
+
133
+ # Differential scan on this single modified file
134
+ file_findings = audit_runner.scan_file(target_path, target_root)
135
+ matching_rule_findings = [f for f in file_findings if f.get("rule_id") == rule_id]
136
+
137
+ if not matching_rule_findings:
138
+ outcome = "Confirmed Fixed"
139
+ confirmed_count += 1
140
+ status_color = GREEN
141
+ # Record in memory
142
+ try:
143
+ memory_engine.record_event("fix_verified", {
144
+ "rule_id": rule_id,
145
+ "file_path": rel_path,
146
+ "verification_result": "fixed"
147
+ }, root_dir=target_root)
148
+ except Exception:
149
+ pass
150
+ else:
151
+ outcome = "Unresolved"
152
+ unresolved_count += 1
153
+ status_color = YELLOW
154
+
155
+ recheck_results.append({
156
+ "rule_id": rule_id,
157
+ "target_file": rel_path,
158
+ "outcome": outcome,
159
+ "title": bdata.get("title", rule_id)
160
+ })
161
+
162
+ recheck_md_lines.append(f"### [{rule_id}] {bdata.get('title')}")
163
+ recheck_md_lines.append(f"- **File:** `{rel_path}`")
164
+ recheck_md_lines.append(f"- **Outcome:** `{outcome}`")
165
+ recheck_md_lines.append(f"- **Verification Timestamp:** {get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}\n")
166
+
167
+ print(f" {status_color}✔ [{outcome}]{RESET} {WHITE}{rule_id}{RESET} on {rel_path}")
168
+
169
+ # Write recheck.md
170
+ (run_folder / "recheck.md").write_text("\n".join(recheck_md_lines), encoding="utf-8")
171
+
172
+ # Update manifest
173
+ manifest_file = run_folder / "manifest.json"
174
+ if manifest_file.is_file():
175
+ try:
176
+ mdata = json.loads(manifest_file.read_text(encoding="utf-8"))
177
+ mdata["status"] = "verified_fixed" if regressed_count == 0 and unresolved_count == 0 else "recheck_completed"
178
+ mdata["confirmed_fixed_count"] = confirmed_count
179
+ mdata["regressed_count"] = regressed_count
180
+ manifest_file.write_text(json.dumps(mdata, indent=2), encoding="utf-8")
181
+ except Exception:
182
+ pass
183
+
184
+ print()
185
+ print(f" {CYAN}┌─ Recheck Summary ───────────────────────────────────────────────────────┐{RESET}")
186
+ print(format_box_line(f"Confirmed Fixed:{GREEN}{confirmed_count} vulnerabilities verified closed{RESET}"))
187
+ print(format_box_line(f"Regressed: {RED if regressed_count > 0 else GREEN}{regressed_count} regressions detected{RESET}"))
188
+ print(format_box_line(f"Unresolved: {YELLOW if unresolved_count > 0 else GREEN}{unresolved_count} unresolved{RESET}"))
189
+ print(format_box_line(f"Memory Sync: {GREEN}Verification events synced to persistent memory engine{RESET}"))
190
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
191
+
192
+ print(f" {GREEN}╔═ Next Governed Action ═════════════════════════════════════════════════════╗{RESET}")
193
+ print(format_box_line(f"Visual Dashboard: {BOLD}{WHITE}npx torusguard report --html{RESET} (Updated posture score)", border="║", border_color=GREEN))
194
+ print(format_box_line(f"View Recipes: {CYAN}npx torusguard recipes{RESET} (Active golden fix recipes)", border="║", border_color=GREEN))
195
+ print(f" {GREEN}╚═════════════════════════════════════════════════════════════════════════════╝{RESET}\n")
196
+
197
+ return {
198
+ "run_folder": str(run_folder),
199
+ "confirmed_fixed_count": confirmed_count,
200
+ "regressed_count": regressed_count,
201
+ "unresolved_count": unresolved_count,
202
+ "results": recheck_results
203
+ }
204
+
205
+
206
+ def main():
207
+ parser = argparse.ArgumentParser(description="TorusGuard Differential Recheck Engine")
208
+ parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
209
+ parser.add_argument("--run", "-r", help="Explicit run ID to recheck")
210
+ parser.add_argument("--json", action="store_true", help="Output raw JSON")
211
+ args = parser.parse_args()
212
+
213
+ target = Path(args.path).resolve()
214
+ result = execute_recheck(target, run_id_arg=args.run)
215
+
216
+ if args.json:
217
+ print(json.dumps(result, indent=2))
218
+
219
+
220
+ if __name__ == "__main__":
221
+ main()
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ TorusGuard Golden Fix Recipe Explorer (v1.3.0)
4
+ Inspect, list, and export reusable, verified AST remediation code snippets
5
+ distilled from passing security patches and persistent memory patterns.
6
+
7
+ Pure Python 3.10+ standard library (zero external dependencies).
8
+ """
9
+
10
+ import sys
11
+ import json
12
+ import argparse
13
+ import unicodedata
14
+ import re
15
+ from pathlib import Path
16
+ from typing import Dict, List, Any, Optional
17
+
18
+ # Windows console UTF-8 support
19
+ if sys.stdout and hasattr(sys.stdout, "reconfigure"):
20
+ try:
21
+ getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
22
+ except Exception:
23
+ pass
24
+
25
+ # ─── ANSI Colors & Formatter ───────────────────────────────────────────────────
26
+ BOLD = "\033[1m"
27
+ DIM = "\033[2m"
28
+ RESET = "\033[0m"
29
+ CYAN = "\033[36m"
30
+ GREEN = "\033[32m"
31
+ YELLOW = "\033[33m"
32
+ WHITE = "\033[97m"
33
+ GRAY = "\033[90m"
34
+ RED = "\033[31m"
35
+
36
+ ANSI_REGEX = re.compile(r'\033\[[0-9;]*m')
37
+
38
+ def get_visual_width(text: str) -> int:
39
+ clean = ANSI_REGEX.sub('', text)
40
+ width = 0
41
+ for ch in clean:
42
+ ea = unicodedata.east_asian_width(ch)
43
+ if ea in ('W', 'F'):
44
+ width += 2
45
+ elif ord(ch) >= 0x1F300:
46
+ width += 2
47
+ else:
48
+ width += 1
49
+ return width
50
+
51
+ def format_box_line(content: str, width: int = 71, border: str = "│", border_color: str = CYAN) -> str:
52
+ vis = get_visual_width(content)
53
+ pad = " " * max(0, width - vis)
54
+ return f" {border_color}{border}{RESET} {content}{pad}{border_color}{border}{RESET}"
55
+
56
+
57
+ def list_recipes(target_root: Path, detail_id: Optional[str] = None, json_output: bool = False) -> None:
58
+ patterns_file = target_root / ".torusguard" / "memory" / "patterns.json"
59
+ recipes: List[Dict[str, Any]] = []
60
+
61
+ if patterns_file.is_file():
62
+ try:
63
+ patterns = json.loads(patterns_file.read_text(encoding="utf-8"))
64
+ recipes = [p for p in patterns if p.get("pattern_type") == "golden_fix_recipe"]
65
+ except Exception:
66
+ recipes = []
67
+
68
+ if json_output:
69
+ print(json.dumps(recipes, indent=2))
70
+ return
71
+
72
+ # Header Card
73
+ print(f"\n {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}")
74
+ print(f" {CYAN}│ │{RESET}")
75
+ print(format_box_line(f"{BOLD}🛡️ TORUSGUARD GOLDEN FIX RECIPES v1.3.0{RESET}", border_color=CYAN))
76
+ print(format_box_line(f"{DIM}Distilled Ponytail Fixes (<= 35 add, <= 25 del) in Persistent Memory{RESET}", border_color=CYAN))
77
+ print(f" {CYAN}│ │{RESET}")
78
+ print(f" {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}\n")
79
+
80
+ if not recipes:
81
+ print(f" {YELLOW}ℹ No golden fix recipes captured yet.{RESET}")
82
+ print(f" Run {CYAN}npx torusguard harden{RESET} followed by {CYAN}npx torusguard apply{RESET} to distill verified recipes.\n")
83
+ return
84
+
85
+ print(f" {CYAN}┌─ Active Distilled Recipes ({len(recipes)}) ─────────────────────────────────────┐{RESET}")
86
+ for idx, r in enumerate(recipes, 1):
87
+ rule_id = r.get("rule_id", "TG-SEC")
88
+ rec_id = r.get("recipe_id", f"recipe-{idx}")
89
+ desc = r.get("description", "Verified fix")
90
+ rdata = r.get("recipe_data", {})
91
+ metrics = rdata.get("ponytail_metrics", {})
92
+ verified = rdata.get("verified_count", 1)
93
+ adds = metrics.get("additions", 0)
94
+ dels = metrics.get("deletions", 0)
95
+
96
+ print(format_box_line(f"{GREEN}[{rule_id}]{RESET} {WHITE}{rec_id}{RESET} (Verified {verified}x · +{adds}/-{dels} Ponytail)"))
97
+ print(format_box_line(f" └─ {DIM}{desc}{RESET}"))
98
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
99
+
100
+ if detail_id:
101
+ target_rec = next((r for r in recipes if r.get("recipe_id") == detail_id), None)
102
+ if target_rec:
103
+ rdata = target_rec.get("recipe_data", {})
104
+ print(f" {BOLD}Recipe Details: {detail_id}{RESET}")
105
+ print(f" {DIM}Rule ID:{RESET} {target_rec.get('rule_id')}")
106
+ print(f" {DIM}Diff Snippet:{RESET}")
107
+ print(" ```diff")
108
+ for line in rdata.get("diff_snippet", "").splitlines():
109
+ if line.startswith("+"):
110
+ print(f" {GREEN}{line}{RESET}")
111
+ elif line.startswith("-"):
112
+ print(f" {RED}{line}{RESET}")
113
+ else:
114
+ print(f" {DIM}{line}{RESET}")
115
+ print(" ```\n")
116
+
117
+
118
+ def main():
119
+ parser = argparse.ArgumentParser(description="TorusGuard Golden Fix Recipe Explorer")
120
+ parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
121
+ parser.add_argument("--detail", "-d", help="Inspect specific recipe ID")
122
+ parser.add_argument("--json", action="store_true", help="Output raw JSON")
123
+ args = parser.parse_args()
124
+
125
+ target = Path(args.path).resolve()
126
+ list_recipes(target, detail_id=args.detail, json_output=args.json)
127
+
128
+
129
+ if __name__ == "__main__":
130
+ main()