| 306 | return self.ctx.match(node, self._compiled) |
| 307 | |
| 308 | def apply(self, context: nodes.Context): |
| 309 | logger.debug(f"Applying AST pattern {self.id} at {context.node.line_no}") |
| 310 | |
| 311 | if "tags" in self._signature: |
| 312 | context.node.tags |= set(self._signature["tags"]) |
| 313 | |
| 314 | if "taint" in self._signature: |
| 315 | t = self._signature["taint"] |
| 316 | |
| 317 | if type(t) == str: |
| 318 | t = {"level": t} |
| 319 | |
| 320 | msg = t.get("log_message") |
| 321 | level = t.get("level") |
| 322 | |
| 323 | if level == "sink": |
| 324 | context.node.mark_as_sink(context=context) |
| 325 | elif level: |
| 326 | level = nodes.Taints.from_string(level) |
| 327 | |
| 328 | if level == nodes.Taints.TAINTED and not msg: |
| 329 | msg = "AST node marked as source using semantic rules" |
| 330 | elif level == nodes.Taints.SAFE and not msg: |
| 331 | msg = "AST node has been cleaned of taint using semantic rules" |
| 332 | |
| 333 | log = nodes.TaintLog( |
| 334 | path = context.visitor.path, |
| 335 | line_no = context.node.line_no, |
| 336 | taint_level = level, |
| 337 | message = msg |
| 338 | ) |
| 339 | context.node.add_taint(level, context, taint_log=log, lock=t.get("lock", True)) |
| 340 | elif msg: |
| 341 | log = nodes.TaintLog( |
| 342 | path=context.visitor.path, |
| 343 | line_no=context.node.line_no, |
| 344 | message=msg |
| 345 | ) |
| 346 | context.node._taint_log.append(log) |
| 347 | |
| 348 | if type(context.node) == nodes.Call and "args" in t: |
| 349 | for arg_name, arg_level in t["args"].items(): |
| 350 | for arg in context.node.args: |
| 351 | if type(arg) == nodes.Arguments and arg_name in arg.args: |
| 352 | arg.taints[arg_name] = nodes.Taints.from_string(arg_level) |
| 353 | |
| 354 | if "detection" in self._signature: |
| 355 | d = self._signature["detection"] |
| 356 | |
| 357 | hit = Detection( |
| 358 | detection_type=d.get("type", "ASTPattern"), |
| 359 | score=d.get("score", 0), |
| 360 | message=d["message"], |
| 361 | node=context.node, |
| 362 | tags=context.node.tags, |
| 363 | signature=f"ast_pattern#{self.id}/{context.node.line_no}#{context.visitor.normalized_path}" |
| 364 | ) |
| 365 | if "informational" in d: |