codejury 0.17.1__tar.gz → 0.18.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 (94) hide show
  1. codejury-0.18.0/PKG-INFO +147 -0
  2. codejury-0.18.0/README.md +116 -0
  3. {codejury-0.17.1 → codejury-0.18.0}/codejury/__init__.py +3 -2
  4. {codejury-0.17.1 → codejury-0.18.0}/codejury/cli.py +1 -1
  5. codejury-0.18.0/codejury/data/frameworks/python/celery.md +36 -0
  6. {codejury-0.17.1/codejury/data/frameworks → codejury-0.18.0/codejury/data/frameworks/python}/django.md +9 -7
  7. {codejury-0.17.1 → codejury-0.18.0}/codejury/data/languages/python.md +4 -4
  8. {codejury-0.17.1/codejury/data/methodology → codejury-0.18.0/codejury/data/methodologies}/repo-review.md +66 -36
  9. {codejury-0.17.1/codejury/data/methodology → codejury-0.18.0/codejury/data/methodologies}/security-review-memory.md +4 -4
  10. codejury-0.18.0/codejury/data/protocols/oauth.md +55 -0
  11. codejury-0.18.0/codejury/data/vulnerabilities/SKILL.md +59 -0
  12. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/code-injection.md +1 -1
  13. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/cross-site-request-forgery.md +1 -1
  14. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/cross-site-scripting.md +1 -1
  15. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/http-response-splitting.md +1 -1
  16. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/improper-authentication.md +1 -1
  17. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/information-exposure.md +5 -5
  18. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/insecure-cryptography.md +1 -1
  19. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/insecure-deserialization.md +1 -1
  20. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/insecure-direct-object-reference.md +2 -2
  21. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/insecure-transport.md +1 -1
  22. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/mass-assignment.md +1 -1
  23. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/open-redirect.md +1 -1
  24. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/path-traversal.md +3 -3
  25. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/race-condition.md +3 -3
  26. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/replay-attack.md +1 -1
  27. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/server-side-request-forgery.md +2 -2
  28. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/server-side-template-injection.md +3 -3
  29. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/session-fixation.md +2 -2
  30. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/sql-injection.md +1 -1
  31. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/xml-external-entity.md +2 -2
  32. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/debate.py +6 -6
  33. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/debate_prompts.py +7 -7
  34. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/engine.py +5 -5
  35. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/prompts.py +5 -5
  36. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/runner.py +1 -1
  37. codejury-0.18.0/codejury/diff/vulnerabilities.py +75 -0
  38. {codejury-0.17.1 → codejury-0.18.0}/codejury/domain/__init__.py +1 -1
  39. {codejury-0.17.1 → codejury-0.18.0}/codejury/guides.py +35 -11
  40. {codejury-0.17.1 → codejury-0.18.0}/codejury/mddoc.py +10 -8
  41. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/__init__.py +1 -1
  42. codejury-0.18.0/codejury/repo/model.py +106 -0
  43. {codejury-0.17.1 → codejury-0.18.0}/codejury/repo/scaffold.py +48 -10
  44. {codejury-0.17.1 → codejury-0.18.0}/codejury/resources.py +3 -2
  45. codejury-0.18.0/codejury.egg-info/PKG-INFO +147 -0
  46. codejury-0.18.0/codejury.egg-info/SOURCES.txt +85 -0
  47. {codejury-0.17.1 → codejury-0.18.0}/pyproject.toml +1 -1
  48. {codejury-0.17.1 → codejury-0.18.0}/tests/test_diff_engine.py +2 -2
  49. {codejury-0.17.1 → codejury-0.18.0}/tests/test_guides.py +19 -3
  50. {codejury-0.17.1 → codejury-0.18.0}/tests/test_repo_model.py +14 -3
  51. {codejury-0.17.1 → codejury-0.18.0}/tests/test_repo_scaffold.py +1 -1
  52. codejury-0.17.1/tests/test_rules.py → codejury-0.18.0/tests/test_vulnerabilities.py +31 -31
  53. codejury-0.17.1/PKG-INFO +0 -135
  54. codejury-0.17.1/README.md +0 -104
  55. codejury-0.17.1/codejury/data/rules/SKILL.md +0 -58
  56. codejury-0.17.1/codejury/diff/rules.py +0 -74
  57. codejury-0.17.1/codejury/repo/model.py +0 -61
  58. codejury-0.17.1/codejury.egg-info/PKG-INFO +0 -135
  59. codejury-0.17.1/codejury.egg-info/SOURCES.txt +0 -83
  60. {codejury-0.17.1 → codejury-0.18.0}/LICENSE +0 -0
  61. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/business-logic.md +0 -0
  62. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/command-injection.md +0 -0
  63. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/hardcoded-secrets.md +0 -0
  64. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/jwt-validation.md +0 -0
  65. {codejury-0.17.1/codejury/data/rules → codejury-0.18.0/codejury/data/vulnerabilities}/missing-authorization.md +0 -0
  66. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/__init__.py +0 -0
  67. {codejury-0.17.1 → codejury-0.18.0}/codejury/diff/findings_filter.py +0 -0
  68. {codejury-0.17.1 → codejury-0.18.0}/codejury/domain/finding.py +0 -0
  69. {codejury-0.17.1 → codejury-0.18.0}/codejury/json_parse.py +0 -0
  70. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/anthropic.py +0 -0
  71. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/base.py +0 -0
  72. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/factory.py +0 -0
  73. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/litellm.py +0 -0
  74. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/mock.py +0 -0
  75. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/openai.py +0 -0
  76. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/openai_format.py +0 -0
  77. {codejury-0.17.1 → codejury-0.18.0}/codejury/providers/retry.py +0 -0
  78. {codejury-0.17.1 → codejury-0.18.0}/codejury/repo/__init__.py +0 -0
  79. {codejury-0.17.1 → codejury-0.18.0}/codejury/report.py +0 -0
  80. {codejury-0.17.1 → codejury-0.18.0}/codejury.egg-info/dependency_links.txt +0 -0
  81. {codejury-0.17.1 → codejury-0.18.0}/codejury.egg-info/entry_points.txt +0 -0
  82. {codejury-0.17.1 → codejury-0.18.0}/codejury.egg-info/requires.txt +0 -0
  83. {codejury-0.17.1 → codejury-0.18.0}/codejury.egg-info/top_level.txt +0 -0
  84. {codejury-0.17.1 → codejury-0.18.0}/setup.cfg +0 -0
  85. {codejury-0.17.1 → codejury-0.18.0}/tests/test_anthropic_provider.py +0 -0
  86. {codejury-0.17.1 → codejury-0.18.0}/tests/test_cli_audit.py +0 -0
  87. {codejury-0.17.1 → codejury-0.18.0}/tests/test_diff_debate.py +0 -0
  88. {codejury-0.17.1 → codejury-0.18.0}/tests/test_json_parse.py +0 -0
  89. {codejury-0.17.1 → codejury-0.18.0}/tests/test_litellm_provider.py +0 -0
  90. {codejury-0.17.1 → codejury-0.18.0}/tests/test_mddoc.py +0 -0
  91. {codejury-0.17.1 → codejury-0.18.0}/tests/test_openai_format.py +0 -0
  92. {codejury-0.17.1 → codejury-0.18.0}/tests/test_openai_provider.py +0 -0
  93. {codejury-0.17.1 → codejury-0.18.0}/tests/test_report.py +0 -0
  94. {codejury-0.17.1 → codejury-0.18.0}/tests/test_retry_provider.py +0 -0
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: codejury
3
+ Version: 0.18.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,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,15 @@
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("]
10
12
  ---
11
- # Django review notes
13
+ # Django Review Notes
12
14
 
13
15
  ## Entrypoints
14
16
  - Routes live in `urls.py`: `path()` / `re_path()` map a URL to a view.
@@ -18,14 +20,14 @@ entrypoint_files: ["*urls.py"]
18
20
  signals, and middleware.
19
21
 
20
22
  ## Authorization / IDOR
21
- - Auth is enforced by decorators (`@login_required`), DRF permission classes, or
23
+ - Auth is enforced by decorators such as `@login_required`, DRF permission classes, or
22
24
  middleware. Note where it is and where it is missing.
23
- - Classic IDOR shape: `Model.objects.get(pk=<user input>)` (or `filter(id=...)`)
25
+ - Classic IDOR shape: `Model.objects.get(pk=<user input>)` or `filter(id=...)`
24
26
  with no owner/tenant scoping, then returned to the caller. Inspect every object
25
27
  fetch keyed by a user-supplied id.
26
28
 
27
- ## Common sinks / gotchas
29
+ ## Common Sinks / Gotchas
28
30
  - SQL: `.raw()`, `.extra()`, `RawSQL`, or string-built SQL via `connection.cursor()`.
29
31
  - 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`.
32
+ - Settings: `DEBUG=True` leaks internals, a hardcoded `SECRET_KEY`. Untrusted
33
+ deserialization is a language-level sink, see the Python guide.
@@ -7,17 +7,17 @@ detect:
7
7
  manifest: []
8
8
  imports: []
9
9
  ---
10
- # Python review notes
10
+ # Python Review Notes
11
11
 
12
- Where untrusted input enters (beyond web routes, which the framework guide covers):
13
- CLI (`argparse`/`click`), scheduled jobs, queue consumers, and any function fed an
12
+ Where untrusted input enters beyond web routes, which the framework guide covers:
13
+ CLI such as `argparse` or `click`, scheduled jobs, queue consumers, and any function fed an
14
14
  external value. Non-HTTP sources matter as much as routes:
15
15
 
16
16
  - deserialization: `pickle.loads`, `yaml.load` without `SafeLoader`, `marshal`
17
17
  - code execution: `eval`, `exec`, `subprocess(..., shell=True)`, `os.system`
18
18
  - XML/XXE: `lxml`/`xml.etree` parsing attacker XML
19
19
  - filesystem: `open()` / `os.path.join` on a path built from user input
20
- - network: `requests.get(user_url)` and friends (SSRF).
20
+ - network: `requests.get(user_url)` and similar, the SSRF sink.
21
21
 
22
22
  Common sinks: string-built SQL handed to a DB cursor or ORM `.raw()`/`.extra()`,
23
23
  a shell command, `eval`/`exec`, a user-controlled file path, a fetch of a
@@ -7,47 +7,54 @@ PoC, and iterates over multiple rounds with a persistent memory. One round is
7
7
  roughly 30 minutes. Run as many rounds as needed.
8
8
 
9
9
  Target repository: the directory you were given.
10
- Workspace: `<workspace>/<project>/` (created for you), holding `entrypoints/`,
10
+ Workspace: `<workspace>/<project>/`, created for you, holding `entrypoints/`,
11
11
  `issues/`, `analysis/`, and `security-review-memory.md`.
12
12
 
13
13
  ---
14
14
 
15
- ## On start
15
+ ## On Start
16
16
 
17
17
  1. Read `security-review-memory.md` in the workspace if it exists:
18
18
  - skip every pattern under "Confirmed false positives".
19
19
  - do not re-report anything under "Fixed".
20
20
  - weight the files under "High-risk areas" more heavily.
21
- 2. Read `entrypoints/_entrypoints.md` (seeded): the files the detected stack
21
+ 2. Read `entrypoints/_entrypoints.md`, the seeded list of files the detected stack
22
22
  flags as likely to define entrypoints. Open them to find the actual
23
- entrypoints. It is a *starting* subset, not the whole surface (see "Map the
24
- attack surface").
25
- 3. Read `_stack.md` (seeded): the detected languages and frameworks and review
26
- notes for them, so you know where this stack's entrypoints, sinks, and auth
27
- checks live. If it matched nothing, lean on your own knowledge of the stack.
28
- 4. Read the relevant rule files under the shipped `rules/` for the target's stack
29
- (sql-injection, idor, ssrf, authentication-jwt, insecure-deserialization, ...).
30
-
31
- ## Map the attack surface
32
-
33
- The seeded inventory lists HTTP routes and CLI commands only. Before analysing,
34
- complete the surface: untrusted input enters at more than HTTP. Enumerate every
35
- source the attacker can influence and add it to `entrypoints/`:
23
+ entrypoints. It is a *starting* subset, not the whole surface. See "Map the
24
+ attack surface".
25
+ 3. Read `_stack.md`, the seeded detected languages, frameworks, and protocols plus
26
+ review notes for them, so you know where this stack's entrypoints and sinks
27
+ live and which protocol checks apply, for example the OAuth checklist. If it
28
+ matched nothing, lean on your own knowledge of the stack.
29
+ 4. Read the relevant vulnerability files under the shipped `vulnerabilities/` for
30
+ the target's stack such as sql-injection, idor, ssrf, jwt-validation, or
31
+ insecure-deserialization.
32
+
33
+ ## Map the Attack Surface
34
+
35
+ The seeded `entrypoints/_entrypoints.md` flags files that likely define
36
+ entrypoints. It is a starting point, not the whole surface. Before any per-source
37
+ analysis, build a COMPLETE inventory: open every flagged file, read its routes
38
+ and handlers, and enumerate every source the attacker can influence, including
39
+ the ones no scan finds. Untrusted input enters at more than HTTP:
36
40
 
37
41
  - HTTP routes, GraphQL resolvers, gRPC / RPC handlers, WebSocket handlers.
38
42
  - CLI commands, scheduled jobs / cron, queue and topic consumers, webhooks and
39
43
  third-party callbacks.
40
- - deserialization points (pickle, yaml.load, marshal), file and document parsers
41
- (XML / XXE, YAML, CSV, zip, image / office), template rendering of user input.
44
+ - deserialization points such as pickle, yaml.load, or marshal, file and document parsers
45
+ for XML / XXE, YAML, CSV, zip, image / office, and template rendering of user input.
42
46
  - file uploads, archive extraction, and any filesystem path built from user input.
43
47
  - headers, cookies, environment, and config read as trusted, and inbound
44
48
  inter-service calls.
45
49
 
46
50
  `pickle.loads(cookie)` and `yaml.load(upload)` are entrypoints just as much as a
47
- route is. Record the inventory in `entrypoints/` (one file per module: source +
48
- auth method + review status ✅/⚠️/❌).
51
+ route is. Record the full inventory in `entrypoints/`, one file per module, each
52
+ listing the source, the auth method, and a review status ✅/⚠️/❌. Do not begin
53
+ per-source analysis until the inventory covers every endpoint, since an endpoint
54
+ you never list is one you never review. This single step is what most decides
55
+ whether the review finds the deep issues.
49
56
 
50
- ## Analyse each source
57
+ ## Analyse Each Source
51
58
 
52
59
  Read the implementation reachable from each source. For every one ask:
53
60
 
@@ -56,22 +63,43 @@ Read the implementation reachable from each source. For every one ask:
56
63
  a business-state check bypassed or missing?
57
64
  - IDOR: can a user reach another user's, tenant's, or service's resource by a
58
65
  supplied id?
59
- - Do privileged operations (payment, signing, approval, state change) allow state
60
- bypass or replay (no nonce / time window)?
66
+ - Do privileged operations such as payment, signing, approval, or state change allow state
67
+ bypass or replay with no nonce or time window?
61
68
  - Mass assignment: is a user-controlled body bound wholesale into a model?
62
69
  - Signature: is a caller-supplied key trusted as the trust anchor?
63
70
 
64
- ## Trace attack paths, the core work
71
+ ## Authorization Model
72
+
73
+ The missing-authorization and IDOR classes are not local to one function, so they
74
+ need their own pass. This step is language and framework agnostic. The access
75
+ gate looks different per stack, a decorator, a middleware, a permission class, a
76
+ filter, a guard, or an annotation, but every protected endpoint must authenticate
77
+ the caller and authorize the specific resource.
78
+
79
+ First map how this codebase enforces access control, then record on each
80
+ inventory entry which gate it applies and which identity and resource it checks.
81
+ Then hunt three shapes:
82
+
83
+ - A peer that dropped a check. Compare sibling endpoints such as a v1 and a v2, a
84
+ batch and a single, or an admin and a public variant. When one applies an
85
+ ownership or permission check that a sibling omits, the sibling is a likely
86
+ flaw.
87
+ - IDOR. An endpoint acts on a resource named by a client-supplied id with no
88
+ owner or tenant check, however the id arrives.
89
+ - An unauthenticated privileged path. A state-changing or sensitive endpoint is
90
+ reachable without the gate its peers require.
91
+
92
+ ## Trace Attack Paths, the Core Work
65
93
 
66
94
  A whole-repo review earns its keep by reasoning *across files*: a flaw is usually
67
95
  a source in one file reaching a dangerous sink in another, past a control defined
68
- in a third (a route that trusts a helper which skips signature checks, an id that
69
- reaches a query with no ownership check). For each promising source, trace the
96
+ in a third, for example a route that trusts a helper which skips signature checks, or an id that
97
+ reaches a query with no ownership check. For each promising source, trace the
70
98
  path and record it in `analysis/`:
71
99
 
72
100
  - **Source**: the entrypoint and the attacker-controlled value.
73
- - **Sink**: the dangerous operation it reaches (query, shell, file path, fetch,
74
- deserialize, template, redirect), with `file:line`.
101
+ - **Sink**: the dangerous operation it reaches such as a query, shell, file path, fetch,
102
+ deserialize, template, or redirect, with `file:line`.
75
103
  - **Controls on the path**: every auth / authz / validation / sanitization /
76
104
  signature / tenant check between source and sink, and crucially which are
77
105
  missing or bypassable.
@@ -83,11 +111,11 @@ trace can refer to it instead of restating it.
83
111
  ## Scope
84
112
 
85
113
  Report only HIGH / CRITICAL, exploitable, high-confidence issues. **Do not report**
86
- (regardless of severity): dependency CVEs, style or best-practice notes,
114
+ regardless of severity, dependency CVEs, style or best-practice notes,
87
115
  speculative issues you cannot tie to a concrete exploit, and risks that only
88
116
  matter if production config is leaked.
89
117
 
90
- ## Recording an issue
118
+ ## Recording an Issue
91
119
 
92
120
  Write one `issues/<name>.md` per confirmed issue. Do not write an issue you cannot
93
121
  confirm with high confidence. Each must have:
@@ -102,7 +130,7 @@ confirm with high confidence. Each must have:
102
130
  ## Analysis
103
131
  (cite exact file paths and line numbers)
104
132
 
105
- ## Attack path
133
+ ## Attack Path
106
134
  (end-to-end, actionable steps)
107
135
 
108
136
  ## PoC
@@ -114,7 +142,7 @@ confirm with high confidence. Each must have:
114
142
  ## Fix
115
143
  ```
116
144
 
117
- ## PoC verification (human in the loop)
145
+ ## PoC Verification, Human in the Loop
118
146
 
119
147
  Confirm each issue by running the PoC against a sandbox / dev environment. When
120
148
  you need something only the operator has, stop and ask:
@@ -129,11 +157,13 @@ destructive action without the operator's explicit go-ahead.
129
157
  ## Iteration
130
158
 
131
159
  Each round, read the workspace history first and do not repeat finished work.
132
- Process leftover TODOs, otherwise pick an unreviewed () or to-deepen (⚠️)
133
- source from the inventory. When every source is and there are no TODOs,
134
- report the review complete.
160
+ Process leftover TODOs, otherwise pick an unreviewed ❌ or to-deepen ⚠️ source
161
+ from the inventory. One round rarely finds the deep cross-file and stateful bugs,
162
+ so keep going until two consecutive rounds surface nothing new, then report the
163
+ review complete. The hard classes such as authorization, replay, and broken
164
+ business state usually appear only after several rounds.
135
165
 
136
- ## On finish
166
+ ## On Finish
137
167
 
138
168
  Append a row to the audit history in `security-review-memory.md`, and ask the
139
169
  operator which findings were false positives. Record those under "Confirmed false
@@ -4,7 +4,7 @@
4
4
  > updated at the end. It skips confirmed false positives, avoids re-reporting
5
5
  > fixed issues, and focuses on historically risky areas.
6
6
 
7
- ## Confirmed false positives (skip, do not report)
7
+ ## Confirmed False Positives
8
8
 
9
9
  <!-- FP-001 <short description>
10
10
  - Date: YYYY-MM-DD
@@ -13,18 +13,18 @@
13
13
  - Why not a real issue: <reason>
14
14
  -->
15
15
 
16
- ## Fixed (do not report again)
16
+ ## Fixed
17
17
 
18
18
  <!-- FIXED-001 <issue title>
19
19
  - Date / commit: YYYY-MM-DD / abc1234
20
20
  - Original issue: <summary>
21
21
  -->
22
22
 
23
- ## High-risk areas (weight every round)
23
+ ## High-Risk Areas
24
24
 
25
25
  <!-- - `<path>`: <reason, for example a past auth bypass> -->
26
26
 
27
- ## Audit history
27
+ ## Audit History
28
28
 
29
29
  | Date | Mode | HIGH | MEDIUM | Notes |
30
30
  |------|------|------|--------|-------|
@@ -0,0 +1,55 @@
1
+ ---
2
+ id: oauth
3
+ title: OAuth and OIDC
4
+ kind: protocol
5
+ detect:
6
+ content: ["grant_type", "authorization_code", "redirect_uri", "code_challenge", "response_type", "client_secret", "openid-configuration"]
7
+ ---
8
+ # OAuth and OIDC Review Notes
9
+
10
+ These are protocol invariants, independent of language or framework. The way each
11
+ check looks in code differs by stack, so read the language and framework guides
12
+ for the concrete idioms and confirm each invariant against the actual flow. An
13
+ OAuth or OIDC server holds protocol state, so the high-value bugs are logic,
14
+ authorization, and replay flaws rather than injection.
15
+
16
+ ## Authorization Code
17
+ - Single use. The code is redeemable once. The redeem path reads and marks the
18
+ code consumed atomically, under a row lock or an equivalent conditional update,
19
+ so two concurrent requests cannot both succeed. A read then update with no lock
20
+ is a double-redeem.
21
+ - Bound to the client. A code issued to one client is rejected when another
22
+ client presents it. The token step compares the code's client to the
23
+ authenticated client.
24
+ - Bound to the redirect_uri and the PKCE verifier. Both at the token step match
25
+ what was used at authorize. A missing PKCE check on a public client is
26
+ exploitable.
27
+ - Expiry enforced. An expired code is rejected. Confirm the expiry is read and
28
+ compared, not merely stored.
29
+
30
+ ## redirect_uri and State
31
+ - redirect_uri is validated against a registered allowlist by exact match, not a
32
+ prefix or a substring, so an open redirect or a code leak is not possible.
33
+ - A state or equivalent anti-forgery value is present and checked, to stop login
34
+ CSRF.
35
+
36
+ ## Tokens and Sessions
37
+ - Access and refresh tokens are random, high entropy, scoped, and expiring.
38
+ - Refresh rotates and the previous token is revoked, so a captured refresh cannot
39
+ be replayed.
40
+ - A JWT access token has its signature, algorithm, issuer, audience, and expiry
41
+ verified. Disabling signature verification or allowing an unconstrained
42
+ algorithm is a flaw. See the jwt-validation vulnerability class.
43
+
44
+ ## Replay and Signatures
45
+ - A signed or one-time request such as an MFA binding, a webhook, or a privileged
46
+ action carries a nonce or a short timestamp window and a single-use check, so a
47
+ captured request cannot be replayed. See the replay-attack vulnerability class.
48
+
49
+ ## Authorization per Endpoint
50
+ - Every token, introspection, revocation, and management endpoint authenticates
51
+ the caller and authorizes the specific resource. Watch for an endpoint that
52
+ acts on a client-supplied id with no owner or tenant check, the IDOR shape, and
53
+ for a privileged endpoint left unauthenticated. See the
54
+ insecure-direct-object-reference and missing-authorization vulnerability classes,
55
+ and the Authorization Model step in the methodology.