def test_matching_triggers(): src = """ import flask app = flask.Flask() app.run(debug=True) """ sig = { "pattern": "flask.Flask.run(..., debug=True)", "detection": { "type": "CustomDetection", "message": "detection_message", "score": 666 }, "tags": ["detection_tag"], "taint": "tainted" } compiled_src = ASTPattern._compile_src(src) p = ASTPattern(signature=sig) v = PatternMatchingVisitor(pattern=p) result = v.traverse(compiled_src) assert result is not None assert len(v.hits) == 1, v.hits hit: Detection = v.hits[0] assert hit.detection_type == "CustomDetection" assert hit.score == 666 assert "detection_tag" in hit.tags, hit.tags assert result._taint_class == Taints.TAINTED
def test_patterns(src, pattern, should_match): signature = {"pattern": pattern, "taint": {"level": "tainted"}} compiled_src = ASTPattern._compile_src(src) p = ASTPattern(signature=signature) v = PatternMatchingVisitor(pattern=p) result = v.traverse(compiled_src) assert bool(result) is should_match
def test_any_of(): src = "eval(print('Hello world'))" sig = { "pattern": ["exec(...)", "something", "print(...)", "x"], "taint": "tainted" } compiled_src = ASTPattern._compile_src(src) p = ASTPattern(sig) v = PatternMatchingVisitor(pattern=p) result = v.traverse(compiled_src) assert result is not None assert result.full_name == "print" assert result._taint_class == Taints.TAINTED
def process_taint(src: str, pattern: str, taint: str="tainted"): tree = collect(dedent(src), minimal=True) loc = ScanLocation(location="<unknown>") p = ASTPattern({ "pattern": pattern, "taint": taint }) with patch.object(config, "get_ast_patterns", return_value=[p]) as mock: v = Visitor.run_stages(location=loc, ast_tree=tree) return v.tree[-1]
def disabled_test_decorator(): # TODO: add pattern matching for decorators src = """\ app = flask.Flask() @app.route("/") def index(): return "Hello world" """ sig = { "pattern": """\ @flask.Flask.route("/") def _(*args, **kwargs): ... """ } compiled_src = ASTPattern._compile_src(src) p = ASTPattern(sig) v = PatternMatchingVisitor(pattern=p) result = v.traverse(compiled_src) assert result is not None
def process_taint(src: str, pattern: str, cache_mock, taint: str="tainted"): tree = collect(dedent(src), minimal=True) loc = ScanLocation(location="<unknown>") p = ASTPattern({ "pattern": pattern, "taint": taint }) cache_mock.return_value = [p] v = Visitor.run_stages(location=loc, ast_tree=tree) return v.tree[-1]