apisec-code-bolt 0.1.0__py3-none-any.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.
- apisec_code_bolt/__init__.py +42 -0
- apisec_code_bolt/__main__.py +11 -0
- apisec_code_bolt/analysis/__init__.py +96 -0
- apisec_code_bolt/analysis/analyzer.py +2309 -0
- apisec_code_bolt/analysis/binding_tracker.py +341 -0
- apisec_code_bolt/analysis/call_graph.py +1197 -0
- apisec_code_bolt/analysis/call_graph_types.py +332 -0
- apisec_code_bolt/analysis/call_resolver.py +988 -0
- apisec_code_bolt/analysis/capability_tagger.py +322 -0
- apisec_code_bolt/analysis/config_scanner.py +197 -0
- apisec_code_bolt/analysis/data_flow.py +1883 -0
- apisec_code_bolt/analysis/dependency_extractor.py +959 -0
- apisec_code_bolt/analysis/flow_analysis.py +1406 -0
- apisec_code_bolt/analysis/hof_catalog.py +61 -0
- apisec_code_bolt/analysis/integration_detector.py +1399 -0
- apisec_code_bolt/analysis/literal_scanner.py +300 -0
- apisec_code_bolt/analysis/path_normalizer.py +55 -0
- apisec_code_bolt/analysis/read_site_detector.py +310 -0
- apisec_code_bolt/analysis/request_patterns.py +162 -0
- apisec_code_bolt/analysis/sensitivity_classifier.py +224 -0
- apisec_code_bolt/analysis/sink_evidence.py +333 -0
- apisec_code_bolt/analysis/url_prefix_resolver.py +338 -0
- apisec_code_bolt/cli/__init__.py +5 -0
- apisec_code_bolt/cli/exit_codes.py +17 -0
- apisec_code_bolt/cli/main.py +1069 -0
- apisec_code_bolt/cloud/__init__.py +1 -0
- apisec_code_bolt/cloud/apisec_client.py +118 -0
- apisec_code_bolt/cloud/client.py +255 -0
- apisec_code_bolt/core/__init__.py +75 -0
- apisec_code_bolt/core/config.py +528 -0
- apisec_code_bolt/core/credentials.py +65 -0
- apisec_code_bolt/core/discovery.py +433 -0
- apisec_code_bolt/core/log_format.py +115 -0
- apisec_code_bolt/core/manifest.py +1009 -0
- apisec_code_bolt/core/repo.py +280 -0
- apisec_code_bolt/core/state.py +59 -0
- apisec_code_bolt/core/telemetry.py +451 -0
- apisec_code_bolt/core/types.py +587 -0
- apisec_code_bolt/fingerprinting/__init__.py +1 -0
- apisec_code_bolt/frameworks/__init__.py +29 -0
- apisec_code_bolt/frameworks/_jwt_common.py +50 -0
- apisec_code_bolt/frameworks/auth_helpers.py +437 -0
- apisec_code_bolt/frameworks/base.py +608 -0
- apisec_code_bolt/frameworks/dotnet/__init__.py +17 -0
- apisec_code_bolt/frameworks/dotnet/_path_helpers.py +43 -0
- apisec_code_bolt/frameworks/dotnet/aspnet_plugin.py +2546 -0
- apisec_code_bolt/frameworks/dotnet/grpc_plugin.py +559 -0
- apisec_code_bolt/frameworks/dotnet/jwt_config_extractor.py +545 -0
- apisec_code_bolt/frameworks/dotnet/legacy_aspnet_plugin.py +732 -0
- apisec_code_bolt/frameworks/dotnet/refit_plugin.py +374 -0
- apisec_code_bolt/frameworks/dotnet/wcf_plugin.py +1239 -0
- apisec_code_bolt/frameworks/java/__init__.py +6 -0
- apisec_code_bolt/frameworks/java/_annotations.py +167 -0
- apisec_code_bolt/frameworks/java/_constraints.py +128 -0
- apisec_code_bolt/frameworks/java/graphql_plugin.py +287 -0
- apisec_code_bolt/frameworks/java/jaxrs_plugin.py +748 -0
- apisec_code_bolt/frameworks/java/jwt_config_extractor.py +361 -0
- apisec_code_bolt/frameworks/java/micronaut_plugin.py +1059 -0
- apisec_code_bolt/frameworks/java/spring_plugin.py +1293 -0
- apisec_code_bolt/frameworks/js/__init__.py +8 -0
- apisec_code_bolt/frameworks/js/express_plugin.py +391 -0
- apisec_code_bolt/frameworks/js/fastify_plugin.py +381 -0
- apisec_code_bolt/frameworks/js/graphql_plugin.py +198 -0
- apisec_code_bolt/frameworks/js/nestjs_plugin.py +423 -0
- apisec_code_bolt/frameworks/python/__init__.py +19 -0
- apisec_code_bolt/frameworks/python/celery_plugin.py +393 -0
- apisec_code_bolt/frameworks/python/click_plugin.py +427 -0
- apisec_code_bolt/frameworks/python/django_plugin.py +867 -0
- apisec_code_bolt/frameworks/python/fastapi/__init__.py +28 -0
- apisec_code_bolt/frameworks/python/fastapi/plugin.py +1390 -0
- apisec_code_bolt/frameworks/python/flask_plugin.py +205 -0
- apisec_code_bolt/frameworks/python/graphql_plugin.py +274 -0
- apisec_code_bolt/frameworks/python/prefect_plugin.py +251 -0
- apisec_code_bolt/frameworks/python/webhook_plugin.py +255 -0
- apisec_code_bolt/parsing/__init__.py +62 -0
- apisec_code_bolt/parsing/base.py +554 -0
- apisec_code_bolt/parsing/csharp/__init__.py +5 -0
- apisec_code_bolt/parsing/csharp/language_services.py +203 -0
- apisec_code_bolt/parsing/csharp/literals.py +72 -0
- apisec_code_bolt/parsing/csharp/parser.py +1158 -0
- apisec_code_bolt/parsing/csharp/type_resolver.py +568 -0
- apisec_code_bolt/parsing/js/__init__.py +5 -0
- apisec_code_bolt/parsing/js/language_services.py +118 -0
- apisec_code_bolt/parsing/js/parser.py +622 -0
- apisec_code_bolt/parsing/jvm/__init__.py +7 -0
- apisec_code_bolt/parsing/jvm/language_services.py +270 -0
- apisec_code_bolt/parsing/jvm/parser.py +774 -0
- apisec_code_bolt/parsing/jvm/type_resolver.py +422 -0
- apisec_code_bolt/parsing/python/__init__.py +150 -0
- apisec_code_bolt/parsing/python/cbv_extractor.py +606 -0
- apisec_code_bolt/parsing/python/constant_resolver.py +500 -0
- apisec_code_bolt/parsing/python/cross_file_resolver.py +1054 -0
- apisec_code_bolt/parsing/python/dynamic_route_detector.py +532 -0
- apisec_code_bolt/parsing/python/expression_utils.py +221 -0
- apisec_code_bolt/parsing/python/extraction_types.py +271 -0
- apisec_code_bolt/parsing/python/language_services.py +487 -0
- apisec_code_bolt/parsing/python/parameter_analyzer.py +789 -0
- apisec_code_bolt/parsing/python/parser.py +719 -0
- apisec_code_bolt/parsing/python/path_resolver.py +576 -0
- apisec_code_bolt/parsing/python/router_registry.py +806 -0
- apisec_code_bolt/parsing/python/type_resolver.py +730 -0
- apisec_code_bolt/parsing/python/visitors.py +1544 -0
- apisec_code_bolt/parsing/services.py +544 -0
- apisec_code_bolt/query/__init__.py +1 -0
- apisec_code_bolt/query/ast_cache.py +182 -0
- apisec_code_bolt/query/executor.py +283 -0
- apisec_code_bolt/query/handlers.py +832 -0
- apisec_code_bolt-0.1.0.dist-info/METADATA +230 -0
- apisec_code_bolt-0.1.0.dist-info/RECORD +111 -0
- apisec_code_bolt-0.1.0.dist-info/WHEEL +4 -0
- apisec_code_bolt-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Call graph type definitions: enums, data models, and built-in constants.
|
|
3
|
+
|
|
4
|
+
This module contains all pure data types used across the call graph subsystem.
|
|
5
|
+
It has zero dependencies on other analysis modules.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from enum import Enum, auto
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
# =============================================================================
|
|
15
|
+
# Call Graph Node and Edge Types
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class NodeType(Enum):
|
|
20
|
+
"""Types of nodes in the call graph."""
|
|
21
|
+
|
|
22
|
+
FUNCTION = auto() # Top-level function
|
|
23
|
+
METHOD = auto() # Class method
|
|
24
|
+
CONSTRUCTOR = auto() # __init__ or constructor
|
|
25
|
+
STATIC_METHOD = auto() # @staticmethod
|
|
26
|
+
CLASS_METHOD = auto() # @classmethod
|
|
27
|
+
PROPERTY = auto() # @property
|
|
28
|
+
LAMBDA = auto() # Lambda expression
|
|
29
|
+
CLOSURE = auto() # Nested function
|
|
30
|
+
EXTERNAL = auto() # External library function
|
|
31
|
+
BUILTIN = auto() # Built-in function
|
|
32
|
+
UNKNOWN = auto() # Could not determine
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EdgeType(Enum):
|
|
36
|
+
"""Types of edges (call relationships) in the call graph."""
|
|
37
|
+
|
|
38
|
+
DIRECT_CALL = auto() # foo()
|
|
39
|
+
METHOD_CALL = auto() # obj.foo()
|
|
40
|
+
STATIC_CALL = auto() # Class.foo()
|
|
41
|
+
SUPER_CALL = auto() # super().foo()
|
|
42
|
+
CONSTRUCTOR_CALL = auto() # MyClass()
|
|
43
|
+
CALLBACK = auto() # foo(callback=bar)
|
|
44
|
+
DECORATOR = auto() # @decorator
|
|
45
|
+
COMPREHENSION = auto() # [f(x) for x in ...]
|
|
46
|
+
CONDITIONAL = auto() # foo() if cond else bar()
|
|
47
|
+
LAMBDA_CALL = auto() # (lambda x: x)()
|
|
48
|
+
RETURN_CALL = auto() # return func()
|
|
49
|
+
UNKNOWN = auto()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ResolutionConfidence(Enum):
|
|
53
|
+
"""Confidence level in call resolution."""
|
|
54
|
+
|
|
55
|
+
EXACT = auto() # Statically determined, single target
|
|
56
|
+
HIGH = auto() # Single likely target with good evidence
|
|
57
|
+
MEDIUM = auto() # Few possible targets
|
|
58
|
+
LOW = auto() # Many possible targets or weak evidence
|
|
59
|
+
UNRESOLVED = auto() # Could not resolve at all
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CallContext(Enum):
|
|
63
|
+
"""Syntactic context where a call occurs."""
|
|
64
|
+
|
|
65
|
+
NORMAL = auto() # Regular statement
|
|
66
|
+
LOOP = auto() # Inside for/while
|
|
67
|
+
CONDITIONAL = auto() # Inside if/elif/else
|
|
68
|
+
TRY_BLOCK = auto() # Inside try
|
|
69
|
+
EXCEPT_HANDLER = auto() # Inside except
|
|
70
|
+
FINALLY_BLOCK = auto() # Inside finally
|
|
71
|
+
WITH_BLOCK = auto() # Inside with
|
|
72
|
+
COMPREHENSION = auto() # Inside list/dict/set comp or genexp
|
|
73
|
+
LAMBDA = auto() # Inside lambda body
|
|
74
|
+
DEFAULT_ARG = auto() # As default argument value
|
|
75
|
+
DECORATOR = auto() # As decorator
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class CallGraphNode:
|
|
80
|
+
"""
|
|
81
|
+
A node in the call graph (a callable entity).
|
|
82
|
+
|
|
83
|
+
Represents a function, method, constructor, lambda, or external symbol.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
# Identity
|
|
87
|
+
qualified_name: str # Fully qualified name
|
|
88
|
+
name: str # Simple name
|
|
89
|
+
node_type: NodeType
|
|
90
|
+
|
|
91
|
+
# Location (None for external/builtin)
|
|
92
|
+
file_path: Path | None = None
|
|
93
|
+
line: int = 0
|
|
94
|
+
end_line: int = 0
|
|
95
|
+
|
|
96
|
+
# For methods
|
|
97
|
+
class_name: str | None = None
|
|
98
|
+
class_qualified_name: str | None = None
|
|
99
|
+
|
|
100
|
+
# Metadata
|
|
101
|
+
is_async: bool = False
|
|
102
|
+
is_generator: bool = False
|
|
103
|
+
is_abstract: bool = False
|
|
104
|
+
|
|
105
|
+
# Parameters (for signature matching)
|
|
106
|
+
parameters: list[str] = field(default_factory=list)
|
|
107
|
+
return_type: str | None = None
|
|
108
|
+
|
|
109
|
+
# Return value tracking (for closure/lambda returns)
|
|
110
|
+
returns_callable: bool = False
|
|
111
|
+
returned_callables: list[str] = field(default_factory=list)
|
|
112
|
+
|
|
113
|
+
# Resolution info
|
|
114
|
+
is_external: bool = False
|
|
115
|
+
external_module: str | None = None
|
|
116
|
+
|
|
117
|
+
# Analysis metadata
|
|
118
|
+
docstring: str | None = None
|
|
119
|
+
decorators: list[str] = field(default_factory=list)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass
|
|
123
|
+
class CallGraphEdge:
|
|
124
|
+
"""
|
|
125
|
+
An edge in the call graph (a call relationship).
|
|
126
|
+
|
|
127
|
+
Represents a call from one function to another.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# Identity (required fields first)
|
|
131
|
+
caller: str # Qualified name of caller
|
|
132
|
+
callee: str # Qualified name of callee
|
|
133
|
+
edge_type: EdgeType
|
|
134
|
+
|
|
135
|
+
# Call site location
|
|
136
|
+
file_path: Path
|
|
137
|
+
line: int
|
|
138
|
+
|
|
139
|
+
# Resolution
|
|
140
|
+
confidence: ResolutionConfidence
|
|
141
|
+
|
|
142
|
+
# Optional fields with defaults
|
|
143
|
+
column: int = 0
|
|
144
|
+
|
|
145
|
+
# If multiple possible targets
|
|
146
|
+
possible_callees: list[str] = field(default_factory=list)
|
|
147
|
+
|
|
148
|
+
# Arguments at call site
|
|
149
|
+
argument_count: int = 0
|
|
150
|
+
keyword_arguments: list[str] = field(default_factory=list)
|
|
151
|
+
has_spread: bool = False
|
|
152
|
+
has_keyword_spread: bool = False
|
|
153
|
+
|
|
154
|
+
# Context (now properly populated)
|
|
155
|
+
context: CallContext = CallContext.NORMAL
|
|
156
|
+
in_loop: bool = False
|
|
157
|
+
in_conditional: bool = False
|
|
158
|
+
in_try_block: bool = False
|
|
159
|
+
in_except_handler: bool = False
|
|
160
|
+
in_comprehension: bool = False
|
|
161
|
+
|
|
162
|
+
# For callbacks/higher-order
|
|
163
|
+
argument_position: int | None = None # If callee is passed as argument
|
|
164
|
+
callback_parameter: str | None = None # Parameter name if callback
|
|
165
|
+
|
|
166
|
+
# Provenance (why we think this is the target)
|
|
167
|
+
resolution_reason: str = ""
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# =============================================================================
|
|
171
|
+
# Variable Binding Data Model
|
|
172
|
+
# =============================================================================
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@dataclass
|
|
176
|
+
class TypeBinding:
|
|
177
|
+
"""
|
|
178
|
+
A binding between a variable and possible types.
|
|
179
|
+
|
|
180
|
+
Used for resolving dynamic dispatch: if we see x.foo(), we need to know
|
|
181
|
+
what types x could be to resolve which foo() is called.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
variable: str
|
|
185
|
+
possible_types: set[str] = field(default_factory=set)
|
|
186
|
+
|
|
187
|
+
# Where this binding was established
|
|
188
|
+
assignment_locations: list[tuple[Path, int]] = field(default_factory=list)
|
|
189
|
+
|
|
190
|
+
# Is this a parameter? (could be any type that matches signature)
|
|
191
|
+
is_parameter: bool = False
|
|
192
|
+
parameter_type_annotation: str | None = None
|
|
193
|
+
|
|
194
|
+
# Is this from an import?
|
|
195
|
+
is_import: bool = False
|
|
196
|
+
import_source: str | None = None
|
|
197
|
+
|
|
198
|
+
# For transitive propagation: variables this was assigned from
|
|
199
|
+
source_variables: set[str] = field(default_factory=set)
|
|
200
|
+
|
|
201
|
+
# Does this hold a callable (function/lambda)?
|
|
202
|
+
holds_callable: bool = False
|
|
203
|
+
callable_targets: set[str] = field(default_factory=set)
|
|
204
|
+
|
|
205
|
+
# Is this self/cls?
|
|
206
|
+
is_self: bool = False
|
|
207
|
+
is_cls: bool = False
|
|
208
|
+
enclosing_class: str | None = None
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# =============================================================================
|
|
212
|
+
# Python Builtins
|
|
213
|
+
# =============================================================================
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
PYTHON_BUILTINS = {
|
|
217
|
+
"print",
|
|
218
|
+
"len",
|
|
219
|
+
"range",
|
|
220
|
+
"str",
|
|
221
|
+
"int",
|
|
222
|
+
"float",
|
|
223
|
+
"list",
|
|
224
|
+
"dict",
|
|
225
|
+
"set",
|
|
226
|
+
"tuple",
|
|
227
|
+
"bool",
|
|
228
|
+
"type",
|
|
229
|
+
"isinstance",
|
|
230
|
+
"issubclass",
|
|
231
|
+
"hasattr",
|
|
232
|
+
"getattr",
|
|
233
|
+
"setattr",
|
|
234
|
+
"delattr",
|
|
235
|
+
"callable",
|
|
236
|
+
"iter",
|
|
237
|
+
"next",
|
|
238
|
+
"enumerate",
|
|
239
|
+
"zip",
|
|
240
|
+
"map",
|
|
241
|
+
"filter",
|
|
242
|
+
"sorted",
|
|
243
|
+
"reversed",
|
|
244
|
+
"min",
|
|
245
|
+
"max",
|
|
246
|
+
"sum",
|
|
247
|
+
"any",
|
|
248
|
+
"all",
|
|
249
|
+
"abs",
|
|
250
|
+
"round",
|
|
251
|
+
"divmod",
|
|
252
|
+
"pow",
|
|
253
|
+
"open",
|
|
254
|
+
"input",
|
|
255
|
+
"repr",
|
|
256
|
+
"ascii",
|
|
257
|
+
"format",
|
|
258
|
+
"hash",
|
|
259
|
+
"id",
|
|
260
|
+
"hex",
|
|
261
|
+
"oct",
|
|
262
|
+
"bin",
|
|
263
|
+
"chr",
|
|
264
|
+
"ord",
|
|
265
|
+
"bytes",
|
|
266
|
+
"bytearray",
|
|
267
|
+
"memoryview",
|
|
268
|
+
"object",
|
|
269
|
+
"super",
|
|
270
|
+
"staticmethod",
|
|
271
|
+
"classmethod",
|
|
272
|
+
"property",
|
|
273
|
+
"vars",
|
|
274
|
+
"dir",
|
|
275
|
+
"locals",
|
|
276
|
+
"globals",
|
|
277
|
+
"eval",
|
|
278
|
+
"exec",
|
|
279
|
+
"compile",
|
|
280
|
+
"slice",
|
|
281
|
+
"frozenset",
|
|
282
|
+
"complex",
|
|
283
|
+
# Common exceptions
|
|
284
|
+
"Exception",
|
|
285
|
+
"BaseException",
|
|
286
|
+
"ValueError",
|
|
287
|
+
"TypeError",
|
|
288
|
+
"KeyError",
|
|
289
|
+
"IndexError",
|
|
290
|
+
"AttributeError",
|
|
291
|
+
"RuntimeError",
|
|
292
|
+
"StopIteration",
|
|
293
|
+
"GeneratorExit",
|
|
294
|
+
"AssertionError",
|
|
295
|
+
"ImportError",
|
|
296
|
+
"ModuleNotFoundError",
|
|
297
|
+
"FileNotFoundError",
|
|
298
|
+
"OSError",
|
|
299
|
+
"IOError",
|
|
300
|
+
"PermissionError",
|
|
301
|
+
"TimeoutError",
|
|
302
|
+
"ConnectionError",
|
|
303
|
+
"BrokenPipeError",
|
|
304
|
+
"ChildProcessError",
|
|
305
|
+
"NotImplementedError",
|
|
306
|
+
"OverflowError",
|
|
307
|
+
"RecursionError",
|
|
308
|
+
"ZeroDivisionError",
|
|
309
|
+
"FloatingPointError",
|
|
310
|
+
"ArithmeticError",
|
|
311
|
+
"LookupError",
|
|
312
|
+
"SyntaxError",
|
|
313
|
+
"IndentationError",
|
|
314
|
+
"TabError",
|
|
315
|
+
"SystemError",
|
|
316
|
+
"SystemExit",
|
|
317
|
+
"KeyboardInterrupt",
|
|
318
|
+
"MemoryError",
|
|
319
|
+
"BufferError",
|
|
320
|
+
"Warning",
|
|
321
|
+
"UserWarning",
|
|
322
|
+
"DeprecationWarning",
|
|
323
|
+
"PendingDeprecationWarning",
|
|
324
|
+
"RuntimeWarning",
|
|
325
|
+
"SyntaxWarning",
|
|
326
|
+
"ResourceWarning",
|
|
327
|
+
"FutureWarning",
|
|
328
|
+
"ImportWarning",
|
|
329
|
+
"UnicodeWarning",
|
|
330
|
+
"BytesWarning",
|
|
331
|
+
"EncodingWarning",
|
|
332
|
+
}
|