codepathfinder 1.2.0__py3-none-manylinux_2_17_aarch64.whl

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.
@@ -0,0 +1,250 @@
1
+ """
2
+ Taint propagation primitives for dataflow analysis.
3
+
4
+ These primitives define HOW taint propagates through code constructs.
5
+ Developers specify which primitives to enable via propagates_through parameter.
6
+ """
7
+
8
+ from typing import Dict, Any, List, Optional
9
+ from enum import Enum
10
+
11
+
12
+ class PropagationType(Enum):
13
+ """
14
+ Enum of all propagation primitive types.
15
+
16
+ Phase 1 (MVP - This PR):
17
+ ASSIGNMENT, FUNCTION_ARGS, FUNCTION_RETURNS
18
+
19
+ Phase 2 (MVP - Future PR):
20
+ STRING_CONCAT, STRING_FORMAT
21
+
22
+ Phase 3-6 (Post-MVP):
23
+ Collections, control flow, OOP, advanced
24
+ """
25
+
26
+ # ===== PHASE 1: BARE MINIMUM (MVP) =====
27
+ ASSIGNMENT = "assignment"
28
+ FUNCTION_ARGS = "function_args"
29
+ FUNCTION_RETURNS = "function_returns"
30
+
31
+ # ===== PHASE 2: STRING OPERATIONS (MVP - Future PR) =====
32
+ STRING_CONCAT = "string_concat"
33
+ STRING_FORMAT = "string_format"
34
+
35
+ # ===== PHASE 3: COLLECTIONS (POST-MVP) =====
36
+ LIST_APPEND = "list_append"
37
+ LIST_EXTEND = "list_extend"
38
+ DICT_VALUES = "dict_values"
39
+ DICT_UPDATE = "dict_update"
40
+ SET_ADD = "set_add"
41
+
42
+ # ===== PHASE 4: CONTROL FLOW (POST-MVP) =====
43
+ IF_CONDITION = "if_condition"
44
+ FOR_ITERATION = "for_iteration"
45
+ WHILE_CONDITION = "while_condition"
46
+ SWITCH_CASE = "switch_case"
47
+
48
+ # ===== PHASE 5: OOP (POST-MVP) =====
49
+ ATTRIBUTE_ASSIGNMENT = "attribute_assignment"
50
+ METHOD_CALL = "method_call"
51
+ CONSTRUCTOR = "constructor"
52
+
53
+ # ===== PHASE 6: ADVANCED (POST-MVP) =====
54
+ COMPREHENSION = "comprehension"
55
+ LAMBDA_CAPTURE = "lambda_capture"
56
+ YIELD_STMT = "yield_stmt"
57
+
58
+
59
+ class PropagationPrimitive:
60
+ """
61
+ Base class for propagation primitives.
62
+
63
+ Each primitive describes ONE way taint can flow through code.
64
+ """
65
+
66
+ def __init__(
67
+ self, prim_type: PropagationType, metadata: Optional[Dict[str, Any]] = None
68
+ ):
69
+ """
70
+ Args:
71
+ prim_type: The type of propagation
72
+ metadata: Optional additional configuration
73
+ """
74
+ self.type = prim_type
75
+ self.metadata = metadata or {}
76
+
77
+ def to_ir(self) -> Dict[str, Any]:
78
+ """
79
+ Serialize to JSON IR.
80
+
81
+ Returns:
82
+ {
83
+ "type": "assignment",
84
+ "metadata": {}
85
+ }
86
+ """
87
+ return {
88
+ "type": self.type.value,
89
+ "metadata": self.metadata,
90
+ }
91
+
92
+ def __repr__(self) -> str:
93
+ return f"propagates.{self.type.value}()"
94
+
95
+
96
+ class propagates:
97
+ """
98
+ Namespace for taint propagation primitives.
99
+
100
+ Usage:
101
+ propagates.assignment()
102
+ propagates.function_args()
103
+ propagates.function_returns()
104
+ """
105
+
106
+ # ===== PHASE 1: BARE MINIMUM (MVP - THIS PR) =====
107
+
108
+ @staticmethod
109
+ def assignment() -> PropagationPrimitive:
110
+ """
111
+ Taint propagates through variable assignment.
112
+
113
+ Patterns matched:
114
+ x = tainted # Simple assignment
115
+ a = b = tainted # Chained assignment
116
+ x, y = tainted, safe # Tuple unpacking (x is tainted)
117
+
118
+ This is the MOST COMMON propagation pattern (~40% of all flows).
119
+
120
+ Examples:
121
+ user_input = request.GET.get("id") # source
122
+ query = user_input # PROPAGATES via assignment
123
+ cursor.execute(query) # sink
124
+
125
+ Returns:
126
+ PropagationPrimitive for assignment
127
+ """
128
+ return PropagationPrimitive(PropagationType.ASSIGNMENT)
129
+
130
+ @staticmethod
131
+ def function_args() -> PropagationPrimitive:
132
+ """
133
+ Taint propagates through function arguments.
134
+
135
+ Patterns matched:
136
+ func(tainted) # Positional argument
137
+ func(arg=tainted) # Keyword argument
138
+ func(*tainted) # Args unpacking
139
+ func(**tainted) # Kwargs unpacking
140
+
141
+ Critical for inter-procedural analysis (~30% of flows).
142
+
143
+ Examples:
144
+ user_input = request.GET.get("id") # source
145
+ process_data(user_input) # PROPAGATES via function_args
146
+ def process_data(data):
147
+ execute(data) # sink (data is tainted)
148
+
149
+ Returns:
150
+ PropagationPrimitive for function arguments
151
+ """
152
+ return PropagationPrimitive(PropagationType.FUNCTION_ARGS)
153
+
154
+ @staticmethod
155
+ def function_returns() -> PropagationPrimitive:
156
+ """
157
+ Taint propagates through return values.
158
+
159
+ Patterns matched:
160
+ return tainted # Direct return
161
+ return tainted if cond else safe # Conditional return
162
+ return [tainted, safe] # Return list containing tainted
163
+
164
+ Essential for functions that transform tainted data (~20% of flows).
165
+
166
+ Examples:
167
+ def get_user_id():
168
+ user_input = request.GET.get("id") # source
169
+ return user_input # PROPAGATES via return
170
+
171
+ query = get_user_id() # query is now tainted
172
+ execute(query) # sink
173
+
174
+ Returns:
175
+ PropagationPrimitive for function returns
176
+ """
177
+ return PropagationPrimitive(PropagationType.FUNCTION_RETURNS)
178
+
179
+ # ===== PHASE 2: STRING OPERATIONS (MVP - THIS PR) =====
180
+
181
+ @staticmethod
182
+ def string_concat() -> PropagationPrimitive:
183
+ """
184
+ Taint propagates through string concatenation.
185
+
186
+ Patterns matched:
187
+ result = tainted + "suffix" # Right concat
188
+ result = "prefix" + tainted # Left concat
189
+ result = tainted + safe + more # Mixed concat
190
+
191
+ Critical for SQL/Command injection where queries are built via concat (~10% of flows).
192
+
193
+ Examples:
194
+ user_id = request.GET.get("id") # source
195
+ query = "SELECT * FROM users WHERE id = " + user_id # PROPAGATES via string_concat
196
+ cursor.execute(query) # sink
197
+
198
+ Returns:
199
+ PropagationPrimitive for string concatenation
200
+ """
201
+ return PropagationPrimitive(PropagationType.STRING_CONCAT)
202
+
203
+ @staticmethod
204
+ def string_format() -> PropagationPrimitive:
205
+ """
206
+ Taint propagates through string formatting.
207
+
208
+ Patterns matched:
209
+ f"{tainted}" # f-string
210
+ "{}".format(tainted) # str.format()
211
+ "%s" % tainted # % formatting
212
+ "{name}".format(name=tainted) # Named placeholders
213
+
214
+ Critical for SQL injection where ORM methods use format() (~8% of flows).
215
+
216
+ Examples:
217
+ user_id = request.GET.get("id") # source
218
+ query = f"SELECT * FROM users WHERE id = {user_id}" # PROPAGATES via string_format
219
+ cursor.execute(query) # sink
220
+
221
+ Returns:
222
+ PropagationPrimitive for string formatting
223
+ """
224
+ return PropagationPrimitive(PropagationType.STRING_FORMAT)
225
+
226
+ # ===== PHASE 3-6: POST-MVP =====
227
+ # Will be implemented in post-MVP PRs
228
+
229
+
230
+ def create_propagation_list(
231
+ primitives: List[PropagationPrimitive],
232
+ ) -> List[Dict[str, Any]]:
233
+ """
234
+ Convert a list of propagation primitives to JSON IR.
235
+
236
+ Args:
237
+ primitives: List of PropagationPrimitive objects
238
+
239
+ Returns:
240
+ List of JSON IR dictionaries
241
+
242
+ Example:
243
+ >>> prims = [propagates.assignment(), propagates.function_args()]
244
+ >>> create_propagation_list(prims)
245
+ [
246
+ {"type": "assignment", "metadata": {}},
247
+ {"type": "function_args", "metadata": {}}
248
+ ]
249
+ """
250
+ return [prim.to_ir() for prim in primitives]
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.4
2
+ Name: codepathfinder
3
+ Version: 1.2.0
4
+ Summary: Python SDK for code-pathfinder static analysis for modern security teams
5
+ Home-page: https://github.com/shivasurya/code-pathfinder
6
+ Author: code-pathfinder contributors
7
+ License: AGPL-3.0
8
+ Project-URL: Homepage, https://codepathfinder.dev
9
+ Project-URL: Repository, https://github.com/shivasurya/code-pathfinder
10
+ Project-URL: Documentation, https://codepathfinder.dev
11
+ Keywords: sast,security,static-analysis,codeql-alternative
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: Software Development :: Testing
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
28
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
29
+ Requires-Dist: black>=23.0.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
31
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
32
+ Dynamic: home-page
33
+ Dynamic: license-file
34
+ Dynamic: requires-python
35
+
36
+ # Code-Pathfinder Python DSL
37
+
38
+ Python DSL for defining security patterns in Code Pathfinder - an open-source security suite combining structural code analysis with AI-powered vulnerability detection.
39
+
40
+ **Project Goals:**
41
+ - Real-time IDE integration bringing security insights directly into your editor
42
+ - AI-assisted analysis leveraging LLMs to understand context and identify vulnerabilities
43
+ - Unified workflow coverage from local development to CI/CD pipelines
44
+ - Flexible reporting supporting DefectDojo, GitHub Advanced Security, SARIF, and other platforms
45
+
46
+ **Documentation**: https://codepathfinder.dev/
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install codepathfinder
52
+ ```
53
+
54
+ This installs **both** the Python DSL and the `pathfinder` CLI binary for your platform.
55
+
56
+ ### Verify Installation
57
+
58
+ ```bash
59
+ # Test CLI binary
60
+ pathfinder --version
61
+
62
+ # Test Python DSL
63
+ python -c "from codepathfinder import rule, calls; print('DSL OK')"
64
+ ```
65
+
66
+ ### Supported Platforms
67
+
68
+ - Linux (glibc): x86_64, aarch64
69
+ - macOS: arm64 (Apple Silicon), x86_64 (Intel)
70
+ - Windows: x86_64
71
+
72
+ Source distributions are available for other platforms - the binary will be downloaded automatically on first use.
73
+
74
+ ## Quick Example
75
+
76
+ ```python
77
+ from codepathfinder import rule, flows, calls
78
+ from codepathfinder.presets import PropagationPresets
79
+
80
+ @rule(id="sql-injection", severity="critical", cwe="CWE-89")
81
+ def detect_sql_injection():
82
+ """Detects SQL injection vulnerabilities"""
83
+ return flows(
84
+ from_sources=calls("request.GET", "request.POST"),
85
+ to_sinks=calls("execute", "executemany"),
86
+ sanitized_by=calls("quote_sql"),
87
+ propagates_through=PropagationPresets.standard(),
88
+ scope="global"
89
+ )
90
+ ```
91
+
92
+ ## Features
93
+
94
+ - **Matchers**: `calls()`, `variable()` for pattern matching
95
+ - **Dataflow Analysis**: `flows()` for source-to-sink taint tracking
96
+ - **Propagation**: Explicit propagation primitives (assignment, function args, returns)
97
+ - **Logic Operators**: `And()`, `Or()`, `Not()` for complex rules
98
+ - **JSON IR**: Serializes to JSON for Go executor integration
99
+
100
+ ## Documentation
101
+
102
+ For detailed documentation, visit https://codepathfinder.dev/
103
+
104
+ ## Requirements
105
+
106
+ - Python 3.8+
107
+ - No external dependencies (stdlib only!)
108
+
109
+ ## License
110
+
111
+ AGPL-3.0 - GNU Affero General Public License v3
@@ -0,0 +1,33 @@
1
+ codepathfinder/__init__.py,sha256=bezgVTNZB2NM-v5NBjrM2g8S1DKPDg9YQqHtqcd58i8,1194
2
+ codepathfinder/config.py,sha256=jx1Q5QnX2zJKKhai6ISwFIWh7h9M4o06bgZpyieGx98,2473
3
+ codepathfinder/dataflow.py,sha256=H2X3uCc4Srl5WzmjmAeICJggUFSZnNhn1WbrWP7g8Cc,6815
4
+ codepathfinder/decorators.py,sha256=KK-peMcpWdS9uxqjxYCO2xaALjZEDOJ2iVv6w1PzobU,4336
5
+ codepathfinder/ir.py,sha256=K0YfGSFZyysDRd8B-o9gnyou5R3EbwApPsK3qSjmDSE,2837
6
+ codepathfinder/logic.py,sha256=cA76-mhE_A7WmWQtZtufZWxMKSrI4Bt7avJRWi20ud4,2418
7
+ codepathfinder/matchers.py,sha256=mCWG_FWw_CizCsKsnV9IOMaWDdrdETb_bbEeS7uF-LA,7978
8
+ codepathfinder/presets.py,sha256=_EU2WNtMY5PfY1iRcoZuiLkzKRddvtdn6H8tSy1dzGw,3914
9
+ codepathfinder/propagation.py,sha256=yz1ODauUD0hnzDjPWfTIdQojWcvkYbwrnvou4C9Fy6U,7695
10
+ codepathfinder/bin/pathfinder,sha256=J9XWeFdgxbQfOlGb2_kTYyq9FXk_myW5ObwIoyC4qeo,9317592
11
+ codepathfinder/cli/__init__.py,sha256=ymnNkbFV4_HTbQR3nznrMxYWygFdptbtIpowWfQUOwk,6001
12
+ codepathfinder-1.2.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
13
+ rules/__init__.py,sha256=5f-EuZwvtJDUHXeZgMgbF8knpDgvKcCQRiLhXS1kehE,893
14
+ rules/container_combinators.py,sha256=nTW5ofz74_07b9_u3RnxYf5NW6ksqYhiAQNkH8-xJHs,6108
15
+ rules/container_decorators.py,sha256=UG_QwzbTNPnhyOEcYPQV1oj3cCDIrETooBT4tGbYbXk,5937
16
+ rules/container_ir.py,sha256=vq6i7OLLBSRZIVod7hcnQRu8dlB4WATI4fUz4ngKzrY,2609
17
+ rules/container_matchers.py,sha256=YcJQEdU8Pd7clTqjilykxqjajk-cineKli4uD3gsGQ0,7563
18
+ rules/container_programmatic.py,sha256=J5E65PC9DTZCgjBKYZzuXUXNECU0xSa8CBOqui6mlBE,3582
19
+ rules/python_decorators.py,sha256=s8mE1i5BEpdhaWo6EiRMUO1or-7aCC21zvhX6ai5cRo,4792
20
+ rules/python_ir.py,sha256=Rb_kcB6mhZz5l6089snpqQ00dRFFLanFSJVohl7iacc,2091
21
+ rules/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ rules/python/deserialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ rules/python/deserialization/pickle_loads.py,sha256=wGJkzbIZmf7Ph4MG9isbasU_a8nj6WCUulAaVmCgxCs,12621
24
+ rules/python/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ rules/python/django/sql_injection.py,sha256=eTWF2QbeJVcWxYenB9D0henvkd58-YY-U2qJ0bX_SPc,10868
26
+ rules/python/flask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ rules/python/flask/debug_mode.py,sha256=iJhFbIRt1IgDscV4f6rMiKmLur3mbSpZwHPI4pOsrvw,9913
28
+ rules/python/injection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ codepathfinder-1.2.0.dist-info/METADATA,sha256=kHz2QnrpksZ-3NUnpytQrOjW34jIZbovlTq63IiyZx0,3689
30
+ codepathfinder-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ codepathfinder-1.2.0.dist-info/entry_points.txt,sha256=WOhPEAAVEokrKiLCyYAfnLeJaZdDmSj-sf55yGjXdQo,55
32
+ codepathfinder-1.2.0.dist-info/top_level.txt,sha256=bh9z1--S2iWytMW5LQcsHYCynEMN0_7pdFCWEeeNqAU,21
33
+ codepathfinder-1.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pathfinder = codepathfinder.cli:main