API

class aura.analyzers.detections.Detection(signature: str, message: str, score: int = 0, line_no: Optional[int] = None, line: Union[str, None] = None, detection_type: Optional[str] = None, node: Optional[NodeType] = None, tags: Set[str] = <factory>, extra: dict = <factory>, informational: bool = False, location: Optional[Path, str] = None, _metadata: Optional[dict] = 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__()

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

_asdict() → Dict

Exporting mechanism for JSON output/machine processing Define fields to be exported here, subclass need to fetch the fields from their parent in this method Output dict must contain only elements that are JSON serializable

Returns

Serialized data for the detection

Return type

dict

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)

property cached_full_name

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.Arguments(args: 'typing.List[str]', vararg: 'NodeType', kwonlyargs: 'typing.List[NodeType]', kwarg: 'NodeType', defaults: 'typing.List[NodeType]', kw_defaults: 'typing.List[NodeType]', taints: 'typing.Dict[str, Taints]' = <factory>, taint_logs: 'typing.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: 'list', kwargs: 'dict', 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)
class aura.analyzers.python.nodes.Container(name: str, pointer: ASTNode)
class aura.analyzers.python.nodes.Context(node: 'NodeType', parent: 'typing.Union[Context, None]', replace: 'typing.Callable[[NodeType], None]' = <function <lambda> at 0x7f1b2e1bdaf0>, visitor: 'typing.Any' = None, stack: 'Stack' = <factory>, depth: 'int' = 0, modified: 'bool' = False, shared_state: 'dict' = <factory>, scope_closure: 'typing.Optional[ASTNode]' = None)
class aura.analyzers.python.nodes.Continue
class aura.analyzers.python.nodes.Dictionary(keys: list, values: list)
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[ASTNode], decorator_list: typing.List[ASTNode], returns: ASTNode)
class aura.analyzers.python.nodes.Import(names: 'dict' = <factory>)
class aura.analyzers.python.nodes.List(elts: typing.List[ASTNode], ctx: ASTNode)
class aura.analyzers.python.nodes.Module(body: typing.List[NodeType, …])
class aura.analyzers.python.nodes.Number(value: int)
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)
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 = <factory>, node: Optional[NewType.<locals>.new_type] = 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: str, value: typing.Union[NodeType, None] = None, var_type: str = 'assign')
class aura.analyzers.python.nodes.Yield(value: NodeType)
class aura.analyzers.python.nodes.YieldFrom(value: NodeType)