codejury 0.11.0__tar.gz → 0.12.0__tar.gz

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 (294) hide show
  1. codejury-0.12.0/PKG-INFO +102 -0
  2. codejury-0.12.0/README.md +72 -0
  3. codejury-0.12.0/codejury/__init__.py +14 -0
  4. {codejury-0.11.0 → codejury-0.12.0}/codejury/analysis/repo_model.py +23 -5
  5. codejury-0.12.0/codejury/cli.py +142 -0
  6. codejury-0.12.0/codejury/data/agent/full-review.md +102 -0
  7. codejury-0.12.0/codejury/data/agent/security-review-memory.md +30 -0
  8. codejury-0.12.0/codejury/data/rules/SKILL.md +41 -0
  9. codejury-0.12.0/codejury/data/rules/authentication-jwt.md +21 -0
  10. codejury-0.12.0/codejury/data/rules/broken-access-control.md +27 -0
  11. codejury-0.12.0/codejury/data/rules/command-injection.md +25 -0
  12. codejury-0.12.0/codejury/data/rules/idor.md +24 -0
  13. codejury-0.12.0/codejury/data/rules/insecure-crypto.md +22 -0
  14. codejury-0.12.0/codejury/data/rules/insecure-deserialization.md +22 -0
  15. codejury-0.12.0/codejury/data/rules/mass-assignment.md +21 -0
  16. codejury-0.12.0/codejury/data/rules/path-traversal.md +22 -0
  17. codejury-0.12.0/codejury/data/rules/secrets.md +20 -0
  18. codejury-0.12.0/codejury/data/rules/sql-injection.md +25 -0
  19. codejury-0.12.0/codejury/data/rules/ssrf.md +22 -0
  20. codejury-0.12.0/codejury/data/rules/xss.md +24 -0
  21. codejury-0.12.0/codejury/diff/__init__.py +0 -0
  22. codejury-0.12.0/codejury/diff/debate.py +104 -0
  23. codejury-0.12.0/codejury/diff/debate_prompts.py +102 -0
  24. codejury-0.12.0/codejury/diff/engine.py +33 -0
  25. codejury-0.12.0/codejury/diff/findings_filter.py +39 -0
  26. codejury-0.12.0/codejury/diff/prompts.py +65 -0
  27. codejury-0.12.0/codejury/diff/report.py +120 -0
  28. codejury-0.12.0/codejury/diff/rules.py +71 -0
  29. codejury-0.12.0/codejury/domain/finding.py +70 -0
  30. codejury-0.12.0/codejury/fullreview/__init__.py +0 -0
  31. codejury-0.12.0/codejury/fullreview/scaffold.py +77 -0
  32. codejury-0.12.0/codejury/providers/factory.py +30 -0
  33. codejury-0.12.0/codejury/resources.py +13 -0
  34. codejury-0.12.0/codejury.egg-info/PKG-INFO +102 -0
  35. codejury-0.12.0/codejury.egg-info/SOURCES.txt +65 -0
  36. {codejury-0.11.0 → codejury-0.12.0}/pyproject.toml +2 -2
  37. codejury-0.12.0/tests/test_diff_debate.py +105 -0
  38. codejury-0.12.0/tests/test_diff_engine.py +95 -0
  39. codejury-0.12.0/tests/test_diff_report.py +66 -0
  40. codejury-0.12.0/tests/test_full_review_scaffold.py +74 -0
  41. codejury-0.12.0/tests/test_rules.py +58 -0
  42. codejury-0.11.0/PKG-INFO +0 -241
  43. codejury-0.11.0/README.md +0 -211
  44. codejury-0.11.0/codejury/__init__.py +0 -14
  45. codejury-0.11.0/codejury/agents/__init__.py +0 -6
  46. codejury-0.11.0/codejury/agents/base.py +0 -21
  47. codejury-0.11.0/codejury/agents/debate.py +0 -206
  48. codejury-0.11.0/codejury/agents/mock.py +0 -37
  49. codejury-0.11.0/codejury/agents/parsing.py +0 -45
  50. codejury-0.11.0/codejury/agents/refuter.py +0 -76
  51. codejury-0.11.0/codejury/agents/skill_runner.py +0 -121
  52. codejury-0.11.0/codejury/analysis/attack_path.py +0 -110
  53. codejury-0.11.0/codejury/analysis/provenance.py +0 -253
  54. codejury-0.11.0/codejury/analysis/taint.py +0 -303
  55. codejury-0.11.0/codejury/assembly.py +0 -144
  56. codejury-0.11.0/codejury/baseline.py +0 -58
  57. codejury-0.11.0/codejury/cli.py +0 -533
  58. codejury-0.11.0/codejury/data/golden/ag_allowlist_safe.yaml +0 -16
  59. codejury-0.11.0/codejury/data/golden/ag_arbitrary_tool_vuln.yaml +0 -14
  60. codejury-0.11.0/codejury/data/golden/ag_destructive_no_confirm_vuln.yaml +0 -14
  61. codejury-0.11.0/codejury/data/golden/ag_fixed_enum_safe.yaml +0 -19
  62. codejury-0.11.0/codejury/data/golden/ag_human_approval_safe.yaml +0 -13
  63. codejury-0.11.0/codejury/data/golden/ag_model_confirmed_vuln.yaml +0 -16
  64. codejury-0.11.0/codejury/data/golden/api_design_authz_inconsistent_vuln.yaml +0 -23
  65. codejury-0.11.0/codejury/data/golden/api_design_authz_uniform_safe.yaml +0 -22
  66. codejury-0.11.0/codejury/data/golden/api_design_cors_allowlist_safe.yaml +0 -23
  67. codejury-0.11.0/codejury/data/golden/api_design_cors_reflect_origin_vuln.yaml +0 -20
  68. codejury-0.11.0/codejury/data/golden/api_design_cors_wildcard_credentials_vuln.yaml +0 -23
  69. codejury-0.11.0/codejury/data/golden/api_design_mass_assignment_allowlist_safe.yaml +0 -22
  70. codejury-0.11.0/codejury/data/golden/api_design_mass_assignment_vuln.yaml +0 -21
  71. codejury-0.11.0/codejury/data/golden/api_design_single_missing_auth_not_ours_safe.yaml +0 -18
  72. codejury-0.11.0/codejury/data/golden/architecture_clean_surface_safe.yaml +0 -19
  73. codejury-0.11.0/codejury/data/golden/architecture_debug_route_exposed_vuln.yaml +0 -21
  74. codejury-0.11.0/codejury/data/golden/architecture_internal_route_exposed_vuln.yaml +0 -18
  75. codejury-0.11.0/codejury/data/golden/architecture_legit_admin_route_safe.yaml +0 -19
  76. codejury-0.11.0/codejury/data/golden/architecture_minimal_surface_safe.yaml +0 -18
  77. codejury-0.11.0/codejury/data/golden/architecture_test_echo_route_vuln.yaml +0 -17
  78. codejury-0.11.0/codejury/data/golden/authn_bcrypt_password.yaml +0 -5
  79. codejury-0.11.0/codejury/data/golden/authn_jwt_noverify_vuln.yaml +0 -6
  80. codejury-0.11.0/codejury/data/golden/authn_jwt_verified_safe.yaml +0 -6
  81. codejury-0.11.0/codejury/data/golden/authn_sha256_checksum_safe.yaml +0 -6
  82. codejury-0.11.0/codejury/data/golden/authn_sha256_password.yaml +0 -6
  83. codejury-0.11.0/codejury/data/golden/authn_weak_hash_indirect_vuln.yaml +0 -14
  84. codejury-0.11.0/codejury/data/golden/authz_idor_vuln.yaml +0 -6
  85. codejury-0.11.0/codejury/data/golden/authz_owner_safe.yaml +0 -5
  86. codejury-0.11.0/codejury/data/golden/business_logic_atomic_safe.yaml +0 -15
  87. codejury-0.11.0/codejury/data/golden/business_logic_price_tamper_vuln.yaml +0 -14
  88. codejury-0.11.0/codejury/data/golden/business_logic_server_checked_safe.yaml +0 -15
  89. codejury-0.11.0/codejury/data/golden/business_logic_toctou_vuln.yaml +0 -14
  90. codejury-0.11.0/codejury/data/golden/cmdi_fixed_argv_safe.yaml +0 -22
  91. codejury-0.11.0/codejury/data/golden/cmdi_ossystem_vuln.yaml +0 -5
  92. codejury-0.11.0/codejury/data/golden/cmdi_subprocess_safe.yaml +0 -5
  93. codejury-0.11.0/codejury/data/golden/crypto_aesgcm_nonce_safe.yaml +0 -13
  94. codejury-0.11.0/codejury/data/golden/crypto_aesgcm_safe.yaml +0 -6
  95. codejury-0.11.0/codejury/data/golden/crypto_ecb_vuln.yaml +0 -6
  96. codejury-0.11.0/codejury/data/golden/crypto_static_iv_vuln.yaml +0 -14
  97. codejury-0.11.0/codejury/data/golden/data_protection_cleartext_http_vuln.yaml +0 -11
  98. codejury-0.11.0/codejury/data/golden/data_protection_encrypted_at_rest_safe.yaml +0 -11
  99. codejury-0.11.0/codejury/data/golden/data_protection_plaintext_pii_vuln.yaml +0 -14
  100. codejury-0.11.0/codejury/data/golden/data_protection_tokenized_safe.yaml +0 -16
  101. codejury-0.11.0/codejury/data/golden/dependency_config_debug_off_safe.yaml +0 -12
  102. codejury-0.11.0/codejury/data/golden/dependency_config_debug_true_vuln.yaml +0 -11
  103. codejury-0.11.0/codejury/data/golden/dependency_config_tls_verify_off_vuln.yaml +0 -11
  104. codejury-0.11.0/codejury/data/golden/dependency_config_tls_verify_on_safe.yaml +0 -11
  105. codejury-0.11.0/codejury/data/golden/deserialize_json_safe.yaml +0 -13
  106. codejury-0.11.0/codejury/data/golden/deserialize_pickle_vuln.yaml +0 -12
  107. codejury-0.11.0/codejury/data/golden/error_logging_redacted_safe.yaml +0 -11
  108. codejury-0.11.0/codejury/data/golden/error_logging_reraise_safe.yaml +0 -15
  109. codejury-0.11.0/codejury/data/golden/error_logging_secret_leak_vuln.yaml +0 -12
  110. codejury-0.11.0/codejury/data/golden/error_logging_swallow_vuln.yaml +0 -14
  111. codejury-0.11.0/codejury/data/golden/ioh_escaped_output_safe.yaml +0 -12
  112. codejury-0.11.0/codejury/data/golden/ioh_exec_output_vuln.yaml +0 -13
  113. codejury-0.11.0/codejury/data/golden/ioh_innerhtml_output_vuln.yaml +0 -13
  114. codejury-0.11.0/codejury/data/golden/ioh_json_response_safe.yaml +0 -15
  115. codejury-0.11.0/codejury/data/golden/ioh_output_to_sql_vuln.yaml +0 -15
  116. codejury-0.11.0/codejury/data/golden/ioh_schema_validated_safe.yaml +0 -13
  117. codejury-0.11.0/codejury/data/golden/literal_eval_safe.yaml +0 -14
  118. codejury-0.11.0/codejury/data/golden/output_encoding_header_injection_vuln.yaml +0 -11
  119. codejury-0.11.0/codejury/data/golden/path_basename_safe.yaml +0 -15
  120. codejury-0.11.0/codejury/data/golden/path_contained_safe.yaml +0 -8
  121. codejury-0.11.0/codejury/data/golden/path_traversal_vuln.yaml +0 -5
  122. codejury-0.11.0/codejury/data/golden/pi_delimited_data_safe.yaml +0 -15
  123. codejury-0.11.0/codejury/data/golden/pi_format_role_vuln.yaml +0 -16
  124. codejury-0.11.0/codejury/data/golden/pi_indirect_rag_vuln.yaml +0 -16
  125. codejury-0.11.0/codejury/data/golden/pi_system_concat_vuln.yaml +0 -13
  126. codejury-0.11.0/codejury/data/golden/pi_user_content_concat_safe.yaml +0 -18
  127. codejury-0.11.0/codejury/data/golden/pi_user_role_safe.yaml +0 -14
  128. codejury-0.11.0/codejury/data/golden/sc_pinned_safe.yaml +0 -11
  129. codejury-0.11.0/codejury/data/golden/sc_safetensors_safe.yaml +0 -12
  130. codejury-0.11.0/codejury/data/golden/sc_torch_load_vuln.yaml +0 -11
  131. codejury-0.11.0/codejury/data/golden/sc_trust_remote_code_vuln.yaml +0 -12
  132. codejury-0.11.0/codejury/data/golden/secrets_env_safe.yaml +0 -5
  133. codejury-0.11.0/codejury/data/golden/secrets_from_config_safe.yaml +0 -12
  134. codejury-0.11.0/codejury/data/golden/secrets_hardcoded_token_vuln.yaml +0 -13
  135. codejury-0.11.0/codejury/data/golden/secrets_hardcoded_vuln.yaml +0 -5
  136. codejury-0.11.0/codejury/data/golden/session_cookie_flags_safe.yaml +0 -10
  137. codejury-0.11.0/codejury/data/golden/session_fixation_vuln.yaml +0 -16
  138. codejury-0.11.0/codejury/data/golden/session_insecure_cookie_vuln.yaml +0 -11
  139. codejury-0.11.0/codejury/data/golden/session_secure_cookie_safe.yaml +0 -18
  140. codejury-0.11.0/codejury/data/golden/sql_constant_concat_safe.yaml +0 -14
  141. codejury-0.11.0/codejury/data/golden/sqli_format_vuln.yaml +0 -5
  142. codejury-0.11.0/codejury/data/golden/sqli_fstring_query.yaml +0 -5
  143. codejury-0.11.0/codejury/data/golden/sqli_indirect_var_vuln.yaml +0 -16
  144. codejury-0.11.0/codejury/data/golden/sqli_parameterized_query.yaml +0 -5
  145. codejury-0.11.0/codejury/data/golden/ssrf_allowlist_safe.yaml +0 -17
  146. codejury-0.11.0/codejury/data/golden/ssrf_constant_url_safe.yaml +0 -13
  147. codejury-0.11.0/codejury/data/golden/ssrf_substring_allowlist_bypass_vuln.yaml +0 -17
  148. codejury-0.11.0/codejury/data/golden/ssrf_user_url_vuln.yaml +0 -12
  149. codejury-0.11.0/codejury/data/golden/xfile_idor_no_check_vuln.yaml +0 -20
  150. codejury-0.11.0/codejury/data/golden/xfile_idor_owner_checked_safe.yaml +0 -21
  151. codejury-0.11.0/codejury/data/golden/xfile_path_sanitized_safe.yaml +0 -22
  152. codejury-0.11.0/codejury/data/golden/xfile_path_tainted_vuln.yaml +0 -19
  153. codejury-0.11.0/codejury/data/golden/xss_innerhtml_constant_safe.yaml +0 -7
  154. codejury-0.11.0/codejury/data/golden/xss_innerhtml_vuln.yaml +0 -7
  155. codejury-0.11.0/codejury/data/golden/xss_textcontent_safe.yaml +0 -15
  156. codejury-0.11.0/codejury/data/poc/cmdi.yaml +0 -14
  157. codejury-0.11.0/codejury/data/poc/path.yaml +0 -12
  158. codejury-0.11.0/codejury/data/poc/sqli.yaml +0 -14
  159. codejury-0.11.0/codejury/data/poc/ssrf.yaml +0 -15
  160. codejury-0.11.0/codejury/data/skills/api_design/SKILL.md +0 -116
  161. codejury-0.11.0/codejury/data/skills/api_design/skill.yaml +0 -8
  162. codejury-0.11.0/codejury/data/skills/architecture/SKILL.md +0 -52
  163. codejury-0.11.0/codejury/data/skills/architecture/skill.yaml +0 -8
  164. codejury-0.11.0/codejury/data/skills/authn/SKILL.md +0 -59
  165. codejury-0.11.0/codejury/data/skills/authn/skill.yaml +0 -11
  166. codejury-0.11.0/codejury/data/skills/authz/SKILL.md +0 -46
  167. codejury-0.11.0/codejury/data/skills/authz/skill.yaml +0 -11
  168. codejury-0.11.0/codejury/data/skills/business_logic/SKILL.md +0 -50
  169. codejury-0.11.0/codejury/data/skills/business_logic/skill.yaml +0 -11
  170. codejury-0.11.0/codejury/data/skills/crypto/SKILL.md +0 -55
  171. codejury-0.11.0/codejury/data/skills/crypto/skill.yaml +0 -12
  172. codejury-0.11.0/codejury/data/skills/data_protection/SKILL.md +0 -50
  173. codejury-0.11.0/codejury/data/skills/data_protection/skill.yaml +0 -11
  174. codejury-0.11.0/codejury/data/skills/dependency_config/SKILL.md +0 -55
  175. codejury-0.11.0/codejury/data/skills/dependency_config/skill.yaml +0 -11
  176. codejury-0.11.0/codejury/data/skills/error_logging/SKILL.md +0 -45
  177. codejury-0.11.0/codejury/data/skills/error_logging/skill.yaml +0 -11
  178. codejury-0.11.0/codejury/data/skills/excessive_agency/SKILL.md +0 -58
  179. codejury-0.11.0/codejury/data/skills/excessive_agency/skill.yaml +0 -11
  180. codejury-0.11.0/codejury/data/skills/input_validation/SKILL.md +0 -128
  181. codejury-0.11.0/codejury/data/skills/input_validation/skill.yaml +0 -13
  182. codejury-0.11.0/codejury/data/skills/insecure_output_handling/SKILL.md +0 -62
  183. codejury-0.11.0/codejury/data/skills/insecure_output_handling/skill.yaml +0 -11
  184. codejury-0.11.0/codejury/data/skills/model_supply_chain/SKILL.md +0 -57
  185. codejury-0.11.0/codejury/data/skills/model_supply_chain/skill.yaml +0 -11
  186. codejury-0.11.0/codejury/data/skills/output_encoding/SKILL.md +0 -45
  187. codejury-0.11.0/codejury/data/skills/output_encoding/skill.yaml +0 -11
  188. codejury-0.11.0/codejury/data/skills/prompt_injection/SKILL.md +0 -62
  189. codejury-0.11.0/codejury/data/skills/prompt_injection/skill.yaml +0 -10
  190. codejury-0.11.0/codejury/data/skills/secrets/SKILL.md +0 -48
  191. codejury-0.11.0/codejury/data/skills/secrets/skill.yaml +0 -10
  192. codejury-0.11.0/codejury/data/skills/session/SKILL.md +0 -47
  193. codejury-0.11.0/codejury/data/skills/session/skill.yaml +0 -11
  194. codejury-0.11.0/codejury/data/suppressions.yaml +0 -43
  195. codejury-0.11.0/codejury/data/taint.yaml +0 -109
  196. codejury-0.11.0/codejury/data/tasks/audit_diff_debate.yaml +0 -4
  197. codejury-0.11.0/codejury/data/tasks/quick_scan_single.yaml +0 -4
  198. codejury-0.11.0/codejury/domain/artifact.py +0 -23
  199. codejury-0.11.0/codejury/domain/context.py +0 -26
  200. codejury-0.11.0/codejury/domain/observation.py +0 -170
  201. codejury-0.11.0/codejury/domain/result.py +0 -33
  202. codejury-0.11.0/codejury/domain/skill.py +0 -117
  203. codejury-0.11.0/codejury/evaluation.py +0 -183
  204. codejury-0.11.0/codejury/infrastructure/cache.py +0 -101
  205. codejury-0.11.0/codejury/integrations/__init__.py +0 -1
  206. codejury-0.11.0/codejury/integrations/github.py +0 -103
  207. codejury-0.11.0/codejury/orchestrators/__init__.py +0 -6
  208. codejury-0.11.0/codejury/orchestrators/adaptive.py +0 -55
  209. codejury-0.11.0/codejury/orchestrators/base.py +0 -27
  210. codejury-0.11.0/codejury/orchestrators/challenge.py +0 -84
  211. codejury-0.11.0/codejury/orchestrators/debate.py +0 -57
  212. codejury-0.11.0/codejury/orchestrators/reflexion.py +0 -58
  213. codejury-0.11.0/codejury/orchestrators/single.py +0 -24
  214. codejury-0.11.0/codejury/orchestrators/skill_pipeline.py +0 -32
  215. codejury-0.11.0/codejury/orchestrators/taint_gate.py +0 -75
  216. codejury-0.11.0/codejury/reporting.py +0 -265
  217. codejury-0.11.0/codejury/resources.py +0 -17
  218. codejury-0.11.0/codejury/sandbox.py +0 -363
  219. codejury-0.11.0/codejury/selection.py +0 -145
  220. codejury-0.11.0/codejury/sources/__init__.py +0 -6
  221. codejury-0.11.0/codejury/sources/api_surface.py +0 -101
  222. codejury-0.11.0/codejury/sources/base.py +0 -17
  223. codejury-0.11.0/codejury/sources/callers.py +0 -106
  224. codejury-0.11.0/codejury/sources/chunker.py +0 -36
  225. codejury-0.11.0/codejury/sources/diff.py +0 -70
  226. codejury-0.11.0/codejury/sources/function.py +0 -44
  227. codejury-0.11.0/codejury/sources/mock.py +0 -25
  228. codejury-0.11.0/codejury/sources/repo.py +0 -79
  229. codejury-0.11.0/codejury/suppression.py +0 -94
  230. codejury-0.11.0/codejury/tasks/__init__.py +0 -6
  231. codejury-0.11.0/codejury/tasks/base.py +0 -82
  232. codejury-0.11.0/codejury/tasks/registry.py +0 -22
  233. codejury-0.11.0/codejury.egg-info/PKG-INFO +0 -241
  234. codejury-0.11.0/codejury.egg-info/SOURCES.txt +0 -253
  235. codejury-0.11.0/tests/test_adaptive.py +0 -73
  236. codejury-0.11.0/tests/test_api_surface.py +0 -106
  237. codejury-0.11.0/tests/test_assembly.py +0 -74
  238. codejury-0.11.0/tests/test_attack_path.py +0 -141
  239. codejury-0.11.0/tests/test_baseline.py +0 -63
  240. codejury-0.11.0/tests/test_cache.py +0 -120
  241. codejury-0.11.0/tests/test_callers.py +0 -69
  242. codejury-0.11.0/tests/test_challenge.py +0 -105
  243. codejury-0.11.0/tests/test_cli_audit.py +0 -116
  244. codejury-0.11.0/tests/test_context.py +0 -30
  245. codejury-0.11.0/tests/test_debate_agents.py +0 -87
  246. codejury-0.11.0/tests/test_debate_orchestrator.py +0 -77
  247. codejury-0.11.0/tests/test_diff_source.py +0 -63
  248. codejury-0.11.0/tests/test_evaluation.py +0 -181
  249. codejury-0.11.0/tests/test_full_review.py +0 -111
  250. codejury-0.11.0/tests/test_function_source.py +0 -49
  251. codejury-0.11.0/tests/test_integrations.py +0 -82
  252. codejury-0.11.0/tests/test_orchestrator.py +0 -39
  253. codejury-0.11.0/tests/test_parsing.py +0 -32
  254. codejury-0.11.0/tests/test_provenance.py +0 -105
  255. codejury-0.11.0/tests/test_reflexion_orchestrator.py +0 -67
  256. codejury-0.11.0/tests/test_repo_source.py +0 -38
  257. codejury-0.11.0/tests/test_reporting.py +0 -52
  258. codejury-0.11.0/tests/test_review_fixes.py +0 -114
  259. codejury-0.11.0/tests/test_sandbox.py +0 -195
  260. codejury-0.11.0/tests/test_sarif.py +0 -115
  261. codejury-0.11.0/tests/test_selection.py +0 -109
  262. codejury-0.11.0/tests/test_skill.py +0 -140
  263. codejury-0.11.0/tests/test_skill_runner.py +0 -113
  264. codejury-0.11.0/tests/test_suppression.py +0 -44
  265. codejury-0.11.0/tests/test_taint.py +0 -135
  266. codejury-0.11.0/tests/test_taint_crossfile.py +0 -78
  267. codejury-0.11.0/tests/test_taint_gate.py +0 -107
  268. codejury-0.11.0/tests/test_tasks.py +0 -74
  269. {codejury-0.11.0 → codejury-0.12.0}/LICENSE +0 -0
  270. {codejury-0.11.0 → codejury-0.12.0}/codejury/analysis/__init__.py +0 -0
  271. {codejury-0.11.0 → codejury-0.12.0}/codejury/data/entrypoints.yaml +0 -0
  272. {codejury-0.11.0 → codejury-0.12.0}/codejury/domain/__init__.py +0 -0
  273. {codejury-0.11.0 → codejury-0.12.0}/codejury/infrastructure/__init__.py +0 -0
  274. {codejury-0.11.0 → codejury-0.12.0}/codejury/infrastructure/json_parse.py +0 -0
  275. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/__init__.py +0 -0
  276. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/anthropic.py +0 -0
  277. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/base.py +0 -0
  278. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/litellm.py +0 -0
  279. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/mock.py +0 -0
  280. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/openai.py +0 -0
  281. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/openai_format.py +0 -0
  282. {codejury-0.11.0 → codejury-0.12.0}/codejury/providers/retry.py +0 -0
  283. {codejury-0.11.0 → codejury-0.12.0}/codejury.egg-info/dependency_links.txt +0 -0
  284. {codejury-0.11.0 → codejury-0.12.0}/codejury.egg-info/entry_points.txt +0 -0
  285. {codejury-0.11.0 → codejury-0.12.0}/codejury.egg-info/requires.txt +0 -0
  286. {codejury-0.11.0 → codejury-0.12.0}/codejury.egg-info/top_level.txt +0 -0
  287. {codejury-0.11.0 → codejury-0.12.0}/setup.cfg +0 -0
  288. {codejury-0.11.0 → codejury-0.12.0}/tests/test_anthropic_provider.py +0 -0
  289. {codejury-0.11.0 → codejury-0.12.0}/tests/test_json_parse.py +0 -0
  290. {codejury-0.11.0 → codejury-0.12.0}/tests/test_litellm_provider.py +0 -0
  291. {codejury-0.11.0 → codejury-0.12.0}/tests/test_openai_format.py +0 -0
  292. {codejury-0.11.0 → codejury-0.12.0}/tests/test_openai_provider.py +0 -0
  293. {codejury-0.11.0 → codejury-0.12.0}/tests/test_repo_model.py +0 -0
  294. {codejury-0.11.0 → codejury-0.12.0}/tests/test_retry_provider.py +0 -0
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: codejury
3
+ Version: 0.12.0
4
+ Summary: AI code security review: an adversarial diff-audit engine and an agent-driven whole-repo review methodology, with security knowledge as rich rules
5
+ Author: AISecLabs
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/aiseclabs/codejury
8
+ Project-URL: Repository, https://github.com/aiseclabs/codejury
9
+ Keywords: security,appsec,static analysis,llm,owasp,asvs,code review
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Security
13
+ Classifier: Topic :: Software Development :: Quality Assurance
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.12
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: pyyaml>=6.0
20
+ Provides-Extra: anthropic
21
+ Requires-Dist: anthropic>=0.40; extra == "anthropic"
22
+ Provides-Extra: openai
23
+ Requires-Dist: openai>=1.0; extra == "openai"
24
+ Provides-Extra: litellm
25
+ Requires-Dist: litellm>=1.0; extra == "litellm"
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0; extra == "dev"
28
+ Requires-Dist: jsonschema>=4.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # codejury
32
+
33
+ AI code security review, in two paths matched to their nature:
34
+
35
+ - **Diff review** (coded): audit a pull request's diff for newly introduced,
36
+ exploitable risks. A single balanced LLM call, or an adversarial
37
+ Finder/Challenger/Judge pass for higher coverage and fewer false positives.
38
+ - **Whole-repo review** (agent-driven): a methodology an interactive agent
39
+ (Claude Code, Codex) runs to traverse a codebase from its API entrypoints,
40
+ verify issues with a real PoC, and iterate over rounds with a persistent
41
+ memory. Too large for a single LLM call, so codejury ships the methodology and
42
+ scaffolds the workspace rather than running a pipeline.
43
+
44
+ Security knowledge lives in **rich rules** (`codejury/data/rules/*.md`, with
45
+ per-language vulnerable/secure examples), injected into the audit prompt, not
46
+ buried in code.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install codejury # core
52
+ pip install "codejury[anthropic]" # or [openai] / [litellm] for a backend
53
+ ```
54
+
55
+ ## Diff review
56
+
57
+ ```bash
58
+ # audit a diff file
59
+ codejury audit --diff-file changes.diff
60
+
61
+ # audit a git range in a repo
62
+ codejury audit --repo /path/to/app --git-range origin/main...HEAD
63
+
64
+ # from stdin
65
+ git diff HEAD~1 | codejury audit
66
+
67
+ # adversarial mode: Finder + Challenger + Judge (higher coverage, lower FP, ~3x cost)
68
+ codejury audit --diff-file changes.diff --mode adversarial
69
+
70
+ # CI gate + SARIF
71
+ codejury audit --diff-file changes.diff --format sarif --fail-on high
72
+ ```
73
+
74
+ Configure a backend with `--provider`/`--model`/`--api-key`/`--api-base` or the
75
+ `CODEJURY_API_KEY` / `CODEJURY_MODEL` / `CODEJURY_API_BASE` environment variables.
76
+ `codejury dry-run` exercises the engine with a mock provider and no key.
77
+
78
+ ## Whole-repo review
79
+
80
+ ```bash
81
+ codejury full-review /path/to/your/repo
82
+ ```
83
+
84
+ This scaffolds a review workspace (`api/`, `issues/`, `analysis/`, and a
85
+ `security-review-memory.md`), seeds the API inventory from a deterministic scan,
86
+ and prints the methodology. Run it with an interactive agent: it reads the
87
+ methodology and the rules, traverses the code from its API entrypoints, records
88
+ high-confidence issues with a PoC, and asks you to confirm credentials or false
89
+ positives along the way. Nothing runs against production.
90
+
91
+ ## Findings
92
+
93
+ Each finding carries a file and line, a severity and category, a concrete
94
+ exploit scenario, a recommendation, and a confidence. A false-positive filter
95
+ drops test/mock-path and low-confidence noise; the model is also told not to
96
+ report dependency CVEs, style notes, speculation, or config-leak-only risks.
97
+
98
+ ## Extending
99
+
100
+ Add a vulnerability class by dropping a new `codejury/data/rules/<class>.md` with
101
+ the standard frontmatter (title, impact, tags, triggers) and vulnerable/secure
102
+ examples. It is data; no code change needed.
@@ -0,0 +1,72 @@
1
+ # codejury
2
+
3
+ AI code security review, in two paths matched to their nature:
4
+
5
+ - **Diff review** (coded): audit a pull request's diff for newly introduced,
6
+ exploitable risks. A single balanced LLM call, or an adversarial
7
+ Finder/Challenger/Judge pass for higher coverage and fewer false positives.
8
+ - **Whole-repo review** (agent-driven): a methodology an interactive agent
9
+ (Claude Code, Codex) runs to traverse a codebase from its API entrypoints,
10
+ verify issues with a real PoC, and iterate over rounds with a persistent
11
+ memory. Too large for a single LLM call, so codejury ships the methodology and
12
+ scaffolds the workspace rather than running a pipeline.
13
+
14
+ Security knowledge lives in **rich rules** (`codejury/data/rules/*.md`, with
15
+ per-language vulnerable/secure examples), injected into the audit prompt, not
16
+ buried in code.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install codejury # core
22
+ pip install "codejury[anthropic]" # or [openai] / [litellm] for a backend
23
+ ```
24
+
25
+ ## Diff review
26
+
27
+ ```bash
28
+ # audit a diff file
29
+ codejury audit --diff-file changes.diff
30
+
31
+ # audit a git range in a repo
32
+ codejury audit --repo /path/to/app --git-range origin/main...HEAD
33
+
34
+ # from stdin
35
+ git diff HEAD~1 | codejury audit
36
+
37
+ # adversarial mode: Finder + Challenger + Judge (higher coverage, lower FP, ~3x cost)
38
+ codejury audit --diff-file changes.diff --mode adversarial
39
+
40
+ # CI gate + SARIF
41
+ codejury audit --diff-file changes.diff --format sarif --fail-on high
42
+ ```
43
+
44
+ Configure a backend with `--provider`/`--model`/`--api-key`/`--api-base` or the
45
+ `CODEJURY_API_KEY` / `CODEJURY_MODEL` / `CODEJURY_API_BASE` environment variables.
46
+ `codejury dry-run` exercises the engine with a mock provider and no key.
47
+
48
+ ## Whole-repo review
49
+
50
+ ```bash
51
+ codejury full-review /path/to/your/repo
52
+ ```
53
+
54
+ This scaffolds a review workspace (`api/`, `issues/`, `analysis/`, and a
55
+ `security-review-memory.md`), seeds the API inventory from a deterministic scan,
56
+ and prints the methodology. Run it with an interactive agent: it reads the
57
+ methodology and the rules, traverses the code from its API entrypoints, records
58
+ high-confidence issues with a PoC, and asks you to confirm credentials or false
59
+ positives along the way. Nothing runs against production.
60
+
61
+ ## Findings
62
+
63
+ Each finding carries a file and line, a severity and category, a concrete
64
+ exploit scenario, a recommendation, and a confidence. A false-positive filter
65
+ drops test/mock-path and low-confidence noise; the model is also told not to
66
+ report dependency CVEs, style notes, speculation, or config-leak-only risks.
67
+
68
+ ## Extending
69
+
70
+ Add a vulnerability class by dropping a new `codejury/data/rules/<class>.md` with
71
+ the standard frontmatter (title, impact, tags, triggers) and vulnerable/secure
72
+ examples. It is data; no code change needed.
@@ -0,0 +1,14 @@
1
+ """codejury: an AI code security review tool.
2
+
3
+ Two paths matched to their nature: a coded diff-audit engine (standard single
4
+ call or adversarial Finder/Challenger/Judge), and a whole-repo review run as a
5
+ methodology by an interactive agent. Security knowledge lives in rich markdown
6
+ rules (data/rules) injected into the audit prompt, not in a rendered schema.
7
+ """
8
+
9
+ from importlib.metadata import PackageNotFoundError, version
10
+
11
+ try:
12
+ __version__ = version("codejury")
13
+ except PackageNotFoundError: # running from a source tree without an install
14
+ __version__ = "0.0.0"
@@ -51,12 +51,30 @@ def load_entrypoint_signatures(path: str | Path = ENTRYPOINTS_FILE) -> _Signatur
51
51
  return _Signatures(decorators=tuple(data.get("decorators", [])), calls=tuple(data.get("calls", [])))
52
52
 
53
53
 
54
- def build_repo_model_from_dir(root: str | Path, *, signatures: _Signatures | None = None) -> RepoModel:
55
- """Build a RepoModel by reading a directory. Reuses RepoSource's safe walk."""
56
- from codejury.sources.repo import RepoSource
54
+ _SKIP_DIRS = frozenset({".git", ".venv", "venv", "node_modules", "__pycache__", ".mypy_cache", ".pytest_cache"})
55
+
56
+
57
+ def _read_python_files(root: Path) -> dict[str, str]:
58
+ """{relative path: content} for .py files under root, skipping noise dirs and
59
+ symlinks that escape the tree."""
60
+ root = root.resolve()
61
+ files: dict[str, str] = {}
62
+ for path in root.rglob("*.py"):
63
+ rel = path.relative_to(root)
64
+ if any(part in _SKIP_DIRS for part in rel.parts):
65
+ continue
66
+ try:
67
+ if not path.resolve().is_relative_to(root):
68
+ continue # symlink escaping the tree
69
+ files[str(rel)] = path.read_text(encoding="utf-8")
70
+ except (OSError, UnicodeDecodeError, ValueError):
71
+ continue
72
+ return files
57
73
 
58
- files = RepoSource(root, extensions=(".py",)).read_files()
59
- return build_repo_model(root, files, signatures=signatures)
74
+
75
+ def build_repo_model_from_dir(root: str | Path, *, signatures: _Signatures | None = None) -> RepoModel:
76
+ """Build a RepoModel by reading the .py files under a directory."""
77
+ return build_repo_model(root, _read_python_files(Path(root)), signatures=signatures)
60
78
 
61
79
 
62
80
  def build_repo_model(root: str | Path, files: dict[str, str], *, signatures: _Signatures | None = None) -> RepoModel:
@@ -0,0 +1,142 @@
1
+ """codejury CLI.
2
+
3
+ Two entry points matched to their nature:
4
+
5
+ - ``audit`` runs the coded diff engine over a unified diff: a single balanced
6
+ call (standard) or the adversarial Finder/Challenger/Judge pass.
7
+ - ``full-review`` scaffolds a workspace and prints the methodology for an
8
+ interactive agent to run a whole-repo review (it does not run an LLM pipeline,
9
+ which a single call cannot do for a whole codebase).
10
+
11
+ ``dry-run`` exercises the diff engine with a mock provider and no API key.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ import subprocess
18
+ import sys
19
+
20
+ from codejury.diff.debate import AdversarialAuditRunner
21
+ from codejury.diff.engine import AuditRunner
22
+ from codejury.diff.findings_filter import FindingsFilter
23
+ from codejury.diff.report import gate, render
24
+ from codejury.domain.finding import Finding
25
+ from codejury.fullreview.scaffold import scaffold
26
+ from codejury.providers.factory import (
27
+ DEFAULT_API_BASE,
28
+ DEFAULT_API_KEY,
29
+ DEFAULT_MODEL,
30
+ PROVIDERS,
31
+ make_provider,
32
+ )
33
+ from codejury.providers.mock import MockProvider
34
+
35
+ _FORMATS = ("text", "markdown", "json", "sarif")
36
+ _FAIL_ON = ("critical", "high", "medium", "low")
37
+
38
+
39
+ def audit_diff(
40
+ diff: str,
41
+ *,
42
+ provider,
43
+ model: str,
44
+ mode: str = "standard",
45
+ max_rounds: int = 3,
46
+ filter_findings: bool = True,
47
+ ) -> tuple[list[Finding], list[tuple[Finding, str]]]:
48
+ """Audit a diff and return (kept findings, dropped (finding, reason))."""
49
+ if mode == "adversarial":
50
+ findings = AdversarialAuditRunner(provider=provider, model=model).run(diff, max_rounds=max_rounds).findings
51
+ else:
52
+ findings = AuditRunner(provider=provider, model=model).run(diff)
53
+ if filter_findings:
54
+ return FindingsFilter().filter(findings)
55
+ return findings, []
56
+
57
+
58
+ def _read_diff(args) -> str:
59
+ if args.diff_file:
60
+ with open(args.diff_file, encoding="utf-8") as f:
61
+ return f.read()
62
+ if args.git_range:
63
+ return subprocess.run(
64
+ ["git", "-C", args.repo or ".", "diff", args.git_range],
65
+ capture_output=True, text=True, check=True,
66
+ ).stdout
67
+ return sys.stdin.read()
68
+
69
+
70
+ def _dry_run_diff() -> str:
71
+ return "+++ b/app.py\n@@ -0,0 +1 @@\n+cursor.execute('SELECT * FROM u WHERE n=' + name)\n"
72
+
73
+
74
+ def main(argv: list[str] | None = None) -> int:
75
+ parser = argparse.ArgumentParser(prog="codejury")
76
+ sub = parser.add_subparsers(dest="command")
77
+
78
+ sub.add_parser("dry-run", help="run the diff engine with a mock provider, no key")
79
+
80
+ a = sub.add_parser("audit", help="audit a unified diff for security findings")
81
+ a.add_argument("--diff-file", default=None, help="unified diff file (default: read stdin)")
82
+ a.add_argument("--repo", default=None, help="repo path for --git-range")
83
+ a.add_argument("--git-range", default=None, help="git range to diff, e.g. origin/main...HEAD")
84
+ a.add_argument("--mode", choices=("standard", "adversarial"), default="standard")
85
+ a.add_argument("--rounds", type=int, default=3, help="adversarial debate rounds")
86
+ a.add_argument("--provider", choices=PROVIDERS, default="anthropic")
87
+ a.add_argument("--model", default=DEFAULT_MODEL)
88
+ a.add_argument("--api-base", default=DEFAULT_API_BASE)
89
+ a.add_argument("--api-key", default=DEFAULT_API_KEY)
90
+ a.add_argument("--retries", type=int, default=0)
91
+ a.add_argument("--format", choices=_FORMATS, default="text", dest="fmt")
92
+ a.add_argument("--no-filter", action="store_true", help="skip the false-positive filter")
93
+ a.add_argument("--fail-on", choices=_FAIL_ON, default=None, dest="fail_on")
94
+
95
+ fr = sub.add_parser("full-review", help="scaffold a whole-repo review for an interactive agent")
96
+ fr.add_argument("directory", help="target repository to review")
97
+ fr.add_argument("--workspace", default="codejury-review", help="where to create the review workspace")
98
+
99
+ args = parser.parse_args(argv)
100
+ try:
101
+ return _dispatch(args, parser)
102
+ except Exception as exc:
103
+ print(f"{args.command or 'codejury'} failed: {exc}", file=sys.stderr)
104
+ return 1
105
+
106
+
107
+ def _dispatch(args, parser) -> int:
108
+ if args.command == "audit":
109
+ provider = make_provider(args.provider, api_key=args.api_key, api_base=args.api_base, retries=args.retries)
110
+ kept, _ = audit_diff(
111
+ _read_diff(args), provider=provider, model=args.model,
112
+ mode=args.mode, max_rounds=args.rounds, filter_findings=not args.no_filter,
113
+ )
114
+ print(render(args.fmt, kept))
115
+ return 1 if gate(kept, args.fail_on) else 0
116
+
117
+ if args.command == "full-review":
118
+ res = scaffold(args.directory, args.workspace)
119
+ print(f"Workspace: {res.workspace}", file=sys.stderr)
120
+ print(f"Seeded {res.entrypoints} entrypoints into {res.workspace}/api/_entrypoints.md", file=sys.stderr)
121
+ print(f"Memory: {res.memory_path}", file=sys.stderr)
122
+ print("\nRun this review with an interactive agent (Claude Code / Codex) using the methodology below.\n")
123
+ print(res.methodology)
124
+ return 0
125
+
126
+ if args.command in (None, "dry-run"):
127
+ kept, _ = audit_diff(
128
+ _dry_run_diff(),
129
+ provider=MockProvider(default='{"findings": [{"file": "app.py", "line": 1, "severity": "HIGH", '
130
+ '"category": "sql_injection", "description": "[mock] no backend called", '
131
+ '"confidence": 0.9}]}'),
132
+ model="mock",
133
+ )
134
+ print(render("text", kept))
135
+ return 0
136
+
137
+ parser.print_help()
138
+ return 1
139
+
140
+
141
+ if __name__ == "__main__":
142
+ raise SystemExit(main())
@@ -0,0 +1,102 @@
1
+ # Full Security Review — Agent Methodology
2
+
3
+ A whole-repository security audit, run by an interactive coding agent (Claude
4
+ Code, Codex, etc.), not a one-shot LLM call. It traverses the codebase from its
5
+ API entrypoints, reasons across files, verifies issues with a real PoC, and
6
+ iterates over multiple rounds with a persistent memory. One round is roughly
7
+ 30 minutes; run as many rounds as needed.
8
+
9
+ Target repository: the directory you were given.
10
+ Workspace: `<workspace>/<project>/` (created for you), holding `api/`,
11
+ `issues/`, `analysis/`, and `security-review-memory.md`.
12
+
13
+ ---
14
+
15
+ ## On start (do this first)
16
+
17
+ 1. Read `security-review-memory.md` in the workspace if it exists:
18
+ - skip every pattern under "Confirmed false positives";
19
+ - do not re-report anything under "Fixed";
20
+ - weight the files under "High-risk areas" more heavily.
21
+ 2. Read `api/_entrypoints.md` (seeded for you from a deterministic scan) as the
22
+ starting map of HTTP routes and CLI commands.
23
+ 3. Read the relevant rule files under the shipped `rules/` for the target's stack
24
+ (sql-injection, idor, ssrf, authentication-jwt, insecure-deserialization, ...).
25
+
26
+ ## Analysis
27
+
28
+ Start from the API entrypoints and read the implementation of each one. For every
29
+ endpoint ask:
30
+
31
+ - What inputs can the attacker control?
32
+ - Is authentication, authorization, signature verification, tenant isolation, or
33
+ a business-state check bypassed or missing?
34
+ - IDOR: can a user reach another user's, tenant's, or service's resource by a
35
+ supplied id?
36
+ - Do privileged operations (payment, signing, approval, state change) allow state
37
+ bypass or replay (no nonce / time window)?
38
+ - Mass assignment: is a user-controlled body bound wholesale into a model?
39
+ - Signature: is a caller-supplied key trusted as the trust anchor?
40
+
41
+ Record the API inventory in `api/` (one file per module: route + auth method +
42
+ review status ✅/⚠️/❌). Record architecture understanding and high-risk paths in
43
+ `analysis/`.
44
+
45
+ ## Scope
46
+
47
+ Report only HIGH / CRITICAL, exploitable, high-confidence issues. **Do not report**
48
+ (regardless of severity): dependency CVEs, style or best-practice notes,
49
+ speculative issues you cannot tie to a concrete exploit, and risks that only
50
+ matter if production config is leaked.
51
+
52
+ ## Recording an issue
53
+
54
+ Write one `issues/<name>.md` per confirmed issue. Do not write an issue you cannot
55
+ confirm with high confidence. Each must have:
56
+
57
+ ```markdown
58
+ # <title>
59
+
60
+ - Risk: HIGH | CRITICAL
61
+ - Type: IDOR | auth bypass | signature flaw | business logic | ...
62
+ - Endpoint: `<METHOD> <path>`
63
+
64
+ ## Analysis
65
+ (cite exact file paths and line numbers)
66
+
67
+ ## Attack path
68
+ (end-to-end, actionable steps)
69
+
70
+ ## PoC
71
+ (a curl command or script that actually triggers it)
72
+
73
+ ## Verification
74
+ (result of actually running the PoC in a sandbox / dev environment)
75
+
76
+ ## Fix
77
+ ```
78
+
79
+ ## PoC verification (human in the loop)
80
+
81
+ Confirm each issue by running the PoC against a sandbox / dev environment. When
82
+ you need something only the operator has, stop and ask:
83
+
84
+ - an auth cookie or token,
85
+ - an MFA step,
86
+ - specific test data or an account.
87
+
88
+ Never run a PoC against production, and never use real credentials or perform a
89
+ destructive action without the operator's explicit go-ahead.
90
+
91
+ ## Iteration
92
+
93
+ Each round, read the workspace history first and do not repeat finished work.
94
+ Process leftover TODOs; otherwise pick an unreviewed (❌) or to-deepen (⚠️)
95
+ endpoint from the API inventory. When every endpoint is ✅ and there are no TODOs,
96
+ report the review complete.
97
+
98
+ ## On finish
99
+
100
+ Append a row to the audit history in `security-review-memory.md`, and ask the
101
+ operator which findings were false positives. Record those under "Confirmed false
102
+ positives" so future rounds skip them.
@@ -0,0 +1,30 @@
1
+ # Security Review Memory — <project>
2
+
3
+ > Maintained by the security-review agent. Read at the start of every round,
4
+ > updated at the end. It skips confirmed false positives, avoids re-reporting
5
+ > fixed issues, and focuses on historically risky areas.
6
+
7
+ ## Confirmed false positives (skip, do not report)
8
+
9
+ <!-- FP-001 <short description>
10
+ - Date: YYYY-MM-DD
11
+ - Path/pattern: `tests/` or `apps/payment/mock_*.py`
12
+ - Type: sql_injection / auth_bypass / ...
13
+ - Why not a real issue: <reason>
14
+ -->
15
+
16
+ ## Fixed (do not report again)
17
+
18
+ <!-- FIXED-001 <issue title>
19
+ - Date / commit: YYYY-MM-DD / abc1234
20
+ - Original issue: <summary>
21
+ -->
22
+
23
+ ## High-risk areas (weight every round)
24
+
25
+ <!-- - `<path>` — <reason, e.g. past auth bypass> -->
26
+
27
+ ## Audit history
28
+
29
+ | Date | Mode | HIGH | MEDIUM | Notes |
30
+ |------|------|------|--------|-------|
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: code-security-review
3
+ description: "Application security rules for reviewing code for exploitable vulnerabilities. Use when reviewing a diff or a codebase for security issues, or when writing code that handles untrusted input, authentication, authorization, file paths, database queries, network requests, deserialization, or cryptography. Consult the relevant rule file before judging whether code is vulnerable."
4
+ ---
5
+
6
+ # Code Security Review Rules
7
+
8
+ Generic application-security rules, one file per vulnerability class under `rules/`.
9
+ Each rule states the impact, the patterns to hunt, and vulnerable-vs-secure code
10
+ examples. Used both by the diff-audit engine (the relevant rules are injected into
11
+ the prompt) and by the full-review agent (read the rules for the target's stack).
12
+
13
+ ## How to use
14
+
15
+ 1. Identify what the code does: handle input, query a DB, read files, fetch URLs,
16
+ authenticate, authorize, deserialize, render output?
17
+ 2. Read the matching rule files below, Critical and High first.
18
+ 3. Apply the secure pattern when writing; flag the vulnerable pattern when reviewing.
19
+ 4. Report only real, exploitable, high-confidence issues with a concrete exploit
20
+ path. Do not report dependency CVEs, style, speculation, or config-leak-only risks.
21
+
22
+ ## Rules
23
+
24
+ ### Critical
25
+ - SQL Injection — `rules/sql-injection.md`
26
+ - Command Injection — `rules/command-injection.md`
27
+ - Insecure Deserialization — `rules/insecure-deserialization.md`
28
+
29
+ ### High
30
+ - IDOR / object-level access — `rules/idor.md`
31
+ - Broken Access Control / function-level authz — `rules/broken-access-control.md`
32
+ - JWT / Authentication — `rules/authentication-jwt.md`
33
+ - SSRF — `rules/ssrf.md`
34
+ - Path Traversal — `rules/path-traversal.md`
35
+ - XSS — `rules/xss.md`
36
+ - Mass Assignment — `rules/mass-assignment.md`
37
+ - Insecure Cryptography — `rules/insecure-crypto.md`
38
+ - Hardcoded Secrets — `rules/secrets.md`
39
+
40
+ The set is data: add a rule by dropping a new `rules/<class>.md` with the same
41
+ frontmatter (title, impact, tags, triggers) and vulnerable/secure examples.
@@ -0,0 +1,21 @@
1
+ ---
2
+ title: JWT / Authentication Flaws
3
+ impact: HIGH
4
+ tags: [authentication, jwt, cwe-347, cwe-287, owasp-a07]
5
+ triggers: ["jwt.decode", "verify=False", "verify_signature", "algorithms", "none", "HS256", "decode("]
6
+ ---
7
+
8
+ ## JWT and Authentication Flaws
9
+
10
+ Accepting a token without verifying its signature, allowing the "none" algorithm, or trusting claims before verification lets an attacker forge identity. Verify the signature and validate iss/aud/exp before using any claim.
11
+
12
+ ### Python
13
+ Vulnerable:
14
+ ```python
15
+ claims = jwt.decode(token, options={"verify_signature": False})
16
+ jwt.decode(token, key, algorithms=["none"])
17
+ ```
18
+ Secure:
19
+ ```python
20
+ claims = jwt.decode(token, key, algorithms=["RS256"], audience=AUD, issuer=ISS)
21
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: Broken Access Control (Function-Level Authorization)
3
+ impact: HIGH
4
+ tags: [access-control, authorization, cwe-862, cwe-285, owasp-a01]
5
+ triggers: ["@app.route", "@router", "def ", "is_admin", "role", "permission", "@login_required", "requires_", "admin"]
6
+ ---
7
+
8
+ ## Broken Access Control
9
+
10
+ A privileged or state-changing endpoint is reachable without the authorization check its peers enforce, or the role/permission is derived from a client-controlled value. Enforce authorization server-side per request, from a trusted store; never trust a client-supplied role.
11
+
12
+ ### Python
13
+ Vulnerable:
14
+ ```python
15
+ @app.route("/admin/users/<uid>", methods=["DELETE"])
16
+ def delete_user(uid): # no auth check, unlike sibling routes
17
+ delete(uid)
18
+
19
+ is_admin = request.json["is_admin"] # client-controlled privilege
20
+ ```
21
+ Secure:
22
+ ```python
23
+ @app.route("/admin/users/<uid>", methods=["DELETE"])
24
+ @requires_admin
25
+ def delete_user(uid):
26
+ delete(uid)
27
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ title: Command Injection
3
+ impact: CRITICAL
4
+ tags: [injection, command, cwe-78, owasp-a03]
5
+ triggers: ["os.system", "os.popen", "subprocess", "shell=True", "exec(", "Runtime.getRuntime", "child_process", "popen"]
6
+ ---
7
+
8
+ ## Command Injection
9
+
10
+ Passing untrusted input to a shell lets an attacker run arbitrary commands. Never build a shell string from input; pass an argument list with the shell disabled.
11
+
12
+ ### Python
13
+ Vulnerable:
14
+ ```python
15
+ os.system("ping " + host)
16
+ subprocess.run(f"convert {name}", shell=True)
17
+ ```
18
+ Secure:
19
+ ```python
20
+ subprocess.run(["ping", "-c", "1", host], shell=False)
21
+ ```
22
+
23
+ ### Node.js
24
+ Vulnerable: `child_process.exec(`ping ${host}`)`
25
+ Secure: `child_process.execFile("ping", ["-c", "1", host])`
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: Insecure Direct Object Reference (IDOR)
3
+ impact: HIGH
4
+ tags: [access-control, idor, authorization, cwe-639, owasp-a01]
5
+ triggers: ["objects.get(", "findById", "get_object_or_404", "/<id>", "/:id", "request.args", "params[", "pk=", "where id ="]
6
+ ---
7
+
8
+ ## Insecure Direct Object Reference (IDOR)
9
+
10
+ A resource is fetched or mutated by a user-supplied id without checking the caller owns or may access it. An authenticated user reads or changes another user's, tenant's, or service's data by changing the id. Always scope the lookup to the caller's identity / tenant.
11
+
12
+ ### Python (Django)
13
+ Vulnerable:
14
+ ```python
15
+ account = BankAccount.objects.get(id=request.GET["account_id"])
16
+ ```
17
+ Secure:
18
+ ```python
19
+ account = get_object_or_404(BankAccount, id=request.GET["account_id"], org_id=request.user.org_id)
20
+ ```
21
+
22
+ ### Node.js (Express)
23
+ Vulnerable: `const doc = await Document.findById(req.params.id)`
24
+ Secure: `const doc = await Document.findOne({ _id: req.params.id, userId: req.user.id })`
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Insecure Cryptography
3
+ impact: HIGH
4
+ tags: [crypto, cwe-327, cwe-916, owasp-a02]
5
+ triggers: ["hashlib.md5", "hashlib.sha1", "DES", "ECB", "random.random", "random.randint", "MODE_ECB", "md5(", "sha1("]
6
+ ---
7
+
8
+ ## Insecure Cryptography
9
+
10
+ Weak algorithms (MD5, SHA-1, DES, RC4), ECB mode, fast hashes for passwords, static IVs, and non-cryptographic randomness for security values are all exploitable. Use AES-GCM / ChaCha20-Poly1305, bcrypt/argon2 for passwords, fresh random nonces, and a CSPRNG (secrets / os.urandom).
11
+
12
+ ### Python
13
+ Vulnerable:
14
+ ```python
15
+ hashlib.md5(password.encode()).hexdigest()
16
+ token = str(random.randint(0, 999999))
17
+ ```
18
+ Secure:
19
+ ```python
20
+ bcrypt.hashpw(password.encode(), bcrypt.gensalt())
21
+ token = secrets.token_urlsafe(32)
22
+ ```