(self, context)
| 111 | context.node.set_taint(name=arg, taint_level=Taints.TAINTED, taint_log=log, context=context) |
| 112 | |
| 113 | def __propagate_taint(self, context): |
| 114 | if isinstance(context.node, Attribute) and isinstance( |
| 115 | context.node.source, ASTNode |
| 116 | ): |
| 117 | self.__propagate_attribute(context) |
| 118 | return |
| 119 | elif isinstance(context.node, Call): |
| 120 | f_name = context.node.cached_full_name |
| 121 | args_taints = [] |
| 122 | # Extract taints from arguments |
| 123 | for idx, x in enumerate(context.node.args): |
| 124 | if isinstance(x, Arguments) and type(context.node._orig_args[idx]) == str: |
| 125 | arg_name = context.node._orig_args[idx] |
| 126 | args_taints.append(x.taints.get(arg_name, Taints.SAFE)) |
| 127 | elif isinstance(x, ASTNode): |
| 128 | args_taints.append(x._taint_class) |
| 129 | |
| 130 | for x in context.node.kwargs.values(): |
| 131 | if isinstance(x, ASTNode): |
| 132 | args_taints.append(x._taint_class) |
| 133 | |
| 134 | # Extract taint if the function itself is tainted |
| 135 | if isinstance(context.node.func, ASTNode): |
| 136 | args_taints.append(context.node.func._taint_class) |
| 137 | |
| 138 | if not args_taints: |
| 139 | return |
| 140 | # Choose the highest taint from the extracted taints |
| 141 | call_taint = max(args_taints) |
| 142 | if context.node.add_taint(taint=call_taint, context=context): |
| 143 | # Mark built-in objects for example [].append(<tainted>) |
| 144 | if isinstance(context.node.func, Attribute) and isinstance( |
| 145 | context.node.func.source, (List,) |
| 146 | ): |
| 147 | context.node.func.source.add_taint(call_taint, context) |
| 148 | return |
| 149 | |
| 150 | # Lookup in a call graph if the function was defined |
| 151 | if type(f_name) == str and f_name in context.call_graph.definitions: |
| 152 | func_def = context.call_graph.definitions[f_name] |
| 153 | |
| 154 | # Propagate taint from the function definition |
| 155 | context.node.add_taint(func_def._taint_class, context) |
| 156 | # Apply taint from called arguments to the function definition |
| 157 | for idx, x in enumerate(context.node.args): |
| 158 | if not isinstance(x, ASTNode): |
| 159 | continue |
| 160 | if x.cached_full_name is None: |
| 161 | arg_index = idx |
| 162 | elif type(x.cached_full_name) == str: |
| 163 | arg_index = x.cached_full_name |
| 164 | else: |
| 165 | continue |
| 166 | func_def.set_taint(name=arg_index, taint_level=x._taint_class, context=context, taint_log=None) |
| 167 | |
| 168 | elif isinstance(context.node, Var): |
| 169 | var_taint = max( |
| 170 | context.node._taint_class, |
no test coverage detected