src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoXssVulnerability.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9325
8157eb19aba5
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoXssVulnerability.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoXssVulnerability.py	Wed Jul 13 14:55:47 2022 +0200
@@ -23,7 +23,7 @@
 def getChecks():
     """
     Public method to get a dictionary with checks handled by this module.
-    
+
     @return dictionary containing checker lists containing checker function and
         list of codes
     @rtype dict
@@ -38,7 +38,7 @@
 def checkDjangoXssVulnerability(reportError, context, config):
     """
     Function to check for potential XSS vulnerability.
-    
+
     @param reportError function to be used to report errors
     @type func
     @param context security context object
@@ -46,13 +46,13 @@
     @param config dictionary with configuration data
     @type dict
     """
-    if context.isModuleImportedLike('django.utils.safestring'):
+    if context.isModuleImportedLike("django.utils.safestring"):
         affectedFunctions = [
-            'mark_safe',
-            'SafeText',
-            'SafeUnicode',
-            'SafeString',
-            'SafeBytes'
+            "mark_safe",
+            "SafeText",
+            "SafeUnicode",
+            "SafeString",
+            "SafeBytes",
         ]
         if context.callFunctionName in affectedFunctions:
             xss = context.node.args[0]
@@ -63,29 +63,29 @@
 def checkPotentialRisk(reportError, node):
     """
     Function to check a given node for a potential XSS vulnerability.
-    
+
     @param reportError function to be used to report errors
     @type func
     @param node node to be checked
     @type ast.Call
     """
     xssVar = node.args[0]
-    
+
     secure = False
-    
+
     if isinstance(xssVar, ast.Name):
         # Check if the var are secure
         parent = node._securityParent
         while not isinstance(parent, (ast.Module, ast.FunctionDef)):
             parent = parent._securityParent
-        
+
         isParam = False
         if isinstance(parent, ast.FunctionDef):
             for name in parent.args.args:
                 if name.arg == xssVar.id:
                     isParam = True
                     break
-        
+
         if not isParam:
             secure = evaluateVar(xssVar, parent, node.lineno)
     elif isinstance(xssVar, ast.Call):
@@ -102,25 +102,20 @@
                 parent = parent._securityParent
             newCall = transform2call(xssVar)
             secure = evaluateCall(newCall, parent)
-    
+
     if not secure:
-        reportError(
-            node.lineno - 1,
-            node.col_offset,
-            "S703",
-            "M",
-            "H"
-        )
+        reportError(node.lineno - 1, node.col_offset, "S703", "M", "H")
 
 
 class DeepAssignation:
     """
     Class to perform a deep analysis of an assign.
     """
+
     def __init__(self, varName, ignoreNodes=None):
         """
         Constructor
-        
+
         @param varName name of the variable
         @type str
         @param ignoreNodes list of nodes to ignore
@@ -128,11 +123,11 @@
         """
         self.__varName = varName
         self.__ignoreNodes = ignoreNodes
-    
+
     def isAssignedIn(self, items):
         """
         Public method to check, if the variable is assigned to.
-        
+
         @param items list of nodes to check against
         @type list of ast.AST
         @return list of nodes assigned
@@ -146,13 +141,13 @@
                     assigned.extend(newAssigned)
                 else:
                     assigned.append(newAssigned)
-        
+
         return assigned
-    
+
     def isAssigned(self, node):
         """
         Public method to check assignment against a given node.
-        
+
         @param node node to check against
         @type ast.AST
         @return flag indicating an assignement
@@ -160,31 +155,26 @@
         """
         assigned = False
         if (
-            self.__ignoreNodes and
-            isinstance(self.__ignoreNodes, (list, tuple, object)) and
-            isinstance(node, self.__ignoreNodes)
+            self.__ignoreNodes
+            and isinstance(self.__ignoreNodes, (list, tuple, object))
+            and isinstance(node, self.__ignoreNodes)
         ):
             return assigned
-        
+
         if isinstance(node, ast.Expr):
             assigned = self.isAssigned(node.value)
         elif isinstance(node, ast.FunctionDef):
             for name in node.args.args:
-                if (
-                    isinstance(name, ast.Name) and
-                    name.id == self.var_name.id
-                ):
+                if isinstance(name, ast.Name) and name.id == self.var_name.id:
                     # If is param the assignations are not affected
                     return assigned
-            
+
             assigned = self.isAssignedIn(node.body)
         elif isinstance(node, ast.With):
             for withitem in node.items:
-                varId = getattr(withitem.optional_vars, 'id', None)
+                varId = getattr(withitem.optional_vars, "id", None)
                 assigned = (
-                    node
-                    if varId == self.__varName.id else
-                    self.isAssignedIn(node.body)
+                    node if varId == self.__varName.id else self.isAssignedIn(node.body)
                 )
         elif isinstance(node, ast.Try):
             assigned = []
