codejury 0.17.1__tar.gz → 0.19.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 (110) hide show
  1. codejury-0.19.0/PKG-INFO +147 -0
  2. codejury-0.19.0/README.md +116 -0
  3. {codejury-0.17.1 → codejury-0.19.0}/codejury/__init__.py +3 -2
  4. {codejury-0.17.1 → codejury-0.19.0}/codejury/cli.py +1 -1
  5. codejury-0.19.0/codejury/data/detection.yaml +17 -0
  6. codejury-0.19.0/codejury/data/frameworks/go/echo.md +31 -0
  7. codejury-0.19.0/codejury/data/frameworks/go/gin.md +34 -0
  8. codejury-0.19.0/codejury/data/frameworks/javascript/express.md +36 -0
  9. codejury-0.19.0/codejury/data/frameworks/javascript/nestjs.md +36 -0
  10. codejury-0.19.0/codejury/data/frameworks/python/celery.md +36 -0
  11. {codejury-0.17.1/codejury/data/frameworks → codejury-0.19.0/codejury/data/frameworks/python}/django.md +10 -7
  12. codejury-0.19.0/codejury/data/frameworks/python/fastapi.md +37 -0
  13. codejury-0.19.0/codejury/data/frameworks/python/flask.md +37 -0
  14. codejury-0.19.0/codejury/data/languages/go.md +35 -0
  15. codejury-0.19.0/codejury/data/languages/javascript.md +34 -0
  16. {codejury-0.17.1 → codejury-0.19.0}/codejury/data/languages/python.md +4 -4
  17. codejury-0.19.0/codejury/data/languages/typescript.md +28 -0
  18. codejury-0.19.0/codejury/data/methodologies/repo-review.md +229 -0
  19. {codejury-0.17.1/codejury/data/methodology → codejury-0.19.0/codejury/data/methodologies}/security-review-memory.md +4 -4
  20. codejury-0.19.0/codejury/data/protocols/oauth.md +55 -0
  21. codejury-0.19.0/codejury/data/vulnerabilities/SKILL.md +59 -0
  22. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/code-injection.md +1 -1
  23. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/cross-site-request-forgery.md +1 -1
  24. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/cross-site-scripting.md +1 -1
  25. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/http-response-splitting.md +1 -1
  26. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/improper-authentication.md +1 -1
  27. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/information-exposure.md +5 -5
  28. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/insecure-cryptography.md +1 -1
  29. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/insecure-deserialization.md +1 -1
  30. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/insecure-direct-object-reference.md +2 -2
  31. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/insecure-transport.md +1 -1
  32. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/mass-assignment.md +1 -1
  33. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/open-redirect.md +1 -1
  34. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/path-traversal.md +3 -3
  35. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/race-condition.md +3 -3
  36. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/replay-attack.md +1 -1
  37. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/server-side-request-forgery.md +2 -2
  38. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/server-side-template-injection.md +3 -3
  39. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/session-fixation.md +2 -2
  40. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/sql-injection.md +1 -1
  41. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/xml-external-entity.md +2 -2
  42. codejury-0.19.0/codejury/detection.py +56 -0
  43. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/debate.py +6 -6
  44. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/debate_prompts.py +7 -7
  45. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/engine.py +6 -6
  46. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/findings_filter.py +2 -21
  47. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/prompts.py +5 -5
  48. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/runner.py +1 -1
  49. codejury-0.19.0/codejury/diff/vulnerabilities.py +75 -0
  50. {codejury-0.17.1 → codejury-0.19.0}/codejury/domain/__init__.py +1 -1
  51. codejury-0.19.0/codejury/guides.py +120 -0
  52. {codejury-0.17.1 → codejury-0.19.0}/codejury/mddoc.py +10 -8
  53. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/__init__.py +1 -1
  54. codejury-0.19.0/codejury/repo/model.py +103 -0
  55. codejury-0.19.0/codejury/repo/scaffold.py +204 -0
  56. {codejury-0.17.1 → codejury-0.19.0}/codejury/resources.py +4 -2
  57. codejury-0.19.0/codejury.egg-info/PKG-INFO +147 -0
  58. codejury-0.19.0/codejury.egg-info/SOURCES.txt +97 -0
  59. {codejury-0.17.1 → codejury-0.19.0}/pyproject.toml +1 -1
  60. codejury-0.19.0/tests/test_detection.py +35 -0
  61. {codejury-0.17.1 → codejury-0.19.0}/tests/test_diff_engine.py +3 -3
  62. codejury-0.19.0/tests/test_guides.py +56 -0
  63. {codejury-0.17.1 → codejury-0.19.0}/tests/test_repo_model.py +14 -3
  64. {codejury-0.17.1 → codejury-0.19.0}/tests/test_repo_scaffold.py +45 -8
  65. codejury-0.17.1/tests/test_rules.py → codejury-0.19.0/tests/test_vulnerabilities.py +31 -31
  66. codejury-0.17.1/PKG-INFO +0 -135
  67. codejury-0.17.1/README.md +0 -104
  68. codejury-0.17.1/codejury/data/methodology/repo-review.md +0 -140
  69. codejury-0.17.1/codejury/data/rules/SKILL.md +0 -58
  70. codejury-0.17.1/codejury/diff/rules.py +0 -74
  71. codejury-0.17.1/codejury/guides.py +0 -81
  72. codejury-0.17.1/codejury/repo/model.py +0 -61
  73. codejury-0.17.1/codejury/repo/scaffold.py +0 -117
  74. codejury-0.17.1/codejury.egg-info/PKG-INFO +0 -135
  75. codejury-0.17.1/codejury.egg-info/SOURCES.txt +0 -83
  76. codejury-0.17.1/tests/test_guides.py +0 -34
  77. {codejury-0.17.1 → codejury-0.19.0}/LICENSE +0 -0
  78. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/business-logic.md +0 -0
  79. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/command-injection.md +0 -0
  80. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/hardcoded-secrets.md +0 -0
  81. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/jwt-validation.md +0 -0
  82. {codejury-0.17.1/codejury/data/rules → codejury-0.19.0/codejury/data/vulnerabilities}/missing-authorization.md +0 -0
  83. {codejury-0.17.1 → codejury-0.19.0}/codejury/diff/__init__.py +0 -0
  84. {codejury-0.17.1 → codejury-0.19.0}/codejury/domain/finding.py +0 -0
  85. {codejury-0.17.1 → codejury-0.19.0}/codejury/json_parse.py +0 -0
  86. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/anthropic.py +0 -0
  87. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/base.py +0 -0
  88. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/factory.py +0 -0
  89. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/litellm.py +0 -0
  90. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/mock.py +0 -0
  91. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/openai.py +0 -0
  92. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/openai_format.py +0 -0
  93. {codejury-0.17.1 → codejury-0.19.0}/codejury/providers/retry.py +0 -0
  94. {codejury-0.17.1 → codejury-0.19.0}/codejury/repo/__init__.py +0 -0
  95. {codejury-0.17.1 → codejury-0.19.0}/codejury/report.py +0 -0
  96. {codejury-0.17.1 → codejury-0.19.0}/codejury.egg-info/dependency_links.txt +0 -0
  97. {codejury-0.17.1 → codejury-0.19.0}/codejury.egg-info/entry_points.txt +0 -0
  98. {codejury-0.17.1 → codejury-0.19.0}/codejury.egg-info/requires.txt +0 -0
  99. {codejury-0.17.1 → codejury-0.19.0}/codejury.egg-info/top_level.txt +0 -0
  100. {codejury-0.17.1 → codejury-0.19.0}/setup.cfg +0 -0
  101. {codejury-0.17.1 → codejury-0.19.0}/tests/test_anthropic_provider.py +0 -0
  102. {codejury-0.17.1 → codejury-0.19.0}/tests/test_cli_audit.py +0 -0
  103. {codejury-0.17.1 → codejury-0.19.0}/tests/test_diff_debate.py +0 -0
  104. {codejury-0.17.1 → codejury-0.19.0}/tests/test_json_parse.py +0 -0
  105. {codejury-0.17.1 → codejury-0.19.0}/tests/test_litellm_provider.py +0 -0
  106. {codejury-0.17.1 → codejury-0.19.0}/tests/test_mddoc.py +0 -0
  107. {codejury-0.17.1 → codejury-0.19.0}/tests/test_openai_format.py +0 -0
  108. {codejury-0.17.1 → codejury-0.19.0}/tests/test_openai_provider.py +0 -0
  109. {codejury-0.17.1 → codejury-0.19.0}/tests/test_report.py +0 -0
  110. {codejury-0.17.1 → codejury-0.19.0}/tests/test_retry_provider.py +0 -0
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: codejury
3
+ Version: 0.19.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
+ Requires-Dist: json-repair>=0.30
21
+ Provides-Extra: anthropic
22
+ Requires-Dist: anthropic>=0.40; extra == "anthropic"
23
+ Provides-Extra: openai
24
+ Requires-Dist: openai>=1.0; extra == "openai"
25
+ Provides-Extra: litellm
26
+ Requires-Dist: litellm>=1.0; extra == "litellm"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8.0; extra == "dev"
29
+ Requires-Dist: jsonschema>=4.0; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ ```
33
+ ██████╗ ██████╗ ██████╗ ███████╗ ██╗██╗ ██╗██████╗ ██╗ ██╗
34
+ ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██║██║ ██║██╔══██╗╚██╗ ██╔╝
35
+ ██║ ██║ ██║██║ ██║█████╗ ██║██║ ██║██████╔╝ ╚████╔╝
36
+ ██║ ██║ ██║██║ ██║██╔══╝ ██ ██║██║ ██║██╔══██╗ ╚██╔╝
37
+ ╚██████╗╚██████╔╝██████╔╝███████╗╚█████╔╝╚██████╔╝██║ ██║ ██║
38
+ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
39
+ ```
40
+
41
+ > AI code security review for diffs and whole repositories.
42
+
43
+ It runs two paths matched to their nature.
44
+
45
+ - **Diff Review** is coded. It audits a pull request diff for newly introduced
46
+ exploitable risk, as a single balanced LLM call or an adversarial Finder,
47
+ Challenger, and Judge pass that trades roughly 3x the cost for extra recall on
48
+ subtle flaws that span files.
49
+ - **Repo Review** is agent driven. It is a methodology an interactive agent such
50
+ as Claude Code or Codex runs to map a codebase attack surface, trace inputs to
51
+ sinks across files, verify issues with a real PoC, and iterate over rounds with
52
+ a persistent memory. A whole repository is too large for one LLM call, so it
53
+ ships the methodology and scaffolds the workspace instead of running a
54
+ pipeline.
55
+
56
+ Security knowledge lives in rich vulnerability classes under `codejury/data/vulnerabilities/*.md`, with a
57
+ vulnerable and a secure example per language, injected into the audit prompt
58
+ rather than buried in code.
59
+
60
+ ## Install
61
+
62
+ ```bash
63
+ pip install codejury # core
64
+ pip install "codejury[anthropic]" # add a backend, also openai or litellm
65
+ ```
66
+
67
+ ## Diff Review
68
+
69
+ ```bash
70
+ # audit a diff file
71
+ codejury review diff --diff-file changes.diff
72
+
73
+ # audit a git range in a repo
74
+ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
75
+
76
+ # from stdin
77
+ git diff HEAD~1 | codejury review diff
78
+
79
+ # adversarial mode, more recall on subtle flaws, about 3x the cost
80
+ codejury review diff --diff-file changes.diff --mode adversarial
81
+
82
+ # CI gate and SARIF
83
+ codejury review diff --diff-file changes.diff --format sarif --fail-on high
84
+ ```
85
+
86
+ Configure a backend with `--provider`, `--model`, `--api-key`, `--api-base`, or
87
+ the `CODEJURY_API_KEY`, `CODEJURY_MODEL`, and `CODEJURY_API_BASE` environment
88
+ variables. `codejury review diff --dry-run` exercises the engine with a mock
89
+ provider and no key, and falls back to a built in demo diff when you pass none.
90
+
91
+ ### Choosing a Model and Mode
92
+
93
+ Detection quality is dominated by the model first, then the mode. On real diff
94
+ probes:
95
+
96
+ - A strong model at the Claude Sonnet tier in standard mode caught every planted
97
+ vulnerability with almost no false positives. A weaker model raised false
98
+ positives in both modes, so the model is the lever that matters most.
99
+ - Adversarial mode did not lower false positives over standard on those probes
100
+ and costs about 3x. Reach for it to gain recall on subtle logic that spans
101
+ files, not as a way to cut false positives.
102
+
103
+ Default to standard mode with a strong model, set with `--model` or
104
+ `CODEJURY_MODEL`. False positives are held down by the do not report list and the
105
+ post filter, not by the mode.
106
+
107
+ ### Use in CI with GitHub Actions
108
+
109
+ Audit every pull request and surface findings in the code scanning tab. Copy
110
+ `examples/codejury-pr-review.yml` into `.github/workflows/`, add a
111
+ `CODEJURY_API_KEY` repository secret, and it will
112
+
113
+ 1. diff the pull request against its base with `--git-range origin/<base>...HEAD`,
114
+ 2. write SARIF and upload it with `github/codeql-action/upload-sarif`,
115
+ 3. fail the check on a HIGH or CRITICAL finding with `--fail-on high`.
116
+
117
+ The job makes one model call per pull request in standard mode. The SARIF is
118
+ uploaded even when the gate fails, so findings always show up on the pull
119
+ request.
120
+
121
+ ## Repo Review
122
+
123
+ ```bash
124
+ codejury review repo /path/to/your/repo
125
+ ```
126
+
127
+ This scaffolds a review workspace with `entrypoints/`, `issues/`, `analysis/`,
128
+ and a `security-review-memory.md`, seeds the entrypoint inventory from a
129
+ deterministic scan, and prints the methodology. Run it with an interactive agent.
130
+ It reads the methodology and the vulnerability classes, maps the attack surface, traces inputs to
131
+ sinks across files, records high confidence issues with a PoC, and asks you to
132
+ confirm credentials or false positives along the way. Nothing runs against
133
+ production.
134
+
135
+ ## Findings
136
+
137
+ Each finding carries a file and line, a severity and category, a concrete exploit
138
+ scenario, a recommendation, and a confidence. A false positive filter drops test
139
+ paths, mock paths, and low confidence noise. The model is also told not to report
140
+ dependency CVEs, style notes, speculation, or risks that only matter when
141
+ production config leaks.
142
+
143
+ ## Extending
144
+
145
+ Add a vulnerability class by dropping a new file `codejury/data/vulnerabilities/<class>.md`
146
+ with the standard frontmatter of title, impact, tags, and triggers plus a
147
+ vulnerable and a secure example. It is data, no code change needed.
@@ -0,0 +1,116 @@
1
+ ```
2
+ ██████╗ ██████╗ ██████╗ ███████╗ ██╗██╗ ██╗██████╗ ██╗ ██╗
3
+ ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██║██║ ██║██╔══██╗╚██╗ ██╔╝
4
+ ██║ ██║ ██║██║ ██║█████╗ ██║██║ ██║██████╔╝ ╚████╔╝
5
+ ██║ ██║ ██║██║ ██║██╔══╝ ██ ██║██║ ██║██╔══██╗ ╚██╔╝
6
+ ╚██████╗╚██████╔╝██████╔╝███████╗╚█████╔╝╚██████╔╝██║ ██║ ██║
7
+ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
8
+ ```
9
+
10
+ > AI code security review for diffs and whole repositories.
11
+
12
+ It runs two paths matched to their nature.
13
+
14
+ - **Diff Review** is coded. It audits a pull request diff for newly introduced
15
+ exploitable risk, as a single balanced LLM call or an adversarial Finder,
16
+ Challenger, and Judge pass that trades roughly 3x the cost for extra recall on
17
+ subtle flaws that span files.
18
+ - **Repo Review** is agent driven. It is a methodology an interactive agent such
19
+ as Claude Code or Codex runs to map a codebase attack surface, trace inputs to
20
+ sinks across files, verify issues with a real PoC, and iterate over rounds with
21
+ a persistent memory. A whole repository is too large for one LLM call, so it
22
+ ships the methodology and scaffolds the workspace instead of running a
23
+ pipeline.
24
+
25
+ Security knowledge lives in rich vulnerability classes under `codejury/data/vulnerabilities/*.md`, with a
26
+ vulnerable and a secure example per language, injected into the audit prompt
27
+ rather than buried in code.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ pip install codejury # core
33
+ pip install "codejury[anthropic]" # add a backend, also openai or litellm
34
+ ```
35
+
36
+ ## Diff Review
37
+
38
+ ```bash
39
+ # audit a diff file
40
+ codejury review diff --diff-file changes.diff
41
+
42
+ # audit a git range in a repo
43
+ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
44
+
45
+ # from stdin
46
+ git diff HEAD~1 | codejury review diff
47
+
48
+ # adversarial mode, more recall on subtle flaws, about 3x the cost
49
+ codejury review diff --diff-file changes.diff --mode adversarial
50
+
51
+ # CI gate and SARIF
52
+ codejury review diff --diff-file changes.diff --format sarif --fail-on high
53
+ ```
54
+
55
+ Configure a backend with `--provider`, `--model`, `--api-key`, `--api-base`, or
56
+ the `CODEJURY_API_KEY`, `CODEJURY_MODEL`, and `CODEJURY_API_BASE` environment
57
+ variables. `codejury review diff --dry-run` exercises the engine with a mock
58
+ provider and no key, and falls back to a built in demo diff when you pass none.
59
+
60
+ ### Choosing a Model and Mode
61
+
62
+ Detection quality is dominated by the model first, then the mode. On real diff
63
+ probes:
64
+
65
+ - A strong model at the Claude Sonnet tier in standard mode caught every planted
66
+ vulnerability with almost no false positives. A weaker model raised false
67
+ positives in both modes, so the model is the lever that matters most.
68
+ - Adversarial mode did not lower false positives over standard on those probes
69
+ and costs about 3x. Reach for it to gain recall on subtle logic that spans
70
+ files, not as a way to cut false positives.
71
+
72
+ Default to standard mode with a strong model, set with `--model` or
73
+ `CODEJURY_MODEL`. False positives are held down by the do not report list and the
74
+ post filter, not by the mode.
75
+
76
+ ### Use in CI with GitHub Actions
77
+
78
+ Audit every pull request and surface findings in the code scanning tab. Copy
79
+ `examples/codejury-pr-review.yml` into `.github/workflows/`, add a
80
+ `CODEJURY_API_KEY` repository secret, and it will
81
+
82
+ 1. diff the pull request against its base with `--git-range origin/<base>...HEAD`,
83
+ 2. write SARIF and upload it with `github/codeql-action/upload-sarif`,
84
+ 3. fail the check on a HIGH or CRITICAL finding with `--fail-on high`.
85
+
86
+ The job makes one model call per pull request in standard mode. The SARIF is
87
+ uploaded even when the gate fails, so findings always show up on the pull
88
+ request.
89
+
90
+ ## Repo Review
91
+
92
+ ```bash
93
+ codejury review repo /path/to/your/repo
94
+ ```
95
+
96
+ This scaffolds a review workspace with `entrypoints/`, `issues/`, `analysis/`,
97
+ and a `security-review-memory.md`, seeds the entrypoint inventory from a
98
+ deterministic scan, and prints the methodology. Run it with an interactive agent.
99
+ It reads the methodology and the vulnerability classes, maps the attack surface, traces inputs to
100
+ sinks across files, records high confidence issues with a PoC, and asks you to
101
+ confirm credentials or false positives along the way. Nothing runs against
102
+ production.
103
+
104
+ ## Findings
105
+
106
+ Each finding carries a file and line, a severity and category, a concrete exploit
107
+ scenario, a recommendation, and a confidence. A false positive filter drops test
108
+ paths, mock paths, and low confidence noise. The model is also told not to report
109
+ dependency CVEs, style notes, speculation, or risks that only matter when
110
+ production config leaks.
111
+
112
+ ## Extending
113
+
114
+ Add a vulnerability class by dropping a new file `codejury/data/vulnerabilities/<class>.md`
115
+ with the standard frontmatter of title, impact, tags, and triggers plus a
116
+ vulnerable and a secure example. It is data, no code change needed.
@@ -1,9 +1,10 @@
1
- """codejury: an AI code security review tool.
1
+ """AI code security review tool.
2
2
 
3
3
  Two paths matched to their nature: a coded diff-audit engine (standard single
4
4
  call or adversarial Finder/Challenger/Judge), and a whole-repo review run as a
5
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.
6
+ vulnerability classes (data/vulnerabilities) injected into the audit prompt, not
7
+ in a rendered schema.
7
8
  """
8
9
 
9
10
  from importlib.metadata import PackageNotFoundError, version
@@ -1,4 +1,4 @@
1
- """codejury CLI: thin argument parsing and dispatch.
1
+ """Command line interface: thin argument parsing and dispatch.
2
2
 
3
3
  Two paths matched to their nature:
4
4
 
@@ -0,0 +1,17 @@
1
+ # File and path classification, across ecosystems: what the engine treats as a
2
+ # source file, a dependency manifest, a noise directory, or test code. Kept here
3
+ # so the implementation enumerates no language itself, adding a language is a
4
+ # data edit. This is distinct from a guide's stack detection, which decides which
5
+ # language, framework, or protocol applies.
6
+
7
+ skip_dirs: [".git", ".venv", "venv", "node_modules", "__pycache__", ".mypy_cache", ".pytest_cache"]
8
+
9
+ source_extensions: [".py", ".js", ".ts", ".tsx", ".jsx", ".mjs", ".go", ".rb", ".java", ".kt", ".php", ".cs", ".scala", ".rs"]
10
+
11
+ config_extensions: [".yaml", ".yml", ".toml", ".ini", ".cfg", ".conf", ".env"]
12
+
13
+ manifests: ["requirements.txt", "requirements-dev.txt", "pyproject.toml", "setup.py", "Pipfile", "package.json", "go.mod", "Gemfile", "pom.xml", "build.gradle", "Cargo.toml", "composer.json"]
14
+
15
+ test_dirs: ["test", "tests", "__tests__", "__mocks__", "mocks", "fixtures", "testdata", "e2e", "spec", "specs"]
16
+
17
+ test_name_patterns: ["test_*", "*_test.*", "*.test.*", "*.spec.*"]
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: echo
3
+ title: Echo
4
+ kind: framework
5
+ language: go
6
+ detect:
7
+ manifest: ["labstack/echo"]
8
+ imports: ["github.com/labstack/echo"]
9
+ entrypoint_files: ["*main.go", "*/handlers/*.go", "*/handler/*.go", "*/api/*.go", "*/routes/*.go", "*/controllers/*.go"]
10
+ entrypoint_markers: ["echo.New(", "echo.Context", "e.GET", "e.POST", ".GET(", ".POST(", ".Group(", "c.Param", "c.QueryParam", "c.Bind"]
11
+ logic_layers: ["*/service/*.go", "*/services/*.go", "*/usecase/*.go", "*/repository/*.go", "*/repo/*.go", "*/store/*.go", "*/dao/*.go", "*/model/*.go"]
12
+ ---
13
+ # Echo Review Notes
14
+
15
+ ## Entrypoints
16
+ - Handlers have the signature `func(c echo.Context) error`, registered with
17
+ `e.GET`, `.POST`, and grouped under `e.Group`. Input comes from `c.Param`,
18
+ `c.QueryParam`, `c.FormValue`, `c.Request().Header`, and `c.Bind` into a struct.
19
+
20
+ ## Authorization / IDOR
21
+ - Auth is middleware, applied globally, on a `Group`, or per route. The flaw to
22
+ hunt is a route registered outside the authenticated group, inheriting no
23
+ check. Compare grouped routes against routes on the bare instance.
24
+ - IDOR: a record loaded by `c.Param("id")` with no owner or tenant scope.
25
+
26
+ ## Common Sinks / Gotchas
27
+ - SQL: `fmt.Sprintf` into `db.Query` or `db.Exec`, instead of placeholders.
28
+ - Command: `exec.Command` built from input.
29
+ - Path: `c.File` or `c.Attachment` and `filepath.Join` on a path from input.
30
+ - `c.Bind` into a struct with privileged fields is mass assignment.
31
+ - A returned `error` that the caller drops can hide a failed auth or validation.
@@ -0,0 +1,34 @@
1
+ ---
2
+ id: gin
3
+ title: Gin
4
+ kind: framework
5
+ language: go
6
+ detect:
7
+ manifest: ["gin-gonic/gin"]
8
+ imports: ["github.com/gin-gonic/gin"]
9
+ entrypoint_files: ["*main.go", "*/handlers/*.go", "*/handler/*.go", "*/api/*.go", "*/routes/*.go", "*/controllers/*.go"]
10
+ entrypoint_markers: ["gin.Default(", "gin.New(", "*gin.Context", "router.GET", "router.POST", ".GET(", ".POST(", ".Group(", "c.Param", "c.Query", "c.ShouldBind"]
11
+ logic_layers: ["*/service/*.go", "*/services/*.go", "*/usecase/*.go", "*/repository/*.go", "*/repo/*.go", "*/store/*.go", "*/dao/*.go", "*/model/*.go"]
12
+ ---
13
+ # Gin Review Notes
14
+
15
+ ## Entrypoints
16
+ - Handlers have the signature `func(c *gin.Context)`, registered with
17
+ `router.GET`, `.POST`, and grouped under `router.Group`. Input comes from
18
+ `c.Param`, `c.Query`, `c.PostForm`, `c.GetHeader`, and `c.ShouldBindJSON` or
19
+ `c.Bind` into a struct.
20
+
21
+ ## Authorization / IDOR
22
+ - Auth is middleware, applied globally, on a `Group`, or per route. The classic
23
+ flaw is a route registered outside the authenticated group, so it inherits no
24
+ check. Compare a group's routes against the routes registered on the bare
25
+ engine.
26
+ - IDOR: a record loaded by `c.Param("id")` with no owner or tenant scope.
27
+
28
+ ## Common Sinks / Gotchas
29
+ - SQL: `fmt.Sprintf` into `db.Query` or `db.Exec`, instead of placeholders.
30
+ - Command: `exec.Command` built from input.
31
+ - Path: `c.File` or `filepath.Join` on a path from input, the traversal sink.
32
+ - `c.ShouldBindJSON` into a struct with privileged fields is mass assignment.
33
+ - A handler that ignores the error from a bind or an auth call proceeds as if it
34
+ passed.
@@ -0,0 +1,36 @@
1
+ ---
2
+ id: express
3
+ title: Express
4
+ kind: framework
5
+ language: javascript
6
+ detect:
7
+ manifest: ["express"]
8
+ imports: ["require('express')", "require(\"express\")", "from 'express'"]
9
+ entrypoint_files: ["*app.js", "*server.js", "*app.ts", "*server.ts", "*/routes/*.js", "*/routes/*.ts", "*/controllers/*.js", "*/controllers/*.ts", "*router*.js", "*router*.ts"]
10
+ entrypoint_markers: ["express()", "app.get(", "app.post(", "app.use(", "router.get(", "router.post(", ".get(", ".post(", "req.params", "req.query", "req.body"]
11
+ logic_layers: ["*/services/*.js", "*/services/*.ts", "*/models/*.js", "*/models/*.ts", "*/repositories/*.js", "*/repositories/*.ts", "*/dao/*.js", "*/dao/*.ts"]
12
+ ---
13
+ # Express Review Notes
14
+
15
+ Works the same in JavaScript and TypeScript. See the JavaScript guide for the
16
+ runtime sinks.
17
+
18
+ ## Entrypoints
19
+ - Routes are `app.get` / `app.post` / `router.*`, and a `Router` mounted with
20
+ `app.use("/prefix", router)`. The handler is `(req, res, next)`. Input is
21
+ `req.params`, `req.query`, `req.body`, `req.headers`, and `req.cookies`.
22
+
23
+ ## Authorization / IDOR
24
+ - Auth is middleware, passed to `app.use` or per route. The flaw to hunt is a
25
+ route mounted before the auth middleware, or one that omits the middleware its
26
+ siblings have, so order and placement matter.
27
+ - IDOR: a record loaded by `req.params.id` with no owner or tenant scope.
28
+
29
+ ## Common Sinks / Gotchas
30
+ - SQL and NoSQL: a query built by string concatenation, or a Mongo filter built
31
+ straight from `req.body`, the operator-injection sink.
32
+ - Command: `child_process.exec` from input. Code: `eval` from input.
33
+ - Path: `res.sendFile` or `path.join` on a path from input, the traversal sink.
34
+ - Open redirect via `res.redirect(req.query...)`, and prototype pollution from a
35
+ body merge.
36
+ - A body spread whole into a model or an ORM create is mass assignment.
@@ -0,0 +1,36 @@
1
+ ---
2
+ id: nestjs
3
+ title: NestJS
4
+ kind: framework
5
+ language: javascript
6
+ detect:
7
+ manifest: ["@nestjs/core", "@nestjs/common"]
8
+ imports: ["@nestjs/common", "@nestjs/core"]
9
+ entrypoint_files: ["*.controller.ts", "*.controller.js", "*/controllers/*.ts", "*.resolver.ts", "*.gateway.ts"]
10
+ entrypoint_markers: ["@Controller(", "@Get(", "@Post(", "@Put(", "@Delete(", "@Body(", "@Param(", "@Query(", "@UseGuards("]
11
+ logic_layers: ["*.service.ts", "*.service.js", "*/services/*.ts", "*.repository.ts", "*/repositories/*.ts", "*.entity.ts", "*/dao/*.ts"]
12
+ ---
13
+ # NestJS Review Notes
14
+
15
+ Usually TypeScript on Node. See the JavaScript and TypeScript guides for the
16
+ runtime sinks and for why types do not sanitize input.
17
+
18
+ ## Entrypoints
19
+ - A `@Controller` class with `@Get` / `@Post` methods. Input binds through
20
+ `@Param`, `@Query`, `@Body`, and `@Headers`. GraphQL resolvers and WebSocket
21
+ gateways are entrypoints too.
22
+
23
+ ## Authorization / IDOR
24
+ - Access control is a guard applied with `@UseGuards`, at the controller or the
25
+ method, plus role decorators. The flaw to hunt is a route or controller missing
26
+ the guard its siblings declare, and a guard that authenticates but does not
27
+ authorize the specific resource.
28
+ - IDOR: a handler that loads by `@Param("id")` with no owner or tenant check.
29
+
30
+ ## Common Sinks / Gotchas
31
+ - Mass assignment: a `@Body` DTO with no `ValidationPipe` and `whitelist: true`
32
+ binds any field the client sends. Confirm the pipe is global or applied.
33
+ - SQL: a TypeORM or Prisma raw query built from input.
34
+ - SSRF: a server-side `fetch` or `axios` to a URL from input.
35
+ - A custom guard that returns true on an unhandled path, or reads the user from a
36
+ header the client controls.
@@ -0,0 +1,36 @@
1
+ ---
2
+ id: celery
3
+ title: Celery
4
+ kind: framework
5
+ language: python
6
+ detect:
7
+ imports: ["celery", "shared_task"]
8
+ entrypoint_files: ["*tasks.py", "*/tasks/*.py"]
9
+ entrypoint_markers: ["@shared_task", "@app.task", "@celery_app.task", "@periodic_task", ".delay(", ".apply_async(", "crontab("]
10
+ ---
11
+ # Celery Review Notes
12
+
13
+ A task is an entrypoint, not just glue. Its arguments are attacker-influenced
14
+ whenever the enqueue site passes request input through, so review a task the same
15
+ way as an HTTP handler. The web view that calls `.delay()` or `.apply_async()` is
16
+ the producer, and the task body is where the value lands.
17
+
18
+ ## Entrypoints
19
+ - Task definitions in `tasks.py` or a `tasks/` package, marked by `@shared_task`,
20
+ `@app.task`, or `@celery_app.task`. Periodic tasks wired by `crontab()` or a
21
+ beat schedule run with no caller, so their inputs are config or stored state.
22
+ - Trace each task back to its `.delay(...)` and `.apply_async(...)` callers to see
23
+ which arguments are user-controlled.
24
+
25
+ ## What to Hunt
26
+ - A task that fetches a URL, runs a command, opens a file path, or renders a
27
+ template from an argument, the same sink classes as a web handler, now reached
28
+ off the request cycle.
29
+ - Authorization re-check. A producer that checked the caller does not carry that
30
+ identity into the task, so a task that acts on a resource by an id in its
31
+ arguments needs its own owner or tenant check.
32
+ - Secret and token exposure. A task that logs full request headers, a response
33
+ body, or a fetched credential leaks it into worker logs. See the
34
+ information-exposure vulnerability class.
35
+ - Replayable or duplicate enqueue. A task with a side effect that is enqueued from
36
+ an unauthenticated or replayable producer runs more than once.
@@ -2,13 +2,16 @@
2
2
  id: django
3
3
  title: Django
4
4
  kind: framework
5
+ language: python
5
6
  detect:
6
7
  files: ["*urls.py", "manage.py", "*settings.py"]
7
8
  manifest: ["django"]
8
9
  imports: ["from django", "import django"]
9
- entrypoint_files: ["*urls.py"]
10
+ entrypoint_files: ["*urls.py", "*views.py", "*viewsets.py", "*/views/*.py", "*serializers.py", "*api.py", "*consumers.py"]
11
+ entrypoint_markers: ["APIView", "ViewSet", "@api_view", "@action", "router.register", "path(", "re_path(", "as_view("]
12
+ logic_layers: ["*/controllers/*.py", "*controllers.py", "*/managers/*.py", "*managers.py", "*/dao/*.py", "*dao.py", "*/services/*.py", "*services.py", "*/models/*.py", "*models.py"]
10
13
  ---
11
- # Django review notes
14
+ # Django Review Notes
12
15
 
13
16
  ## Entrypoints
14
17
  - Routes live in `urls.py`: `path()` / `re_path()` map a URL to a view.
@@ -18,14 +21,14 @@ entrypoint_files: ["*urls.py"]
18
21
  signals, and middleware.
19
22
 
20
23
  ## Authorization / IDOR
21
- - Auth is enforced by decorators (`@login_required`), DRF permission classes, or
24
+ - Auth is enforced by decorators such as `@login_required`, DRF permission classes, or
22
25
  middleware. Note where it is and where it is missing.
23
- - Classic IDOR shape: `Model.objects.get(pk=<user input>)` (or `filter(id=...)`)
26
+ - Classic IDOR shape: `Model.objects.get(pk=<user input>)` or `filter(id=...)`
24
27
  with no owner/tenant scoping, then returned to the caller. Inspect every object
25
28
  fetch keyed by a user-supplied id.
26
29
 
27
- ## Common sinks / gotchas
30
+ ## Common Sinks / Gotchas
28
31
  - SQL: `.raw()`, `.extra()`, `RawSQL`, or string-built SQL via `connection.cursor()`.
29
32
  - Templates: `mark_safe`, `|safe`, `format_html` on unescaped user input, autoescape off.
30
- - `pickle` / `yaml.load` on a cookie or upload, `DEBUG=True` leaking internals,
31
- a hardcoded `SECRET_KEY`.
33
+ - Settings: `DEBUG=True` leaks internals, a hardcoded `SECRET_KEY`. Untrusted
34
+ deserialization is a language-level sink, see the Python guide.
@@ -0,0 +1,37 @@
1
+ ---
2
+ id: fastapi
3
+ title: FastAPI
4
+ kind: framework
5
+ language: python
6
+ detect:
7
+ manifest: ["fastapi"]
8
+ imports: ["from fastapi", "import fastapi"]
9
+ entrypoint_files: ["*main.py", "*/routers/*.py", "*/api/*.py", "*api.py", "*routes.py", "*/endpoints/*.py"]
10
+ entrypoint_markers: ["FastAPI(", "APIRouter(", "@app.get", "@app.post", "@router.get", "@router.post", "Depends("]
11
+ logic_layers: ["*/services/*.py", "*services.py", "*/models/*.py", "*models.py", "*/repositories/*.py", "*/crud/*.py", "*/dao/*.py"]
12
+ ---
13
+ # FastAPI Review Notes
14
+
15
+ ## Entrypoints
16
+ - Path operations decorated with `@app.get` / `@app.post` or `@router.*` on an
17
+ `APIRouter`. Inputs arrive as path and query parameters, and as a request body
18
+ validated by a Pydantic model.
19
+ - A Pydantic model bounds the body's shape, but an over-wide model still binds
20
+ privileged fields, the mass-assignment shape.
21
+
22
+ ## Authorization / IDOR
23
+ - Auth and access control run through `Depends`, for example a dependency that
24
+ resolves the current user or checks a scope. Note an endpoint that omits the
25
+ dependency its siblings use, or a dependency that authenticates but does not
26
+ authorize the specific resource.
27
+ - IDOR: an endpoint that loads a record by an id parameter with no owner or tenant
28
+ check.
29
+
30
+ ## Common Sinks / Gotchas
31
+ - SQL: a raw query or an ORM `text()` built from a parameter.
32
+ - SSRF: `httpx` or `requests` to a URL from input, common in webhook and fetch
33
+ endpoints.
34
+ - Path: `FileResponse` on a path from input.
35
+ - `CORSMiddleware` with `allow_origins=["*"]` together with credentials, and an
36
+ OAuth2 bearer dependency that decodes a token without verifying signature,
37
+ audience, and expiry.
@@ -0,0 +1,37 @@
1
+ ---
2
+ id: flask
3
+ title: Flask
4
+ kind: framework
5
+ language: python
6
+ detect:
7
+ manifest: ["flask"]
8
+ imports: ["from flask", "import flask"]
9
+ entrypoint_files: ["*app.py", "*views.py", "*routes.py", "*/views/*.py", "*/blueprints/*.py", "*api.py"]
10
+ entrypoint_markers: ["@app.route", ".route(", "Blueprint(", "add_url_rule(", "MethodView", "@app.before_request"]
11
+ logic_layers: ["*/services/*.py", "*services.py", "*/models/*.py", "*models.py", "*/repositories/*.py", "*/dao/*.py"]
12
+ ---
13
+ # Flask Review Notes
14
+
15
+ ## Entrypoints
16
+ - Routes are functions decorated with `@app.route` or `@bp.route`, or registered
17
+ with `add_url_rule`. Blueprints mount a group under a URL prefix. Class views
18
+ subclass `MethodView`.
19
+ - Read input from `request.args`, `request.form`, `request.values`,
20
+ `request.json`, `request.files`, `request.headers`, and `request.cookies`, all
21
+ attacker-controlled.
22
+
23
+ ## Authorization / IDOR
24
+ - Auth is enforced by a `@login_required` style decorator, a `before_request`
25
+ hook, or an explicit check in the view. Note where it is and where a route
26
+ lacks it.
27
+ - IDOR: a model fetched by an id from the request with no owner or tenant scope,
28
+ then returned.
29
+
30
+ ## Common Sinks / Gotchas
31
+ - SSTI: `render_template_string` on input, or `Markup` and `|safe` on unescaped
32
+ input.
33
+ - SQL: raw `cursor.execute` or an ORM `text()` built from input.
34
+ - Path: `send_file` or `send_from_directory` with a path from input, the traversal
35
+ sink.
36
+ - A hardcoded `SECRET_KEY`, `debug=True` in production, and an open redirect via
37
+ `redirect(request.args[...])`.
@@ -0,0 +1,35 @@
1
+ ---
2
+ id: go
3
+ title: Go
4
+ kind: language
5
+ detect:
6
+ files: ["*.go", "go.mod"]
7
+ entrypoint_files: ["*main.go", "*/handlers/*.go", "*/handler/*.go", "*/api/*.go", "*/routes/*.go"]
8
+ entrypoint_markers: ["http.HandleFunc", "http.ListenAndServe", "ServeMux", "http.Handler", "func(w http.ResponseWriter"]
9
+ logic_layers: ["*/service/*.go", "*/services/*.go", "*/usecase/*.go", "*/repository/*.go", "*/repo/*.go", "*/store/*.go", "*/dao/*.go", "*/model/*.go", "*/models/*.go"]
10
+ ---
11
+ # Go Review Notes
12
+
13
+ Where untrusted input enters beyond web routes, which the framework guides cover.
14
+ The standard `net/http` server is itself an entrypoint: a handler that takes an
15
+ `http.ResponseWriter` and an `*http.Request`, registered with `http.HandleFunc`
16
+ or a `ServeMux`. Read the request through `r.URL.Query`, `r.FormValue`, `r.PathValue`,
17
+ `r.Header`, and the decoded body, all attacker-controlled.
18
+
19
+ ## Common Sinks
20
+ - SQL: a query built with `fmt.Sprintf` or string concatenation passed to
21
+ `db.Query` or `db.Exec`. Use placeholders, never build SQL from input.
22
+ - Command: `exec.Command` with a shell or with arguments built from input,
23
+ `os/exec` reaching `sh -c`.
24
+ - Path: `filepath.Join` or `os.Open` on a path from input with no `filepath.Clean`
25
+ and containment check, the traversal sink.
26
+ - SSRF: `http.Get`, `http.NewRequest`, or a client `Do` on a URL from input.
27
+ - Deserialization and templates: `encoding/gob`, `text/template` rendering input,
28
+ and `html/template` used with the wrong escaping context.
29
+
30
+ ## Gotchas
31
+ - Errors ignored with `_` can skip a security check whose failure is never seen.
32
+ - A type assertion or `interface{}` body decoded with `json.Unmarshal` into a
33
+ wide struct is mass assignment if privileged fields are bound.
34
+ - Goroutines and shared state without a lock are a race, relevant to one-time
35
+ tokens and balances.