3 # Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
3 # Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
4 # |
4 # |
5 |
5 |
6 |
6 |
7 """ |
7 """ |
8 Module implementing message translations for the code style plugin messages. |
8 Module implementing message translations for the code style plugin messages |
|
9 (security part). |
9 """ |
10 """ |
10 |
11 |
11 |
|
12 from PyQt5.QtCore import QCoreApplication |
12 from PyQt5.QtCore import QCoreApplication |
13 |
13 |
14 |
14 _securityMessages = { |
15 __all__ = ["getTranslatedMessage"] |
15 # assert used |
16 |
16 "S101": QCoreApplication.translate( |
17 _messages = { |
17 "Security", |
|
18 "Use of assert detected. The enclosed code will be removed when" |
|
19 " compiling to optimised byte code."), |
|
20 |
|
21 # flask app |
|
22 "S201": QCoreApplication.translate( |
|
23 "Security", |
|
24 "A Flask app appears to be run with debug=True, which exposes the" |
|
25 " Werkzeug debugger and allows the execution of arbitrary code."), |
|
26 |
|
27 # blacklisted calls |
18 "S301": QCoreApplication.translate( |
28 "S301": QCoreApplication.translate( |
19 "Security", |
29 "Security", |
20 "Pickle and modules that wrap it can be unsafe when used to " |
30 "Pickle and modules that wrap it can be unsafe when used to " |
21 "deserialize untrusted data, possible security issue."), |
31 "deserialize untrusted data, possible security issue."), |
22 "S302": QCoreApplication.translate( |
32 "S302": QCoreApplication.translate( |
23 "Security", |
33 "Security", |
24 "Deserialization with the marshal module is possibly dangerous."), |
34 "Deserialization with the marshal module is possibly dangerous."), |
25 "S303": QCoreApplication.translate( |
35 "S303": QCoreApplication.translate( |
26 "Security", |
36 "Security", |
27 "Use of insecure MD2, MD4, MD5, or SHA1 hash function."), |
37 "Use of insecure MD2, MD4, MD5, or SHA1 hash function."), |
|
38 "S304": QCoreApplication.translate( |
|
39 "Security", |
|
40 "Use of insecure cipher '{0}'. Replace with a known secure cipher" |
|
41 " such as AES."), |
|
42 "S305": QCoreApplication.translate( |
|
43 "Security", |
|
44 "Use of insecure cipher mode '{0}'."), |
|
45 "S306": QCoreApplication.translate( |
|
46 "Security", |
|
47 "Use of insecure and deprecated function (mktemp)."), |
|
48 "S307": QCoreApplication.translate( |
|
49 "Security", |
|
50 "Use of possibly insecure function - consider using safer" |
|
51 " ast.literal_eval."), |
|
52 "S308": QCoreApplication.translate( |
|
53 "Security", |
|
54 "Use of mark_safe() may expose cross-site scripting vulnerabilities" |
|
55 " and should be reviewed."), |
|
56 "S309": QCoreApplication.translate( |
|
57 "Security", |
|
58 "Use of HTTPSConnection on older versions of Python prior to 2.7.9" |
|
59 " and 3.4.3 do not provide security, see" |
|
60 " https://wiki.openstack.org/wiki/OSSN/OSSN-0033"), |
|
61 "S310": QCoreApplication.translate( |
|
62 "Security", |
|
63 "Audit url open for permitted schemes. Allowing use of file:/ or" |
|
64 " custom schemes is often unexpected."), |
|
65 "S311": QCoreApplication.translate( |
|
66 "Security", |
|
67 "Standard pseudo-random generators are not suitable for" |
|
68 " security/cryptographic purposes."), |
|
69 "S312": QCoreApplication.translate( |
|
70 "Security", |
|
71 "Telnet-related functions are being called. Telnet is considered" |
|
72 " insecure. Use SSH or some other encrypted protocol."), |
|
73 "S313": QCoreApplication.translate( |
|
74 "Security", |
|
75 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
76 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
77 " or make sure defusedxml.defuse_stdlib() is called."), |
|
78 "S314": QCoreApplication.translate( |
|
79 "Security", |
|
80 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
81 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
82 " or make sure defusedxml.defuse_stdlib() is called."), |
|
83 "S315": QCoreApplication.translate( |
|
84 "Security", |
|
85 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
86 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
87 " or make sure defusedxml.defuse_stdlib() is called."), |
|
88 "S316": QCoreApplication.translate( |
|
89 "Security", |
|
90 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
91 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
92 " or make sure defusedxml.defuse_stdlib() is called."), |
|
93 "S317": QCoreApplication.translate( |
|
94 "Security", |
|
95 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
96 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
97 " or make sure defusedxml.defuse_stdlib() is called."), |
|
98 "S318": QCoreApplication.translate( |
|
99 "Security", |
|
100 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
101 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
102 " or make sure defusedxml.defuse_stdlib() is called."), |
|
103 "S319": QCoreApplication.translate( |
|
104 "Security", |
|
105 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
106 " XML attacks. Replace '{0}' with its defusedxml equivalent function" |
|
107 " or make sure defusedxml.defuse_stdlib() is called."), |
|
108 "S320": QCoreApplication.translate( |
|
109 "Security", |
|
110 "Using '{0}' to parse untrusted XML data is known to be vulnerable to" |
|
111 " XML attacks. Replace '{0}' with its defusedxml equivalent" |
|
112 " function."), |
|
113 "S321": QCoreApplication.translate( |
|
114 "Security", |
|
115 "FTP-related functions are being called. FTP is considered insecure." |
|
116 " Use SSH/SFTP/SCP or some other encrypted protocol."), |
|
117 "S322": QCoreApplication.translate( |
|
118 "Security", |
|
119 "The input method in Python 2 will read from standard input, evaluate" |
|
120 " and run the resulting string as Python source code. This is" |
|
121 " similar, though in many ways worse, than using eval. On Python 2," |
|
122 " use raw_input instead, input is safe in Python 3."), |
|
123 "S323": QCoreApplication.translate( |
|
124 "Security", |
|
125 "By default, Python will create a secure, verified SSL context for" |
|
126 " use in such classes as HTTPSConnection. However, it still allows" |
|
127 " using an insecure context via the _create_unverified_context that" |
|
128 " reverts to the previous behavior that does not validate" |
|
129 " certificates or perform hostname checks."), |
|
130 "S325": QCoreApplication.translate( |
|
131 "Security", |
|
132 "Use of os.tempnam() and os.tmpnam() is vulnerable to symlink" |
|
133 " attacks. Consider using tmpfile() instead."), |
|
134 |
|
135 # blacklisted imports |
|
136 "S401": QCoreApplication.translate( |
|
137 "Security", |
|
138 "A telnet-related module is being imported. Telnet is considered" |
|
139 " insecure. Use SSH or some other encrypted protocol."), |
|
140 "S402": QCoreApplication.translate( |
|
141 "Security", |
|
142 "A FTP-related module is being imported. FTP is considered" |
|
143 " insecure. Use SSH/SFTP/SCP or some other encrypted protocol."), |
|
144 "S403": QCoreApplication.translate( |
|
145 "Security", |
|
146 "Consider possible security implications associated with '{0}'" |
|
147 " module."), |
|
148 "S404": QCoreApplication.translate( |
|
149 "Security", |
|
150 "Consider possible security implications associated with '{0}'" |
|
151 " module."), |
|
152 "S405": QCoreApplication.translate( |
|
153 "Security", |
|
154 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
155 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
156 " package, or make sure defusedxml.defuse_stdlib() is called."), |
|
157 "S406": QCoreApplication.translate( |
|
158 "Security", |
|
159 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
160 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
161 " package, or make sure defusedxml.defuse_stdlib() is called."), |
|
162 "S407": QCoreApplication.translate( |
|
163 "Security", |
|
164 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
165 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
166 " package, or make sure defusedxml.defuse_stdlib() is called."), |
|
167 "S408": QCoreApplication.translate( |
|
168 "Security", |
|
169 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
170 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
171 " package, or make sure defusedxml.defuse_stdlib() is called."), |
|
172 "S409": QCoreApplication.translate( |
|
173 "Security", |
|
174 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
175 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
176 " package, or make sure defusedxml.defuse_stdlib() is called."), |
|
177 "S410": QCoreApplication.translate( |
|
178 "Security", |
|
179 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
180 " to XML attacks. Replace '{0}' with the equivalent defusedxml" |
|
181 " package."), |
|
182 "S411": QCoreApplication.translate( |
|
183 "Security", |
|
184 "Using '{0}' to parse untrusted XML data is known to be vulnerable" |
|
185 " to XML attacks. Use defused.xmlrpc.monkey_patch() function to" |
|
186 " monkey-patch xmlrpclib and mitigate XML vulnerabilities."), |
|
187 "S412": QCoreApplication.translate( |
|
188 "Security", |
|
189 "Consider possible security implications associated with '{0}'" |
|
190 " module."), |
|
191 "S413": QCoreApplication.translate( |
|
192 "Security", |
|
193 "The pyCrypto library and its module '{0}' are no longer actively" |
|
194 " maintained and have been deprecated. Consider using" |
|
195 " pyca/cryptography library."), |
|
196 |
|
197 # insecure certificate usage |
|
198 "S501": QCoreApplication.translate( |
|
199 "Security", |
|
200 "Requests call with verify=False disabling SSL certificate checks," |
|
201 " security issue."), |
|
202 |
|
203 # YAML load |
|
204 "S506": QCoreApplication.translate( |
|
205 "Security", |
|
206 "Use of unsafe yaml load. Allows instantiation of arbitrary objects." |
|
207 " Consider yaml.safe_load()."), |
|
208 |
|
209 # Django SQL injection |
|
210 "S610": QCoreApplication.translate( |
|
211 "Security", |
|
212 "Use of extra potential SQL attack vector."), |
|
213 "S611": QCoreApplication.translate( |
|
214 "Security", |
|
215 "Use of RawSQL potential SQL attack vector."), |
|
216 |
|
217 # Django XSS vulnerability |
|
218 "S703": QCoreApplication.translate( |
|
219 "Security", |
|
220 "Potential XSS on mark_safe() function."), |
|
221 |
|
222 ## "S": QCoreApplication.translate( |
|
223 ## "Security", |
|
224 ## ""), |
28 } |
225 } |
29 |
226 |
30 |
227 _securityMessagesSampleArgs = { |
31 _messages_sample_args = { |
228 "S304": ["Crypto.Cipher.DES"], |
|
229 "S305": ["cryptography.hazmat.primitives.ciphers.modes.ECB"], |
|
230 "S313": ["xml.etree.cElementTree.parse"], |
|
231 "S314": ["xml.etree.ElementTree.parse"], |
|
232 "S315": ["xml.sax.expatreader.create_parser"], |
|
233 "S316": ["xml.dom.expatbuilder.parse"], |
|
234 "S317": ["xml.sax.parse"], |
|
235 "S318": ["xml.dom.minidom.parse"], |
|
236 "S319": ["xml.dom.pulldom.parse"], |
|
237 "S320": ["lxml.etree.parse"], |
|
238 |
|
239 "S403": ["pickle"], |
|
240 "S404": ["subprocess"], |
|
241 "S405": ["xml.etree.ElementTree"], |
|
242 "S406": ["xml.sax"], |
|
243 "S407": ["xml.dom.expatbuilder"], |
|
244 "S408": ["xml.dom.minidom"], |
|
245 "S409": ["xml.dom.pulldom"], |
|
246 "S410": ["lxml"], |
|
247 "S411": ["xmlrpclib"], |
|
248 "S412": ["wsgiref.handlers.CGIHandler"], |
|
249 "S413": ["Crypto.Cipher"], |
32 } |
250 } |
33 |
|
34 |
|
35 def getTranslatedMessage(messageCode, messageArgs): |
|
36 """ |
|
37 Module function to get a translated and formatted message for a |
|
38 given message ID. |
|
39 |
|
40 @param messageCode the message code |
|
41 @type str |
|
42 @param messageArgs list of arguments or a single integer value to format |
|
43 the message |
|
44 @type list or int |
|
45 @return translated and formatted message |
|
46 @rtype str |
|
47 """ |
|
48 if messageCode in _messages: |
|
49 if isinstance(messageArgs, int): |
|
50 # Retranslate with correct plural form |
|
51 return _messages[messageCode](messageArgs) |
|
52 else: |
|
53 return _messages[messageCode].format(*messageArgs) |
|
54 else: |
|
55 return QCoreApplication.translate( |
|
56 "CodeStyleFixer", " no message defined for code '{0}'" |
|
57 ).format(messageCode) |
|