@@ -200,9 +190,9 @@
             assigned.extend(self.isAssignedIn(node.body))
             assigned.extend(self.isAssignedIn(node.orelse))
         elif (
-            isinstance(node, ast.AugAssign) and
-            isinstance(node.target, ast.Name) and
-            node.target.id == self.__varName.id
+            isinstance(node, ast.AugAssign)
+            and isinstance(node.target, ast.Name)
+            and node.target.id == self.__varName.id
         ):
             assigned = node.value
         elif isinstance(node, ast.Assign) and node.targets:
@@ -215,14 +205,14 @@
                     if name.id == self.__varName.id:
                         assigned = node.value.elts[pos]
                         break
-        
+
         return assigned
 
 
 def evaluateVar(xssVar, parent, until, ignoreNodes=None):
     """
     Function to evaluate a variable node for potential XSS vulnerability.
-    
+
     @param xssVar variable node to be checked
     @type ast.Name
     @param parent parent node
@@ -236,12 +226,11 @@
     """
     secure = False
     if isinstance(xssVar, ast.Name):
-        if (
-            isinstance(parent, ast.FunctionDef) and
-            any(name.arg == xssVar.id for name in parent.args.args)
+        if isinstance(parent, ast.FunctionDef) and any(
+            name.arg == xssVar.id for name in parent.args.args
         ):
             return False  # Params are not secure
-        
+
         analyser = DeepAssignation(xssVar, ignoreNodes)
         for node in parent.body:
             if node.lineno >= until:
@@ -251,8 +240,7 @@
                 if AstUtilities.isString(to):
                     secure = True
                 elif isinstance(to, ast.Name):
-                    secure = evaluateVar(
-                        to, parent, to.lineno, ignoreNodes)
+                    secure = evaluateVar(to, parent, to.lineno, ignoreNodes)
                 elif isinstance(to, ast.Call):
                     secure = evaluateCall(to, parent, ignoreNodes)
                 elif isinstance(to, (list, tuple)):
@@ -261,8 +249,7 @@
                         if AstUtilities.isString(someTo):
                             numSecure += 1
                         elif isinstance(someTo, ast.Name):
-                            if evaluateVar(someTo, parent,
-                                           node.lineno, ignoreNodes):
+                            if evaluateVar(someTo, parent, node.lineno, ignoreNodes):
                                 numSecure += 1
                             else:
                                 break
@@ -276,14 +263,14 @@
                 else:
                     secure = False
                     break
-    
+
     return secure
 
 
 def evaluateCall(call, parent, ignoreNodes=None):
     """
     Function to evaluate a call node for potential XSS vulnerability.
-    
+
     @param call call node to be checked
     @type ast.Call
     @param parent parent node
@@ -295,20 +282,20 @@
     """
     secure = False
     evaluate = False
-    
+
     if (
-        isinstance(call, ast.Call) and
-        isinstance(call.func, ast.Attribute) and
-        AstUtilities.isString(call.func.value) and
-        call.func.attr == 'format'
+        isinstance(call, ast.Call)
+        and isinstance(call.func, ast.Attribute)
+        and AstUtilities.isString(call.func.value)
+        and call.func.attr == "format"
     ):
         evaluate = True
         if call.keywords:
             evaluate = False
-    
+
     if evaluate:
         args = list(call.args)
-        
+
         numSecure = 0
         for arg in args:
             if AstUtilities.isString(arg):
@@ -323,23 +310,22 @@
                     numSecure += 1
                 else:
                     break
-            elif (
-                isinstance(arg, ast.Starred) and
-                isinstance(arg.value, (ast.List, ast.Tuple))
+            elif isinstance(arg, ast.Starred) and isinstance(
+                arg.value, (ast.List, ast.Tuple)
             ):
                 args.extend(arg.value.elts)
                 numSecure += 1
             else:
                 break
         secure = numSecure == len(args)
-    
+
     return secure
 
 
 def transform2call(var):
     """
     Function to transform a variable node to a call node.
-    
+
     @param var variable node
     @type ast.BinOp
     @return call node
@@ -356,12 +342,12 @@
             newCall.lineno = var.lineno
             newCall.func = ast.Attribute()
             newCall.func.value = var.left
-            newCall.func.attr = 'format'
+            newCall.func.attr = "format"
             if isinstance(var.right, ast.Tuple):
                 newCall.args = var.right.elts
             else:
                 newCall.args = [var.right]
-            
+
             return newCall
-    
+
     return None

eric ide

mercurial