@@ -61,9 +61,6 @@ def _is_allowed_function_call(self, func_name: str) -> bool:
6161 return True
6262
6363 def visit_Call (self , node ):
64- if self .allowed_functions is None and self .blocked_functions is None :
65- return
66-
6764 function_name = None
6865 if isinstance (node .func , ast .Name ):
6966 function_name = node .func .id
@@ -92,13 +89,15 @@ def visit_Call(self, node):
9289 self .generic_visit (node )
9390 return
9491
95- if function_name and not self ._is_allowed_function_call (function_name ):
96- self .errors .append (
97- f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
98- f"=> Function '{ function_name } ' is not allowed." ,
99- )
92+ # Check against allowed/blocked function lists if configured
93+ if self .allowed_functions is not None or self .blocked_functions is not None :
94+ if function_name and not self ._is_allowed_function_call (function_name ):
95+ self .errors .append (
96+ f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
97+ f"=> Function '{ function_name } ' is not allowed." ,
98+ )
10099
101- # Check for dynamic attribute access functions that can bypass security
100+ # Always check for dynamic attribute access functions that can bypass security
102101 if function_name in DANGEROUS_BUILTINS :
103102 self .errors .append (
104103 f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
@@ -119,35 +118,33 @@ def _is_allowed_module_import(self, mod_name: str) -> bool:
119118 return True
120119
121120 def visit_Import (self , node ):
122- if self .allowed_modules is None and self .blocked_modules is None :
123- return
121+ if self .allowed_modules is not None or self .blocked_modules is not None :
122+ for alias in node .names :
123+ if "." in alias .name :
124+ module_name = alias .name .split ("." )[0 ]
125+ else :
126+ module_name = alias .name
127+
128+ if not self ._is_allowed_module_import (module_name ):
129+ self .errors .append (
130+ f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
131+ f"=> Importing module '{ module_name } ' is not allowed. " ,
132+ )
133+ self .generic_visit (node )
124134
125- for alias in node .names :
126- if "." in alias .name :
127- module_name = alias .name .split ("." )[0 ]
135+ def visit_ImportFrom (self , node ):
136+ if self .allowed_modules is not None or self .blocked_modules is not None :
137+ if node .module and "." in node .module :
138+ module_name = node .module .split ("." )[0 ]
128139 else :
129- module_name = alias . name
140+ module_name = node . module
130141
131- if not self ._is_allowed_module_import (module_name ):
142+ if module_name and not self ._is_allowed_module_import (module_name ):
132143 self .errors .append (
133144 f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
134- f"=> Importing module '{ module_name } ' is not allowed. " ,
145+ f"=> Importing from module '{ node . module } ' is not allowed." ,
135146 )
136-
137- def visit_ImportFrom (self , node ):
138- if self .allowed_modules is None and self .blocked_modules is None :
139- return
140-
141- if "." in node .module :
142- module_name = node .module .split ("." )[0 ]
143- else :
144- module_name = node .module
145-
146- if not self ._is_allowed_module_import (module_name ):
147- self .errors .append (
148- f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
149- f"=> Importing from module '{ node .module } ' is not allowed." ,
150- )
147+ self .generic_visit (node )
151148
152149 def _is_allowed_variable (self , var_name : str ) -> bool :
153150 if self .allowed_variables is not None :
@@ -157,23 +154,22 @@ def _is_allowed_variable(self, var_name: str) -> bool:
157154 return True
158155
159156 def visit_Assign (self , node : ast .Assign ):
160- if self .allowed_variables is None :
161- return
162-
163- for target in node .targets :
164- variable_names = []
165- if isinstance (target , ast .Name ):
166- variable_names .append (target .id )
167- else :
168- for name in ast .walk (target ):
169- if isinstance (name , ast .Name ):
170- variable_names .append (name .id )
171- for variable_name in variable_names :
172- if not self ._is_allowed_variable (variable_name ):
173- self .errors .append (
174- f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
175- f"=> Assigning to { variable_name } is not allowed." ,
176- )
157+ if self .allowed_variables is not None :
158+ for target in node .targets :
159+ variable_names = []
160+ if isinstance (target , ast .Name ):
161+ variable_names .append (target .id )
162+ else :
163+ for name in ast .walk (target ):
164+ if isinstance (name , ast .Name ):
165+ variable_names .append (name .id )
166+ for variable_name in variable_names :
167+ if not self ._is_allowed_variable (variable_name ):
168+ self .errors .append (
169+ f"Error on line { node .lineno } : { self .lines [node .lineno - 1 ]} "
170+ f"=> Assigning to { variable_name } is not allowed." ,
171+ )
172+ self .generic_visit (node )
177173
178174 def visit_Subscript (self , node : ast .Subscript ):
179175 """Check for dictionary-based attribute access that could bypass security.
0 commit comments