eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoSqlInjection.py

changeset 7613
382f89c11e27
child 7622
384e2aa5c073
equal deleted inserted replaced
7612:ca1ce1e0fcff 7613:382f89c11e27
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2020 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
21 def getChecks():
22 """
23 Public method to get a dictionary with checks handled by this module.
24
25 @return dictionary containing checker lists containing checker function and
26 list of codes
27 @rtype dict
28 """
29 return {
30 "Call": [
31 (checkDjangoExtraUsed, ("S610",)),
32 (checkDjangoRawSqlUsed, ("S611",)),
33 ],
34 }
35
36
37 def keywords2dict(keywords):
38 """
39 Function to extract keywords arguments into a dictionary.
40
41 @param keywords list of keyword nodes
42 @type list of ast.keyword
43 @return dictionary with keyword name and value
44 @rtype dict
45 """
46 kwargs = {}
47 for node in keywords:
48 if isinstance(node, ast.keyword):
49 kwargs[node.arg] = node.value
50 return kwargs
51
52
53 def checkDjangoExtraUsed(reportError, context, config):
54 """
55 Function to check for potential SQL injection on extra function.
56
57 @param reportError function to be used to report errors
58 @type func
59 @param context security context object
60 @type SecurityContext
61 @param config dictionary with configuration data
62 @type dict
63 """
64 if context.callFunctionName == 'extra':
65 kwargs = keywords2dict(context.node.keywords)
66 args = context.node.args
67 if args:
68 if len(args) >= 1:
69 kwargs['select'] = args[0]
70 if len(args) >= 2:
71 kwargs['where'] = args[1]
72 if len(args) >= 3:
73 kwargs['params'] = args[2]
74 if len(args) >= 4:
75 kwargs['tables'] = args[3]
76 if len(args) >= 5:
77 kwargs['order_by'] = args[4]
78 if len(args) >= 6:
79 kwargs['select_params'] = args[5]
80 insecure = False
81 for key in ['where', 'tables']:
82 if key in kwargs:
83 if isinstance(kwargs[key], ast.List):
84 for val in kwargs[key].elts:
85 if not isinstance(val, ast.Str):
86 insecure = True
87 break
88 else:
89 insecure = True
90 break
91 if not insecure and 'select' in kwargs:
92 if isinstance(kwargs['select'], ast.Dict):
93 for k in kwargs['select'].keys:
94 if not isinstance(k, ast.Str):
95 insecure = True
96 break
97 if not insecure:
98 for v in kwargs['select'].values:
99 if not isinstance(v, ast.Str):
100 insecure = True
101 break
102 else:
103 insecure = True
104
105 if insecure:
106 reportError(
107 context.node.lineno - 1,
108 context.node.col_offset,
109 "S610",
110 "M",
111 "M"
112 )
113
114
115 def checkDjangoRawSqlUsed(reportError, context, config):
116 """
117 Function to check for potential SQL injection on RawSQL function.
118
119 @param reportError function to be used to report errors
120 @type func
121 @param context security context object
122 @type SecurityContext
123 @param config dictionary with configuration data
124 @type dict
125 """
126 if context.isModuleImportedLike('django.db.models'):
127 if context.callFunctionName == 'RawSQL':
128 sql = context.node.args[0]
129 if not isinstance(sql, ast.Str):
130 reportError(
131 context.node.lineno - 1,
132 context.node.col_offset,
133 "S611",
134 "M",
135 "M"
136 )

eric ide

mercurial