API¶
- class aura.analyzers.detections.Detection(signature: str, message: str, score: int = 0, line_no: Optional[int] = None, line: Optional[str] = None, detection_type: Optional[str] = None, node: Optional[ASTNode] = None, tags: Set[str] = <factory>, extra: dict = <factory>, informational: bool = False, location: Optional[Union[Path, str]] = None, scan_location: Optional[ScanLocation] = None, _metadata: Optional[dict] = None, _hash: Optional[int] = None, _diff_hash: Optional[int] = None, _severity: Optional[str] = None, _sigint: Optional[int] = None)¶
Base for analyzers to produce detections from audit scans that are reported back to the Aura framework Subclass this to have different hits on semantic level
- Parameters
message (str) – Detection message, intended to be displayed to a user
signature (str) – Used by default for hashing/deduplication of various detections. At minimum, it is highly recommended to include at least a detection name and a normalized path to the scanned file. In case of AST based detections, line number is also recommended as it is possible that the source code can contain multiple detections of the same anomaly that are on different lines and should be reported separately.
score (int, optional) – A score associated with this detection that is then used to compute the overall score of the input scanned by Aura.
node (ASTNode, optional) – A reference to the AST node object. It is recommended to set this attribute for AST based detections as the framework will automatically fill some of the emtadata for the output such as line number or the actual content of the line.
extra (dict, optional) – A schema less dictionary. Use this to report back any data fields when exporting the scan data into various formats such as JSON
tags (Set[str], optional) – A set of strings that acts as tags for this detection. Used for filtering the outputs and tagging whole files via detections.
detection_type (str, optional) – An identifier of the detection type. Used for filtering out the different detections. If not provided, class name is used.
- __hash__() int ¶
Default hash implementation for deduplication of detections. By default a combination of a class name and a signature attribute is used to produce the hash.
Override this method for a custom deduplication logic
AST Node types¶
This module contains wrappers for parsed AST nodes
- class aura.analyzers.python.nodes.ASTNode¶
- add_taint(taint: aura.analyzers.python.nodes.Taints, context: aura.analyzers.python.nodes.Context, lock=False, taint_log: Optional[aura.analyzers.python.nodes.TaintLog] = None) bool ¶
Assign a taint to the node Operation is ignored if the current taint is already higher or equal return True if the taint was modified (increased)
- as_native()¶
Return the current node as a native python type if possible For example: - String(value=”a”).as_native() == “a” - Dictionary(keys=[String(“a”)], values=[String(“b”)]).as_native() == {“a”: “b”}
- property cached_full_name: str¶
Permanently cache the full_name attribute Use this only if all the remaining stages are read-only as otherwise it would not register changes to the attributes
- enrich_from_previous(node: Union[dict, aura.analyzers.python.nodes.ASTNode])¶
Enrich the current node using the information from the previous node This is used when AST tree is rewritten/replace with a new node so we copy all the information from the previous one
- Parameters
node (typing.Union[dict, ASTNode]) – previous node that was replaced that we want to copy information from
- class aura.analyzers.python.nodes.Arg(arg: 'str', annotation: 't.Optional[str]' = None, type_comment: 't.Optional[str]' = None)¶
- class aura.analyzers.python.nodes.Arguments(args: 't.List[Arg]', vararg: 't.Optional[Arg]', posonlyargs: 't.List[NodeType]', kwonlyargs: 't.List[NodeType]', kwarg: 't.Optional[Arg]', defaults: 't.List[NodeType]', kw_defaults: 't.List[NodeType]', taints: 't.Dict[str, Taints]' = <factory>, taint_logs: 't.Dict[str, list]' = <factory>)¶
- class aura.analyzers.python.nodes.Attribute(source: 'NodeType', attr: 'str', action: 'str')¶
- class aura.analyzers.python.nodes.BinOp(op: 'str', left: 'NodeType', right: 'NodeType')¶
- class aura.analyzers.python.nodes.Bytes(value: 'bytes')¶
- class aura.analyzers.python.nodes.Call(func: 'NodeType', args: 't.List[ASTNode]', kwargs: 't.MutableMapping', taints: 'dict' = <factory>)¶
- class aura.analyzers.python.nodes.ClassDef(name: 'str', body: 'list', bases: 'list' = <factory>)¶
- class aura.analyzers.python.nodes.Compare(left: 'ASTNode', ops: 'typing.List[ASTNode]', comparators: 'typing.List[ASTNode]', body: 'typing.List[ASTNode]' = <factory>, orelse: 'typing.List[ASTNode]' = <factory>)¶
- class aura.analyzers.python.nodes.Constant(value: 'NodeType')¶
- as_native()¶
Return the current node as a native python type if possible For example: - String(value=”a”).as_native() == “a” - Dictionary(keys=[String(“a”)], values=[String(“b”)]).as_native() == {“a”: “b”}
- class aura.analyzers.python.nodes.Container(name: 'str', pointer: 'ASTNode')¶
- class aura.analyzers.python.nodes.Context(node: 'NodeType', parent: 't.Union[Context, None]', replace: 't.Callable[[NodeType], None]' = <function Context.<lambda> at 0x7f2aae3b6950>, visitor: 't.Any' = None, stack: 'Stack' = <factory>, depth: 'int' = 0, modified: 'bool' = False, shared_state: 'dict' = <factory>, scope_closure: 't.Optional[ASTNode]' = None)¶
- class aura.analyzers.python.nodes.Continue¶
- class aura.analyzers.python.nodes.Dictionary(keys: 't.List[NodeType]' = <function Mapping.keys at 0x7f2ab16d43a0>, values: 't.List[NodeType]' = <function Mapping.values at 0x7f2ab16d44c0>)¶
- as_native() dict ¶
Return the current node as a native python type if possible For example: - String(value=”a”).as_native() == “a” - Dictionary(keys=[String(“a”)], values=[String(“b”)]).as_native() == {“a”: “b”}
- items() a set-like object providing a view on D's items ¶
- class aura.analyzers.python.nodes.ExceptHandler(body: 'list', type: 'List', name: 'typing.Union[str, None]' = None)¶
- class aura.analyzers.python.nodes.FunctionDef(name: 'str', args: 'typing.Any', body: 'typing.List[NodeType]', decorator_list: 'typing.List[NodeType]', returns: 'NodeType')¶
- class aura.analyzers.python.nodes.Import(names: 'dict' = <factory>, level: 't.Optional[int]' = None)¶
- class aura.analyzers.python.nodes.List(elts: 'typing.List[ASTNode]', ctx: 'ASTNode')¶
- class aura.analyzers.python.nodes.Module(body: 't.List[NodeType]')¶
- class aura.analyzers.python.nodes.Number(value: 'int')¶
- as_native() int ¶
Return the current node as a native python type if possible For example: - String(value=”a”).as_native() == “a” - Dictionary(keys=[String(“a”)], values=[String(“b”)]).as_native() == {“a”: “b”}
- class aura.analyzers.python.nodes.Pass¶
- class aura.analyzers.python.nodes.Print(values: 'typing.List[NodeType]', dest: 'typing.Any')¶
- class aura.analyzers.python.nodes.ReturnStmt(value: 'NodeType')¶
- class aura.analyzers.python.nodes.String(value: 'str')¶
- as_native() str ¶
Return the current node as a native python type if possible For example: - String(value=”a”).as_native() == “a” - Dictionary(keys=[String(“a”)], values=[String(“b”)]).as_native() == {“a”: “b”}
- class aura.analyzers.python.nodes.Subscript(value: 'ASTNode', slice: 'ASTNode', ctx: 'str')¶
- class aura.analyzers.python.nodes.TaintLog(path: pathlib.Path, taint_level: Optional[aura.analyzers.python.nodes.Taints] = None, line_no: Optional[int] = None, message: Optional[str] = None, extra: Dict[str, Any] = <factory>, node: Optional[aura.analyzers.python.nodes.ASTNode] = None)¶
Log entry to track the propagation of taints in the AST
- classmethod extract_log(node: aura.analyzers.python.nodes.ASTNode)¶
Extract a sequential log from the provided node This will follow the path of chained nodes and their logs concatenated together
- class aura.analyzers.python.nodes.Taints(value)¶
Enumeration class (enum.Enum) defining the different taint levels:
SAFE = 1
UNKNOWN = 2
TAINTED = 3
Taint levels are comparable and can be “added” (e.g. taint1 + taint2) which will return the taint level of whichever is the highest
- class aura.analyzers.python.nodes.Var(var_name: 'typing.Union[str, NodeType]', value: 't.Optional[NodeType]' = None, var_type: 'str' = 'assign')¶
- class aura.analyzers.python.nodes.Yield(value: 'NodeType')¶
- class aura.analyzers.python.nodes.YieldFrom(value: 'NodeType')¶