Пример #1
0
def has_no_password_protection(path: str) -> bool:
    """
    Check if .jks files are password protected.

    :param path: path to check
    """
    if not os.path.exists(path):
        show_unknown('Path does not exist',
                     details=dict(path=path))
        return False
    jks_with_password: list = []
    jks_without_password: list = []
    for full_path in full_paths_in_dir(path):
        if not full_path.endswith('.jks'):
            continue
        try:
            jks.KeyStore.load(full_path, '')
        except jks.util.KeystoreSignatureException:
            # has password
            jks_with_password.append(dict(path=full_path,
                                          sha256=get_sha256(full_path)))
        else:
            # has not password
            jks_without_password.append(dict(path=full_path,
                                             sha256=get_sha256(full_path)))
    if jks_without_password:
        show_open('JKS is/are not password protected',
                  details=dict(jks_without_password=jks_without_password))
        return True
    show_close('JKS is/are password protected',
               details=dict(jks_with_password=jks_with_password))
    return False
Пример #2
0
def _get_requirements_pom_xml(path: str) -> list:
    """
    Get list of requirements from Maven project.

    Files supported are pom.xml

    :param path: Project path
    """
    reqs = []
    namespaces = {'xmlns': 'http://maven.apache.org/POM/4.0.0'}
    for full_path in full_paths_in_dir(path):
        if not full_path.endswith('pom.xml'):
            continue
        tree = parse(full_path)
        root = tree.getroot()
        deps = root.findall(".//xmlns:dependency", namespaces=namespaces)
        for dep in deps:
            artifact_id = dep.find("xmlns:artifactId", namespaces=namespaces)
            version = dep.find("xmlns:version", namespaces=namespaces)
            if version is not None:
                if version.text.startswith('$'):
                    reqs.append((full_path, artifact_id.text, None))
                else:
                    reqs.append((full_path, artifact_id.text, version.text))
            else:
                reqs.append((full_path, artifact_id.text, None))
    return reqs
Пример #3
0
def _get_requirements(path: str) -> list:
    """
    Get list of requirements from NuGet project.

    Files supported are packages.config

    :param path: Project path
    """
    reqs = []
    for full_path in full_paths_in_dir(path):
        if not full_path.endswith('packages.config'):
            continue
        tree = parse(full_path)
        deps = tree.findall(".//package")
        reqs += [(dep.attrib['id'], dep.attrib['version']) for dep in deps]
    return reqs
Пример #4
0
def _use_passwords(path: str, passwords: list) -> bool:
    """
    Check if a JKS file has been protected by any of ``passwords``.

    :param path: path to check
    :param passwords: passwords to test
    """
    if not os.path.exists(path):
        show_unknown('Path does not exist',
                     details=dict(path=path))
        return False

    opened_jks: list = []
    closed_jks: list = []
    passwords = ['', *(p for p in set(passwords))]

    for full_path in full_paths_in_dir(path):
        if not full_path.endswith('.jks'):
            continue
        success: bool = False
        for password in passwords:
            try:
                jks.KeyStore.load(full_path, password)
            except jks.util.KeystoreSignatureException:
                # wrong password
                continue
            else:
                # correct password
                success = True
                break
        if success:
            opened_jks.append(dict(path=full_path,
                                   password=password,
                                   sha256=get_sha256(full_path)))
        else:
            closed_jks.append(dict(path=full_path,
                                   sha256=get_sha256(full_path)))
    if opened_jks:
        show_open('JKS is/are protected by a password from the list',
                  details=dict(opened_jks=opened_jks,
                               tested_passwords=passwords))
        return True
    show_close('JKS is/are protected by a password from the list',
               details=dict(closed_jks=closed_jks,
                            tested_passwords=passwords))
    return False
Пример #5
0
def _insecure_functions_in_dir(py_dest: str, exclude: list = None) -> bool:
    """
    Search for insecure functions in dir.

    :param py_dest: Path to a Python script or package.
    :param exclude: Paths that contains any string from this list are ignored.
    """
    if not exclude:
        exclude = []

    res = [
        _insecure_functions_in_file(full_path)
        for full_path in full_paths_in_dir(py_dest)
        if full_path.endswith(LANGUAGE_SPECS['extensions']) and not any(
            x in full_path for x in exclude)
    ]
    return list(filter(None, res))
