def has_switch_without_default(js_dest: str, exclude: list = None) -> bool: r""" Check if all ``switch``\ es have a ``default`` clause. See `REQ.161 <https://fluidattacks.com/web/rules/161/>`_. See `CWE-478 <https://cwe.mitre.org/data/definitions/478.html>`_. :param js_dest: Path to a JavaScript source file or package. :param exclude: Paths that contains any string from this list are ignored. """ switch = Keyword('switch') + nestedExpr(opener='(', closer=')') switch_block = Suppress(switch) + nestedExpr(opener='{', closer='}') switch_block.ignore(cppStyleComment) switch_block.ignore(L_CHAR) switch_block.ignore(L_STRING) switch_block.addCondition(lambda x: not RE_HAVES_DEFAULT.search(str(x))) try: matches = lang.path_contains_grammar(switch_block, js_dest, LANGUAGE_SPECS, exclude) except FileNotFoundError: show_unknown('File does not exist', details=dict(code_dest=js_dest)) return False if matches: show_open('Code does not have "switch" with "default" clause', details=dict(matched=matches)) return True show_close('Code has "switch" with "default" clause', details=dict(code_dest=js_dest)) return False
def uses_insecure_cipher(java_dest: str, algorithm: str, exclude: list = None) -> bool: """ Check if code uses an insecure cipher algorithm. See `REQ.148 <https://fluidattacks.com/web/rules/148/>`_. See `REQ.149 <https://fluidattacks.com/web/rules/149/>`_. :param java_dest: Path to a Java source file or package. :param algorithm: Insecure algorithm. :param exclude: Paths that contains any string from this list are ignored. """ method = 'Cipher.getInstance("{}")'.format(algorithm.upper()) op_mode = '/' + oneOf('CBC ECB', caseless=True) padding = '/' + oneOf('NoPadding PKCS5Padding', caseless=True) algorithm = '"' + CaselessKeyword(algorithm) + Optional( op_mode + Optional(padding)) + '"' grammar = Suppress(Keyword('Cipher') + '.' + Keyword('getInstance')) + \ nestedExpr() grammar.ignore(javaStyleComment) grammar.addCondition( # Ensure that at least one token is the provided algorithm lambda tokens: tokens.asList() and any( algorithm.matches(tok) for tok in tokens[0])) try: matches = lang.path_contains_grammar(grammar, java_dest, LANGUAGE_SPECS, exclude) except FileNotFoundError: show_unknown('File does not exist', details=dict(location=java_dest)) return False if not matches: show_close('Code does not use {} method'.format(method), details=dict(location=java_dest)) return False show_open('Code uses {} method'.format(method), details=dict(matches=matches)) return True