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

branch
eric7
changeset 11136
437db2f032fd
parent 11135
5af56f31c53f
child 11137
a90284948331
equal deleted inserted replaced
11135:5af56f31c53f 11136:437db2f032fd
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2020 - 2025 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a check for use of insecure md4, md5, or sha1 hash
8 functions in hashlib.new().
9 """
10
11 import sys
12
13 from Security.SecurityDefaults import SecurityDefaults
14
15 #
16 # This is a modified version of the one found in the bandit package.
17 #
18 # Original Copyright 2014 Hewlett-Packard Development Company, L.P.
19 #
20 # SPDX-License-Identifier: Apache-2.0
21 #
22
23
24 def getChecks():
25 """
26 Public method to get a dictionary with checks handled by this module.
27
28 @return dictionary containing checker lists containing checker function and
29 list of codes
30 @rtype dict
31 """
32 return {
33 "Call": [
34 (checkHashlib, ("S331",)),
35 ],
36 }
37
38
39 def _hashlibFunc(reportError, context, func, config):
40 """
41 Function to check for use of insecure md4, md5, sha or sha1 hash functions
42 in hashlib.new() if 'usedforsecurity' is not set to 'False'.
43
44 @param reportError function to be used to report errors
45 @type func
46 @param context security context object
47 @type SecurityContext
48 @param func name of the hash function
49 @type str
50 @param config dictionary with configuration data
51 @type dict
52 """
53 insecureHashes = (
54 [h.lower() for h in config["insecure_hashes"]]
55 if config and "insecure_hashes" in config
56 else SecurityDefaults["insecure_hashes"]
57 )
58
59 if isinstance(context.callFunctionNameQual, str):
60 keywords = context.callKeywords
61
62 if func in insecureHashes:
63 if keywords.get("usedforsecurity", "True") == "True":
64 reportError(
65 context.node.lineno - 1,
66 context.node.col_offset,
67 "S332",
68 "H",
69 "H",
70 func.upper(),
71 )
72 elif func == "new":
73 args = context.callArgs
74 name = args[0] if args else keywords.get("name")
75 if (
76 isinstance(name, str)
77 and name.lower() in insecureHashes
78 and keywords.get("usedforsecurity", "True") == "True"
79 ):
80 reportError(
81 context.node.lineno - 1,
82 context.node.col_offset,
83 "S332",
84 "H",
85 "H",
86 name.upper(),
87 )
88
89
90 def _hashlibNew(reportError, context, func, config):
91 """
92 Function to check for use of insecure md4, md5, sha or sha1 hash functions
93 in hashlib.new().
94
95 @param reportError function to be used to report errors
96 @type func
97 @param context security context object
98 @type SecurityContext
99 @param func name of the hash function
100 @type str
101 @param config dictionary with configuration data
102 @type dict
103 """
104 insecureHashes = (
105 [h.lower() for h in config["insecure_hashes"]]
106 if config and "insecure_hashes" in config
107 else SecurityDefaults["insecure_hashes"]
108 )
109
110 if func == "new":
111 args = context.callArgs
112 keywords = context.callKeywords
113 name = args[0] if args else keywords.get("name")
114 if isinstance(name, str) and name.lower() in insecureHashes:
115 reportError(
116 context.node.lineno - 1,
117 context.node.col_offset,
118 "S331",
119 "M",
120 "H",
121 name.upper(),
122 )
123
124
125 def _cryptCrypt(reportError, context, func, config):
126 """
127 Function to check for use of insecure md4, md5, sha or sha1 hash functions
128 in crypt.crypt().
129
130 @param reportError function to be used to report errors
131 @type func
132 @param context security context object
133 @type SecurityContext
134 @param func name of the hash function
135 @type str
136 @param config dictionary with configuration data
137 @type dict
138 """
139 insecureHashes = (
140 [h.lower() for h in config["insecure_hashes"]]
141 if config and "insecure_hashes" in config
142 else SecurityDefaults["insecure_hashes"]
143 )
144
145 args = context.callArgs
146 keywords = context.callKeywords
147
148 if func == "crypt":
149 name = args[1] if len(args) > 1 else keywords.get("salt")
150 if isinstance(name, str) and name in insecureHashes:
151 reportError(
152 context.node.lineno - 1,
153 context.node.col_offset,
154 "S331",
155 "M",
156 "H",
157 name.upper(),
158 )
159
160 elif func == "mksalt":
161 name = args[0] if args else keywords.get("method")
162 if isinstance(name, str) and name in insecureHashes:
163 reportError(
164 context.node.lineno - 1,
165 context.node.col_offset,
166 "S331",
167 "M",
168 "H",
169 name.upper(),
170 )
171
172
173 def checkHashlib(reportError, context, config):
174 """
175 Function to check for use of insecure md4, md5, sha or sha1 hash functions
176 in hashlib.new().
177
178 @param reportError function to be used to report errors
179 @type func
180 @param context security context object
181 @type SecurityContext
182 @param config dictionary with configuration data
183 @type dict
184 """
185 if isinstance(context.callFunctionNameQual, str):
186 qualnameList = context.callFunctionNameQual.split(".")
187 func = qualnameList[-1]
188
189 if "hashlib" in qualnameList:
190 if sys.version_info >= (3, 9):
191 _hashlibFunc(reportError, context, func, config)
192 else:
193 _hashlibNew(reportError, context, func, config)
194 elif "crypt" in qualnameList and func in ("crypt", "mksalt"):
195 _cryptCrypt(reportError, context, func, config)

eric ide

mercurial