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

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2020 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing checks for potential SQL injections risks.
8 """
9
10 #
11 # This is a modified version of the one found in the bandit package.
12 #
13 # Original Copyright (C) 2018 [Victor Torre](https://github.com/ehooo)
14 #
15 # SPDX-License-Identifier: Apache-2.0
16 #
17
18 import ast
19
20 import AstUtilities
21
22
23 def getChecks():
24 """
25 Public method to get a dictionary with checks handled by this module.
26
27 @return dictionary containing checker lists containing checker function and
28 list of codes
29 @rtype dict
30 """
31 return {
32 "Call": [
33 (checkDjangoExtraUsed, ("S610",)),
34 (checkDjangoRawSqlUsed, ("S611",)),
35 ],
36 }
37
38
39 def keywords2dict(keywords):
40 """
41 Function to extract keywords arguments into a dictionary.
42
43 @param keywords list of keyword nodes
44 @type list of ast.keyword
45 @return dictionary with keyword name and value
46 @rtype dict
47 """
48 kwargs = {}
49 for node in keywords:
50 if isinstance(node, ast.keyword):
51 kwargs[node.arg] = node.value
52 return kwargs
53
54
55 def checkDjangoExtraUsed(reportError, context, config):
56 """
57 Function to check for potential SQL injection on extra function.
58
59 @param reportError function to be used to report errors
60 @type func
61 @param context security context object
62 @type SecurityContext
63 @param config dictionary with configuration data
64 @type dict
65 """
66 if context.callFunctionName == 'extra':
67 kwargs = keywords2dict(context.node.keywords)
68 args = context.node.args
69 if args:
70 if len(args) >= 1:
71 kwargs['select'] = args[0]
72 if len(args) >= 2:
73 kwargs['where'] = args[1]
74 if len(args) >= 3:
75 kwargs['params'] = args[2]
76 if len(args) >= 4:
77 kwargs['tables'] = args[3]
78 if len(args) >= 5:
79 kwargs['order_by'] = args[4]
80 if len(args) >= 6:
81 kwargs['select_params'] = args[5]
82 insecure = False
83 for key in ['where', 'tables']:
84 if key in kwargs:
85 if isinstance(kwargs[key], ast.List):
86 for val in kwargs[key].elts:
87 if not AstUtilities.isString(val):
88 insecure = True
89 break
90 else:
91 insecure = True
92 break
93 if not insecure and 'select' in kwargs:
94 if isinstance(kwargs['select'], ast.Dict):
95 for k in kwargs['select'].keys:
96 if not AstUtilities.isString(k):
97 insecure = True
98 break
99 if not insecure:
100 for v in kwargs['select'].values:
101 if not AstUtilities.isString(v):
102 insecure = True
103 break
104 else:
105 insecure = True
106
107 if insecure:
108 reportError(
109 context.node.lineno - 1,
110 context.node.col_offset,
111 "S610",
112 "M",
113 "M"
114 )
115
116
117 def checkDjangoRawSqlUsed(reportError, context, config):
118 """
119 Function to check for potential SQL injection on RawSQL function.
120
121 @param reportError function to be used to report errors
122 @type func
123 @param context security context object
124 @type SecurityContext
125 @param config dictionary with configuration data
126 @type dict
127 """
128 if (
129 context.isModuleImportedLike('django.db.models') and
130 context.callFunctionName == 'RawSQL'
131 ):
132 sql = context.node.args[0]
133 if not AstUtilities.isString(sql):
134 reportError(
135 context.node.lineno - 1,
136 context.node.col_offset,
137 "S611",
138 "M",
139 "M"
140 )

eric ide

mercurial