Пример #6
0
def _get_requirements_build_gradle(path: str) -> list:
    """
    Get list of requirements from Maven project.

    Files supported are build.gradle

    :param path: Project path
    """
    reqs = []
    for file_path in full_paths_in_dir(path):
        if not file_path.endswith('build.gradle'):
            continue

        with open(file_path, encoding='latin-1') as file_fd:
            file_content = file_fd.read()

        string = MatchFirst([quotedString('"'), quotedString("'")])
        string.setParseAction(lambda x: [x[0][1:-1]])

        grammars: list = [
            Suppress(Keyword('compile') + Optional('(')) +
            string.copy()('package'),
            Suppress(Keyword('compile') + Optional('(')) +
            Suppress(Keyword('group') + ':') + string.copy()('group') +
            Suppress(',') + Suppress(Keyword('name') + ':') +
            string.copy()('name') + Suppress(',') +
            Suppress(Keyword('version') + ':') + string.copy()('version'),
        ]

        for grammar in grammars:
            for tokens, _, _ in grammar.scanString(file_content):
                matches = tokens.asDict()
                if 'package' in matches:
                    if ':' in matches['package']:
                        name, version = matches['package'].rsplit(':', 1)
                    else:
                        name, version = matches['package'], None
                    reqs.append((file_path, name, version))
                else:
                    reqs.append(
                        (file_path, f"{matches['group']}:{matches['name']}",
                         matches['version']))
                    reqs.append(
                        (file_path, matches['group'], matches['version']))
    return reqs
Пример #7
0
def path_contains_grammar(grammar: ParserElement,
                          path: str,
                          lang_spec: dict,
                          exclude: list = None) -> List[str]:
    """
    Return a dict mapping all files in path to the line with grammar matches.

    :param grammar: Grammar to be searched for in path.
    :param path: Path to the destination file.
    :param lang_spec: Contains language-specific syntax elements, such as
                      acceptable file extensions and comment delimiters.
    """
    vulns = {}
    exclude = exclude if exclude else tuple()
    extensions = lang_spec.get('extensions')
    for full_path in full_paths_in_dir(path):
        if _path_match_extension(full_path, extensions) and \
                not any(x in full_path for x in exclude):
            vulns.update(_path_contains_grammar(grammar, full_path))
    return vulns
Пример #8
0
def _check_grammar_in_dir(grammar: ParserElement,
                          code_dest: str,
                          lang_spec: dict,
                          exclude: list = None) -> Dict[str, List[str]]:
    """
    Check grammar in directory.

    :param grammar: Pyparsing grammar against which file will be checked.
    :param code_dest: File or directory to check.
    :param lang_spec: Contains language-specific syntax elements, such as
                       acceptable file extensions and comment delimiters.
    :param exclude: Exclude files or directories with given strings
    :return: Maps files to their found vulnerabilites.
    """
    if not exclude:
        exclude = []
    vulns = {}
    for full_path in full_paths_in_dir(code_dest):
        if not any(x in full_path for x in exclude):
            vulns.update(_check_grammar_in_file(grammar, full_path, lang_spec))
    return vulns
Пример #9
0
def _get_requirements(path: str) -> set:
    """
    Get a list of requirements from NPM project.

    Files supported are package.json and package-lock.json

    :param path: Project path
    """
    reqs = set()
    if not os.path.exists(path):
        return reqs
    dictionary = {ord(c): None for c in '^~<=>'}
    for path in full_paths_in_dir(path):
        is_package = path.endswith('package.json')
        is_package_lock = path.endswith('package-lock.json')
        if is_package or is_package_lock:
            with open(path) as file:
                data = json.load(file)
            reqs.update((path, dep, ver.translate(dictionary))
                        for dep, ver in _get_all_versions(data))
    return reqs