Mon, 15 Jun 2020 19:01:02 +0200
Code Style Checker: continued to implement checker for security related issues.
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Mon Jun 15 19:01:02 2020 +0200 @@ -12,6 +12,7 @@ except ImportError: import queue +import ast import sys import multiprocessing @@ -272,6 +273,48 @@ outputQueue.put((filename, result)) +def __checkSyntax(filename, source): + """ + Private module function to perform a syntax check. + + @param filename source filename + @type str + @param source string containing the code to check + @type str + @return tuple containing the error dictionary with syntax error details + and a statistics dictionary or a tuple containing two None + @rtype tuple of (dict, dict) or tuple of (None, None) + """ + src = "".join(source) + # Check type for py2: if not str it's unicode + if sys.version_info[0] == 2: + try: + src = src.encode('utf-8') + except UnicodeError: + pass + + try: + ast.parse(src, filename, 'exec') + return None, None + except (SyntaxError, TypeError): + exc_type, exc = sys.exc_info()[:2] + if len(exc.args) > 1: + offset = exc.args[1] + if len(offset) > 2: + offset = offset[1:3] + else: + offset = (1, 0) + return ({ + "file": filename, + "line": offset[0], + "offset": offset[1], + "code": "E901", + "args": [exc_type.__name__, exc.args[0]], + }, { + "E901": 1, + }) + + def __checkCodeStyle(filename, source, args): """ Private module function to perform the code style check and/or fix @@ -340,68 +383,73 @@ else: ignore = [] - # TODO: perform syntax check and report invalid syntax once for all - - # check coding style - pycodestyle.BLANK_LINES_CONFIG = { - # Top level class and function. - 'top_level': blankLines[0], - # Methods and nested class and function. - 'method': blankLines[1], - } - styleGuide = pycodestyle.StyleGuide( - reporter=CodeStyleCheckerReport, - repeat=repeatMessages, - select=select, - ignore=ignore, - max_line_length=maxLineLength, - max_doc_length=maxDocLineLength, - hang_closing=hangClosing, - ) - report = styleGuide.check_files([filename]) - stats.update(report.counters) - errors = report.errors - - # check documentation style - docStyleChecker = DocStyleChecker( - source, filename, select, ignore, [], repeatMessages, - maxLineLength=maxDocLineLength, docType=docType) - docStyleChecker.run() - stats.update(docStyleChecker.counters) - errors += docStyleChecker.errors + syntaxError, syntaxStats = __checkSyntax(filename, source) + if syntaxError: + errors = [syntaxError] + stats.update(syntaxStats) - # miscellaneous additional checks - miscellaneousChecker = MiscellaneousChecker( - source, filename, select, ignore, [], repeatMessages, - miscellaneousArgs) - miscellaneousChecker.run() - stats.update(miscellaneousChecker.counters) - errors += miscellaneousChecker.errors - - # check code complexity - complexityChecker = ComplexityChecker( - source, filename, select, ignore, codeComplexityArgs) - complexityChecker.run() - stats.update(complexityChecker.counters) - errors += complexityChecker.errors - - # check function annotations - if sys.version_info >= (3, 5, 0): - # annotations are supported from Python 3.5 on - from AnnotationsChecker import AnnotationsChecker - annotationsChecker = AnnotationsChecker( + # perform the checks only, if syntax is ok + else: + # check coding style + pycodestyle.BLANK_LINES_CONFIG = { + # Top level class and function. + 'top_level': blankLines[0], + # Methods and nested class and function. + 'method': blankLines[1], + } + styleGuide = pycodestyle.StyleGuide( + reporter=CodeStyleCheckerReport, + repeat=repeatMessages, + select=select, + ignore=ignore, + max_line_length=maxLineLength, + max_doc_length=maxDocLineLength, + hang_closing=hangClosing, + ) + report = styleGuide.check_files([filename]) + stats.update(report.counters) + errors = report.errors + + # check documentation style + docStyleChecker = DocStyleChecker( source, filename, select, ignore, [], repeatMessages, - annotationArgs) - annotationsChecker.run() - stats.update(annotationsChecker.counters) - errors += annotationsChecker.errors - - securityChecker = SecurityChecker( - source, filename, select, ignore, [], repeatMessages, - securityArgs) - securityChecker.run() - stats.update(securityChecker.counters) - errors += securityChecker.errors + maxLineLength=maxDocLineLength, docType=docType) + docStyleChecker.run() + stats.update(docStyleChecker.counters) + errors += docStyleChecker.errors + + # miscellaneous additional checks + miscellaneousChecker = MiscellaneousChecker( + source, filename, select, ignore, [], repeatMessages, + miscellaneousArgs) + miscellaneousChecker.run() + stats.update(miscellaneousChecker.counters) + errors += miscellaneousChecker.errors + + # check code complexity + complexityChecker = ComplexityChecker( + source, filename, select, ignore, codeComplexityArgs) + complexityChecker.run() + stats.update(complexityChecker.counters) + errors += complexityChecker.errors + + # check function annotations + if sys.version_info >= (3, 5, 0): + # annotations are supported from Python 3.5 on + from AnnotationsChecker import AnnotationsChecker + annotationsChecker = AnnotationsChecker( + source, filename, select, ignore, [], repeatMessages, + annotationArgs) + annotationsChecker.run() + stats.update(annotationsChecker.counters) + errors += annotationsChecker.errors + + securityChecker = SecurityChecker( + source, filename, select, ignore, [], repeatMessages, + securityArgs) + securityChecker.run() + stats.update(securityChecker.counters) + errors += securityChecker.errors errorsDict = {} for error in errors:
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Mon Jun 15 19:01:02 2020 +0200 @@ -52,6 +52,13 @@ 'print_function', 'unicode_literals', 'generator_stop', 'annotations'] + cryptoBitSelectionsDsaRsa = [ + "512", "1024", "2048", "4096", "8192", "16384", "32786", + ] + cryptoBitSelectionsEc = [ + "160", "224", "256", "384", "512", + ] + checkCategories = { "A": QCoreApplication.translate( "CheckerCategories", @@ -121,6 +128,19 @@ itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(Qt.Unchecked) + self.dsaHighRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) + self.dsaMediumRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) + self.rsaHighRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) + self.rsaMediumRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) + self.ecHighRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsEc) + self.ecMediumRiskCombo.addItems( + CodeStyleCheckerDialog.cryptoBitSelectionsEc) + self.statisticsButton = self.buttonBox.addButton( self.tr("Statistics..."), QDialogButtonBox.ActionRole) self.statisticsButton.setToolTip( @@ -457,7 +477,30 @@ "MaximumComplexity": 3, } - # TODO: add 'SecurityChecker' + if "SecurityChecker" not in self.__data: + from .Security.SecurityDefaults import SecurityDefaults + self.__data["SecurityChecker"] = { + "HardcodedTmpDirectories": + SecurityDefaults["hardcoded_tmp_directories"], + "InsecureHashes": + SecurityDefaults["insecure_hashes"], + "InsecureSslProtocolVersions": + SecurityDefaults["insecure_ssl_protocol_versions"], + "WeakKeySizeDsaHigh": + str(SecurityDefaults["weak_key_size_dsa_high"]), + "WeakKeySizeDsaMedium": + str(SecurityDefaults["weak_key_size_dsa_medium"]), + "WeakKeySizeRsaHigh": + str(SecurityDefaults["weak_key_size_rsa_high"]), + "WeakKeySizeRsaMedium": + str(SecurityDefaults["weak_key_size_rsa_medium"]), + "WeakKeySizeEcHigh": + str(SecurityDefaults["weak_key_size_ec_high"]), + "WeakKeySizeEcMedium": + str(SecurityDefaults["weak_key_size_ec_medium"]), + "CheckTypedException": + SecurityDefaults["check_typed_exception"], + } self.__initCategoriesList(self.__data["EnabledCheckerCategories"]) self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) @@ -492,6 +535,28 @@ self.maxAnnotationsComplexitySpinBox.setValue( self.__data["AnnotationsChecker"]["MaximumComplexity"]) + # security + self.tmpDirectoriesEdit.setPlainText("\n".join( + self.__data["SecurityChecker"]["HardcodedTmpDirectories"])) + self.hashesEdit.setText(", ".join( + self.__data["SecurityChecker"]["InsecureHashes"])) + self.insecureSslProtocolsEdit.setPlainText("\n".join( + self.__data["SecurityChecker"]["InsecureSslProtocolVersions"])) + self.dsaHighRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeDsaHigh"]) + self.dsaMediumRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeDsaMedium"]) + self.rsaHighRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeRsaHigh"]) + self.rsaMediumRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeRsaMedium"]) + self.ecHighRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeEcHigh"]) + self.ecMediumRiskCombo.setCurrentText( + self.__data["SecurityChecker"]["WeakKeySizeEcMedium"]) + self.typedExceptionsCheckBox.setChecked( + self.__data["SecurityChecker"]["CheckTypedException"]) + self.__cleanupData() def start(self, fn, save=False, repeat=None): @@ -556,6 +621,8 @@ self.__cleanupData() if len(self.files) > 0: + self.securityNoteLabel.setVisible( + "S" in self.__getCategories(True, asList=True)) self.checkProgress.setMaximum(len(self.files)) self.checkProgressLabel.setVisible(len(self.files) > 1) self.checkProgress.setVisible(len(self.files) > 1) @@ -607,14 +674,41 @@ self.maxAnnotationsComplexitySpinBox.value(), } - # TODO: add 'SecurityChecker' - safetyArgs = {} + securityArgs = { + "hardcoded_tmp_directories": [ + t.strip() + for t in self.tmpDirectoriesEdit.toPlainText().splitlines() + ], + "insecure_hashes": [ + h.strip() + for h in self.hashesEdit.text().split(",") + ], + "insecure_ssl_protocol_versions": [ + p.strip() + for p in self.insecureSslProtocolsEdit.toPlainText() + .splitlines() + ], + "weak_key_size_dsa_high": + int(self.dsaHighRiskCombo.currentText()), + "weak_key_size_dsa_medium": + int(self.dsaMediumRiskCombo.currentText()), + "weak_key_size_rsa_high": + int(self.rsaHighRiskCombo.currentText()), + "weak_key_size_rsa_medium": + int(self.rsaMediumRiskCombo.currentText()), + "weak_key_size_ec_high": + int(self.ecHighRiskCombo.currentText()), + "weak_key_size_ec_medium": + int(self.ecMediumRiskCombo.currentText()), + "check_typed_exception": + self.typedExceptionsCheckBox.isChecked(), + } self.__options = [excludeMessages, includeMessages, repeatMessages, fixCodes, noFixCodes, fixIssues, maxLineLength, maxDocLineLength, blankLines, hangClosing, docType, codeComplexityArgs, miscellaneousArgs, - annotationArgs, safetyArgs] + annotationArgs, securityArgs] # now go through all the files self.progress = 0 @@ -960,9 +1054,37 @@ self.minAnnotationsCoverageSpinBox.value(), "MaximumComplexity": self.maxAnnotationsComplexitySpinBox.value(), - } - - # TODO: add 'SecurityChecker' + }, + "SecurityChecker": { + "HardcodedTmpDirectories": [ + t.strip() + for t in self.tmpDirectoriesEdit.toPlainText() + .splitlines() + ], + "InsecureHashes": [ + h.strip() + for h in self.hashesEdit.text().split(",") + ], + "InsecureSslProtocolVersions": [ + p.strip() + for p in self.insecureSslProtocolsEdit.toPlainText() + .splitlines() + ], + "WeakKeySizeDsaHigh": + self.dsaHighRiskCombo.currentText(), + "WeakKeySizeDsaMedium": + self.dsaMediumRiskCombo.currentText(), + "WeakKeySizeRsaHigh": + self.rsaHighRiskCombo.currentText(), + "WeakKeySizeRsaMedium": + self.rsaMediumRiskCombo.currentText(), + "WeakKeySizeEcHigh": + self.ecHighRiskCombo.currentText(), + "WeakKeySizeEcMedium": + self.ecMediumRiskCombo.currentText(), + "CheckTypedException": + self.typedExceptionsCheckBox.isChecked(), + }, } if data != self.__data: self.__data = data @@ -1060,7 +1182,6 @@ vm.openSourceFile(fn, lineno=lineno, pos=position + 1) editor = vm.getOpenEditor(fn) - # TODO: add other syntax errors or do syntax check once for all if code in ["E901", "E902"]: editor.toggleSyntaxError(lineno, 0, True, message, True) else: @@ -1197,7 +1318,48 @@ Preferences.Prefs.settings.value( "PEP8/MaximumAnnotationComplexity", 3))) - # TODO: add 'SecurityChecker' + # security + from .Security.SecurityDefaults import SecurityDefaults + self.tmpDirectoriesEdit.setPlainText("\n".join( + Preferences.toList(Preferences.Prefs.settings.value( + "PEP8/HardcodedTmpDirectories", + SecurityDefaults["hardcoded_tmp_directories"])))) + self.hashesEdit.setText(", ".join( + Preferences.toList(Preferences.Prefs.settings.value( + "PEP8/InsecureHashes", + SecurityDefaults["insecure_hashes"])))), + self.insecureSslProtocolsEdit.setPlainText("\n".join( + Preferences.toList(Preferences.Prefs.settings.value( + "PEP8/InsecureSslProtocolVersions", + SecurityDefaults["insecure_ssl_protocol_versions"])))), + self.dsaHighRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeDsaHigh", + str(SecurityDefaults["weak_key_size_dsa_high"]))) + self.dsaMediumRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeDsaMedium", + str(SecurityDefaults["weak_key_size_dsa_medium"]))), + self.rsaHighRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeRsaHigh", + str(SecurityDefaults["weak_key_size_rsa_high"]))), + self.rsaMediumRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeRsaMedium", + str(SecurityDefaults["weak_key_size_rsa_medium"]))), + self.ecHighRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeEcHigh", + str(SecurityDefaults["weak_key_size_ec_high"]))), + self.ecMediumRiskCombo.setCurrentText( + Preferences.Prefs.settings.value( + "PEP8/WeakKeySizeEcMedium", + str(SecurityDefaults["weak_key_size_ec_medium"]))), + self.typedExceptionsCheckBox.setChecked(Preferences.toBool( + Preferences.Prefs.settings.value( + "PEP8/CheckTypedException", + SecurityDefaults["check_typed_exception"]))), self.__cleanupData() @@ -1266,7 +1428,43 @@ "PEP8/MaximumAnnotationComplexity", self.maxAnnotationsComplexitySpinBox.value()) - # TODO: add 'SecurityChecker' + # security + Preferences.Prefs.settings.setValue( + "PEP8/HardcodedTmpDirectories", + [t.strip() + for t in self.tmpDirectoriesEdit.toPlainText().splitlines() + ]), + Preferences.Prefs.settings.setValue( + "PEP8/InsecureHashes", + [h.strip() + for h in self.hashesEdit.text().split(",") + ]), + Preferences.Prefs.settings.setValue( + "PEP8/InsecureSslProtocolVersions", + [p.strip() + for p in self.insecureSslProtocolsEdit.toPlainText().splitlines() + ]), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeDsaHigh", + self.dsaHighRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeDsaMedium", + self.dsaMediumRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeRsaHigh", + self.rsaHighRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeRsaMedium", + self.rsaMediumRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeEcHigh", + self.ecHighRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeEcMedium", + self.ecMediumRiskCombo.currentText()), + Preferences.Prefs.settings.setValue( + "PEP8/CheckTypedException", + self.typedExceptionsCheckBox.isChecked()), @pyqtSlot() def on_resetDefaultButton_clicked(self): @@ -1314,7 +1512,38 @@ Preferences.Prefs.settings.setValue( "PEP8/MaximumAnnotationComplexity", 3) - # TODO: add 'SecurityChecker' + # security + from .Security.SecurityDefaults import SecurityDefaults + Preferences.Prefs.settings.setValue( + "PEP8/HardcodedTmpDirectories", + SecurityDefaults["hardcoded_tmp_directories"]) + Preferences.Prefs.settings.setValue( + "PEP8/InsecureHashes", + SecurityDefaults["insecure_hashes"]) + Preferences.Prefs.settings.setValue( + "PEP8/InsecureSslProtocolVersions", + SecurityDefaults["insecure_ssl_protocol_versions"]) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeDsaHigh", + str(SecurityDefaults["weak_key_size_dsa_high"])) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeDsaMedium", + str(SecurityDefaults["weak_key_size_dsa_medium"])) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeRsaHigh", + str(SecurityDefaults["weak_key_size_rsa_high"])) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeRsaMedium", + str(SecurityDefaults["weak_key_size_rsa_medium"])) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeEcHigh", + str(SecurityDefaults["weak_key_size_ec_high"])) + Preferences.Prefs.settings.setValue( + "PEP8/WeakKeySizeEcMedium", + str(SecurityDefaults["weak_key_size_ec_medium"])) + Preferences.Prefs.settings.setValue( + "PEP8/CheckTypedException", + SecurityDefaults["check_typed_exception"]) # Update UI with default values self.on_loadDefaultButton_clicked()
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui Mon Jun 15 19:01:02 2020 +0200 @@ -265,7 +265,7 @@ <x>0</x> <y>0</y> <width>637</width> - <height>891</height> + <height>884</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_6"> @@ -828,6 +828,248 @@ </item> </layout> </widget> + <widget class="QWidget" name="securityOptionsTab"> + <attribute name="title"> + <string>Security Options</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_7"> + <item row="0" column="0"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>Hardcoded 'tmp' Directories:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox_11"> + <property name="title"> + <string>Weak Cryptographic Keys</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="QGroupBox" name="groupBox_12"> + <property name="title"> + <string>DSA</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>High Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="dsaHighRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which a DSA key is to be considered very weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_25"> + <property name="text"> + <string>Medium Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="dsaMediumRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which a DSA key is to be considered weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>324</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_13"> + <property name="title"> + <string>RSA</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <item> + <widget class="QLabel" name="label_26"> + <property name="text"> + <string>High Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="rsaHighRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which a RSA key is to be considered very weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_27"> + <property name="text"> + <string>Medium Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="rsaMediumRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which a RSA key is to be considered weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_14"> + <property name="title"> + <string>Elliptic Curves</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="label_28"> + <property name="text"> + <string>High Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="ecHighRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which an Elliptic Curve is to be considered very weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_29"> + <property name="text"> + <string>Medium Risk:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="ecMediumRiskCombo"> + <property name="toolTip"> + <string>Select the bit length below which an Elliptic Curve is to be considered weak</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_10"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="1"> + <widget class="QPlainTextEdit" name="insecureSslProtocolsEdit"> + <property name="toolTip"> + <string>Enter the names of insecure SSL protocols and methods (one per line)</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_23"> + <property name="text"> + <string>Insecure SSL Protocols:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_22"> + <property name="text"> + <string>Insecure Hashes:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="E5ClearableLineEdit" name="hashesEdit"> + <property name="toolTip"> + <string>Enter a list of hash methods to be considered insecure separated by comma</string> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QCheckBox" name="typedExceptionsCheckBox"> + <property name="toolTip"> + <string>Select to also check for insecure exception handling for typed exceptions</string> + </property> + <property name="text"> + <string>Check Typed Exceptions</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPlainTextEdit" name="tmpDirectoriesEdit"> + <property name="toolTip"> + <string>Enter directory names (one per line) to be checked for</string> + </property> + </widget> + </item> + </layout> + </widget> </widget> </item> <item> @@ -907,6 +1149,13 @@ <item> <layout class="QVBoxLayout" name="verticalLayout_7"> <item> + <widget class="QLabel" name="securityNoteLabel"> + <property name="text"> + <string><b>Note:</b> Mark reviewed security issues with a "<b># secok</b>" comment.</string> + </property> + </widget> + </item> + <item> <widget class="QTreeWidget" name="resultList"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> @@ -1089,13 +1338,23 @@ <tabstop>lineComplexityScoreSpinBox</tabstop> <tabstop>minAnnotationsCoverageSpinBox</tabstop> <tabstop>maxAnnotationsComplexitySpinBox</tabstop> + <tabstop>tmpDirectoriesEdit</tabstop> + <tabstop>hashesEdit</tabstop> + <tabstop>insecureSslProtocolsEdit</tabstop> + <tabstop>dsaHighRiskCombo</tabstop> + <tabstop>dsaMediumRiskCombo</tabstop> + <tabstop>rsaHighRiskCombo</tabstop> + <tabstop>rsaMediumRiskCombo</tabstop> + <tabstop>ecHighRiskCombo</tabstop> + <tabstop>ecMediumRiskCombo</tabstop> + <tabstop>typedExceptionsCheckBox</tabstop> + <tabstop>resetDefaultButton</tabstop> <tabstop>loadDefaultButton</tabstop> <tabstop>storeDefaultButton</tabstop> - <tabstop>resetDefaultButton</tabstop> <tabstop>startButton</tabstop> <tabstop>resultList</tabstop> + <tabstop>fixButton</tabstop> <tabstop>restartButton</tabstop> - <tabstop>fixButton</tabstop> </tabstops> <resources/> <connections>
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/blackListCalls.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/blackListCalls.py Mon Jun 15 19:01:02 2020 +0200 @@ -158,7 +158,7 @@ 'S323': ([ 'ssl._create_unverified_context'], "M"), - 'S325': ([ + 'S324': ([ 'os.tempnam', 'os.tmpnam'], "M"),
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoXssVulnerability.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/djangoXssVulnerability.py Mon Jun 15 19:01:02 2020 +0200 @@ -115,7 +115,6 @@ ) -# TODO: carry on from here class DeepAssignation(object): """ Class to perform a deep analysis of an assign.
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/insecureHashlibNew.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/insecureHashlibNew.py Mon Jun 15 19:01:02 2020 +0200 @@ -29,7 +29,7 @@ """ return { "Call": [ - (checkHashlibNew, ("S324",)), + (checkHashlibNew, ("S331",)), ], } @@ -65,7 +65,7 @@ reportError( context.node.lineno - 1, context.node.col_offset, - "S324", + "S331", "M", "H", name.upper()
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityChecker.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityChecker.py Mon Jun 15 19:01:02 2020 +0200 @@ -47,9 +47,10 @@ # insecure function calls (blacklisted) "S301", "S302", "S303", "S304", "S305", "S306", "S307", "S308", "S309", "S310", "S311", "S312", "S313", "S314", "S315", "S316", "S317", "S318", - "S319", "S320", "S321", "S322", "S323", "S325", # TODO: check S324 + "S319", "S320", "S321", "S322", "S323", "S324", + # hashlib.new - "S324", + "S331", # insecure imports (blacklisted) "S401", "S402", "S403", "S404", "S405", "S406", "S407", "S408", "S409",
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/translations.py Mon Jun 15 18:23:27 2020 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/translations.py Mon Jun 15 19:01:02 2020 +0200 @@ -166,13 +166,13 @@ " using an insecure context via the _create_unverified_context that" " reverts to the previous behavior that does not validate" " certificates or perform hostname checks."), - "S325": QCoreApplication.translate( + "S324": QCoreApplication.translate( "Security", "Use of os.tempnam() and os.tmpnam() is vulnerable to symlink" " attacks. Consider using tmpfile() instead."), # hashlib.new - "S324": QCoreApplication.translate( + "S331": QCoreApplication.translate( "Security", "Use of insecure {0} hash function."), @@ -187,11 +187,11 @@ " insecure. Use SSH/SFTP/SCP or some other encrypted protocol."), "S403": QCoreApplication.translate( "Security", - "Consider possible security implications associated with '{0}'" + "Consider possible security implications associated with the '{0}'" " module."), "S404": QCoreApplication.translate( "Security", - "Consider possible security implications associated with '{0}'" + "Consider possible security implications associated with the '{0}'" " module."), "S405": QCoreApplication.translate( "Security", @@ -384,7 +384,7 @@ "S319": ["xml.dom.pulldom.parse"], "S320": ["lxml.etree.parse"], - "S324": ["MD5"], + "S331": ["MD5"], "S403": ["pickle"], "S404": ["subprocess"],