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

branch
eric7
changeset 10503
6a37b6ac3928
parent 10439
21c28b0f9e41
child 10507
d1c6608155ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/prohibitedCalls.py	Tue Jan 16 14:18:52 2024 +0100
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2020 - 2024 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing checks for prohibited methods and functions.
+"""
+
+#
+# This is a modified version of the one found in the bandit package.
+#
+# Original Copyright 2016 Hewlett-Packard Development Company, L.P.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+import ast
+import fnmatch
+import sys
+
+import AstUtilities
+
+_prohibitedCalls = {
+    "S301": (
+        [
+            "pickle.loads",
+            "pickle.load",
+            "pickle.Unpickler",
+            "cPickle.loads",
+            "cPickle.load",
+            "cPickle.Unpickler",
+            "dill.loads",
+            "dill.load",
+            "dill.Unpickler",
+            "shelve.open",
+            "shelve.DbfilenameShelf",
+        ],
+        "M",
+    ),
+    "S302": (["marshal.load", "marshal.loads"], "M"),
+}
+if sys.version_info >= (3, 9):
+    _prohibitedCalls["S303"] = (
+        [
+            "Crypto.Hash.MD2.new",
+            "Crypto.Hash.MD4.new",
+            "Crypto.Hash.MD5.new",
+            "Crypto.Hash.SHA.new",
+            "Cryptodome.Hash.MD2.new",
+            "Cryptodome.Hash.MD4.new",
+            "Cryptodome.Hash.MD5.new",
+            "Cryptodome.Hash.SHA.new",
+            "cryptography.hazmat.primitives.hashes.MD5",
+            "cryptography.hazmat.primitives.hashes.SHA1",
+        ],
+        "M",
+    )
+else:
+    _prohibitedCalls["S303"] = (
+        [
+            "hashlib.md4",
+            "hashlib.md5",
+            "hashlib.sha",
+            "hashlib.sha1",
+            "Crypto.Hash.MD2.new",
+            "Crypto.Hash.MD4.new",
+            "Crypto.Hash.MD5.new",
+            "Crypto.Hash.SHA.new",
+            "Cryptodome.Hash.MD2.new",
+            "Cryptodome.Hash.MD4.new",
+            "Cryptodome.Hash.MD5.new",
+            "Cryptodome.Hash.SHA.new",
+            "cryptography.hazmat.primitives.hashes.MD5",
+            "cryptography.hazmat.primitives.hashes.SHA1",
+        ],
+        "M",
+    )
+
+_prohibitedCalls.update(
+    {
+        "S304": (
+            [
+                "Crypto.Cipher.ARC2.new",
+                "Crypto.Cipher.ARC4.new",
+                "Crypto.Cipher.Blowfish.new",
+                "Crypto.Cipher.DES.new",
+                "Crypto.Cipher.XOR.new",
+                "Cryptodome.Cipher.ARC2.new",
+                "Cryptodome.Cipher.ARC4.new",
+                "Cryptodome.Cipher.Blowfish.new",
+                "Cryptodome.Cipher.DES.new",
+                "Cryptodome.Cipher.XOR.new",
+                "cryptography.hazmat.primitives.ciphers.algorithms.ARC4",
+                "cryptography.hazmat.primitives.ciphers.algorithms.Blowfish",
+                "cryptography.hazmat.primitives.ciphers.algorithms.IDEA",
+            ],
+            "H",
+        ),
+        "S305": (["cryptography.hazmat.primitives.ciphers.modes.ECB"], "M"),
+        "S306": (["tempfile.mktemp"], "M"),
+        "S307": (["eval"], "M"),
+        "S308": (["django.utils.safestring.mark_safe"], "M"),
+        "S309": (
+            [
+                "httplib.HTTPSConnection",
+                "http.client.HTTPSConnection",
+                "six.moves.http_client.HTTPSConnection",
+            ],
+            "M",
+        ),
+        "S310": (
+            [
+                "urllib.urlopen",
+                "urllib.request.urlopen",
+                "urllib.urlretrieve",
+                "urllib.request.urlretrieve",
+                "urllib.URLopener",
+                "urllib.request.URLopener",
+                "urllib.FancyURLopener",
+                "urllib.request.FancyURLopener",
+                "urllib2.urlopen",
+                "urllib2.Request",
+                "six.moves.urllib.request.urlopen",
+                "six.moves.urllib.request.urlretrieve",
+                "six.moves.urllib.request.URLopener",
+                "six.moves.urllib.request.FancyURLopener",
+            ],
+            "",
+        ),
+        "S311": (
+            [
+                "random.random",
+                "random.randrange",
+                "random.randint",
+                "random.choice",
+                "random.choices",
+                "random.uniform",
+                "random.triangular",
+            ],
+            "L",
+        ),
+        "S312": (["telnetlib.*"], "H"),
+        "S313": (
+            [
+                "xml.etree.cElementTree.parse",
+                "xml.etree.cElementTree.iterparse",
+                "xml.etree.cElementTree.fromstring",
+                "xml.etree.cElementTree.XMLParser",
+            ],
+            "M",
+        ),
+        "S314": (
+            [
+                "xml.etree.ElementTree.parse",
+                "xml.etree.ElementTree.iterparse",
+                "xml.etree.ElementTree.fromstring",
+                "xml.etree.ElementTree.XMLParser",
+            ],
+            "M",
+        ),
+        "S315": (["xml.sax.expatreader.create_parser"], "M"),
+        "S316": (
+            ["xml.dom.expatbuilder.parse", "xml.dom.expatbuilder.parseString"],
+            "M",
+        ),
+        "S317": (["xml.sax.parse", "xml.sax.parseString", "xml.sax.make_parser"], "M"),
+        "S318": (["xml.dom.minidom.parse", "xml.dom.minidom.parseString"], "M"),
+        "S319": (["xml.dom.pulldom.parse", "xml.dom.pulldom.parseString"], "M"),
+        "S320": (
+            [
+                "lxml.etree.parse",
+                "lxml.etree.fromstring",
+                "lxml.etree.RestrictedElement",
+                "lxml.etree.GlobalParserTLS",
+                "lxml.etree.getDefaultParser",
+                "lxml.etree.check_docinfo",
+            ],
+            "M",
+        ),
+        "S321": (["ftplib.*"], "H"),
+        "S322": (["input"], "H"),
+        "S323": (["ssl._create_unverified_context"], "M"),
+        "S324": (["os.tempnam", "os.tmpnam"], "M"),
+    }
+)
+
+
+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
+    """
+    return {
+        "Call": [
+            (checkProhibitedCalls, tuple(_prohibitedCalls)),
+        ],
+    }
+
+
+def checkProhibitedCalls(reportError, context, config):  # noqa: U100
+    """
+    Function to check for prohibited method calls.
+
+    @param reportError function to be used to report errors
+    @type func
+    @param context security context object
+    @type SecurityContext
+    @param config dictionary with configuration data
+    @type dict
+    """
+    nodeType = context.node.__class__.__name__
+
+    if nodeType == "Call":
+        func = context.node.func
+        if isinstance(func, ast.Name) and func.id == "__import__":
+            if len(context.node.args):
+                if AstUtilities.isString(context.node.args[0]):
+                    name = context.node.args[0].s
+                else:
+                    name = "UNKNOWN"
+            else:
+                name = ""  # handle '__import__()'
+        else:
+            name = context.callFunctionNameQual
+            # In the case the Call is an importlib.import, treat the first
+            # argument name as an actual import module name.
+            # Will produce None if argument is not a literal or identifier.
+            if name in ["importlib.import_module", "importlib.__import__"]:
+                name = context.callArgs[0]
+
+        for code in _prohibitedCalls:
+            qualnames, severity = _prohibitedCalls[code]
+            for qualname in qualnames:
+                if name and fnmatch.fnmatch(name, qualname):
+                    reportError(
+                        context.node.lineno - 1,
+                        context.node.col_offset,
+                        code,
+                        severity,
+                        "H",
+                        name,
+                    )

eric ide

mercurial