Пример #1
0
def get_header_issues(res: Response, raw: str, url: str) -> List[Result]:
    results: List[Result] = []

    try:
        headers = res.headers

        if "X-Powered-By" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'X-Powered-By Header Present: {headers["X-Powered-By"]} ({url})',
                    Vln.HTTP_HEADER_X_POWERED_BY,
                ))

            # check to see if this is a php version
            results += php.check_version(headers["X-Powered-By"], raw, url)

        if "X-XSS-Protection" in headers:
            # header is present, check the value
            if "0" in headers["X-XSS-Protection"]:
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f"X-XSS-Protection Disabled Header Present ({url})",
                        Vln.HTTP_HEADER_X_XSS_PROTECTION_DISABLED,
                    ))
        else:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-XSS-Protection Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_XSS_PROTECTION_MISSING,
                ))

        if "X-Runtime" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Runtime Header Present; likely indicates a RoR application ({url})",
                    Vln.HTTP_HEADER_X_RUNTIME,
                ))

        if "X-Backend-Server" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'X-Backend-Server Header Present: {headers["X-Backend-Server"]} ({url})',
                    Vln.HTTP_HEADER_X_BACKEND_SERVER,
                ))

        if "Via" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'Via Header Present: #{headers["Via"]} ({url})',
                    Vln.HTTP_HEADER_VIA,
                ))

        if "X-Frame-Options" in headers:
            if "allow" in str(headers["X-Frame-Options"]).lower():
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f'X-Frame-Options Header: {headers["X-Frame-Options"]} ({url})',
                        Vln.HTTP_HEADER_X_FRAME_OPTIONS_ALLOW,
                    ))
        else:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Frame-Options Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_FRAME_OPTIONS_MISSING,
                ))

        if "X-Content-Type-Options" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Content-Type-Options Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_CONTENT_TYPE_OPTIONS_MISSING,
                ))

        if "Content-Security-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Content-Security-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_CONTENT_SECURITY_POLICY_MISSING,
                ))

        if "Referrer-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Referrer-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_REFERRER_POLICY_MISSING,
                ))

        if "Feature-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Feature-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_FEATURE_POLICY_MISSING,
                ))

        if "Access-Control-Allow-Origin" in headers:
            if headers["Access-Control-Allow-Origin"] == "*":
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f"Access-Control-Allow-Origin: Unrestricted ({url})",
                        Vln.HTTP_HEADER_CORS_ACAO_UNRESTRICTED,
                    ))

        if "Strict-Transport-Security" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Strict-Transport-Security Header Not Present ({url})",
                    Vln.HTTP_HEADER_HSTS_MISSING,
                ))

        if "Server" in headers:
            results += get_server_banner_issues(headers["Server"], raw, url,
                                                headers)
    except Exception:
        output.debug_exception()

    return results
Пример #2
0
def get_header_issues(res: Response, raw: str, url: str) -> List[Result]:
    results: List[Result] = []

    try:
        headers = res.headers

        if "X-Powered-By" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'X-Powered-By Header Present: {headers["X-Powered-By"]} ({url})',
                    Vln.HTTP_HEADER_X_POWERED_BY,
                )
            )

            # check to see if this is a php version
            results += php.check_version(headers["X-Powered-By"], raw, url)

        if "X-XSS-Protection" in headers:
            # header is present, check the value
            if "0" in headers["X-XSS-Protection"]:
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f"X-XSS-Protection Disabled Header Present ({url})",
                        Vln.HTTP_HEADER_X_XSS_PROTECTION_DISABLED,
                    )
                )
        else:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-XSS-Protection Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_XSS_PROTECTION_MISSING,
                )
            )

        if "X-Runtime" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Runtime Header Present; likely indicates a RoR application ({url})",
                    Vln.HTTP_HEADER_X_RUNTIME,
                )
            )

        if "X-Backend-Server" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'X-Backend-Server Header Present: {headers["X-Backend-Server"]} ({url})',
                    Vln.HTTP_HEADER_X_BACKEND_SERVER,
                )
            )

        if "Via" in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f'Via Header Present: #{headers["Via"]} ({url})',
                    Vln.HTTP_HEADER_VIA,
                )
            )

        if "X-Frame-Options" in headers:
            if "allow" in str(headers["X-Frame-Options"]).lower():
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f'X-Frame-Options Header: {headers["X-Frame-Options"]} ({url})',
                        Vln.HTTP_HEADER_X_FRAME_OPTIONS_ALLOW,
                    )
                )
        else:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Frame-Options Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_FRAME_OPTIONS_MISSING,
                )
            )

        if "X-Content-Type-Options" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"X-Content-Type-Options Header Not Present ({url})",
                    Vln.HTTP_HEADER_X_CONTENT_TYPE_OPTIONS_MISSING,
                )
            )

        if "Content-Security-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Content-Security-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_CONTENT_SECURITY_POLICY_MISSING,
                )
            )

        if "Referrer-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Referrer-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_REFERRER_POLICY_MISSING,
                )
            )

        if "Feature-Policy" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Feature-Policy Header Not Present ({url})",
                    Vln.HTTP_HEADER_FEATURE_POLICY_MISSING,
                )
            )

        if "Access-Control-Allow-Origin" in headers:
            if headers["Access-Control-Allow-Origin"] == "*":
                results.append(
                    Result.from_evidence(
                        Evidence.from_response(res),
                        f"Access-Control-Allow-Origin: Unrestricted ({url})",
                        Vln.HTTP_HEADER_CORS_ACAO_UNRESTRICTED,
                    )
                )

        if "Strict-Transport-Security" not in headers:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(res),
                    f"Strict-Transport-Security Header Not Present ({url})",
                    Vln.HTTP_HEADER_HSTS_MISSING,
                )
            )

        if "Server" in headers:
            results += get_server_banner_issues(headers["Server"], raw, url, headers)

        # check to see if any headers are duplicated.
        # we have to access a private member, as it's the only access to the raw headers
        if res.raw._original_response is not None:
            raw_headers = str(res.raw._original_response.headers).splitlines(False)
            raw_headers_checked: List[str] = []

            for raw_header in raw_headers:
                header_name = raw_header.split(":")[0]

                if header_name not in raw_headers_checked:
                    raw_headers_checked.append(header_name)

                    for dup in raw_headers:
                        dup_name = dup.split(":")[0]

                        if dup_name == header_name and dup != raw_header:
                            # we have a second header, with a different value
                            results.append(
                                Result.from_evidence(
                                    Evidence.from_response(res),
                                    f"Header {header_name} set multiple times with different values at {url}",
                                    Vln.HTTP_HEADER_DUPLICATE,
                                )
                            )

                            break
    except Exception:
        output.debug_exception()

    return results
Пример #3
0
def check_banner(banner: str, raw: str, url: str) -> List[Result]:
    # don't bother if this doesn't look like Apache
    if "Apache" not in banner or "Apache-" in banner:
        return []

    results = []

    if "/" in banner:
        # this means that we have a version
        modules = banner.split(" ")

        # double check that we have a '/' in the first part
        if "/" in modules[0]:
            # we have a version
            results.append(
                Result(
                    f"Apache Server Version Exposed: {modules[0]}",
                    Vulnerabilities.HTTP_BANNER_APACHE_VERSION,
                    url,
                    raw,
                ))

            # parse the version, and get the latest version - see if the server is up to date
            ver = cast(version.Version,
                       version.parse(modules[0].split("/")[1]))
            curr_version = version_checker.get_latest_version(
                "apache_httpd", ver)

            if curr_version is not None and curr_version > ver:
                results.append(
                    Result(
                        f"Apache Server Outdated: {ver} - Current: {curr_version}",
                        Vulnerabilities.SERVER_APACHE_OUTDATED,
                        url,
                        raw,
                    ))

        # check to see what else we have
        if len(modules) > 1:
            if modules[1].startswith("("):
                # this is a distro string, garbage
                modules.remove(modules[1])

            for module in modules:
                if module.startswith("PHP/"):
                    results += php.check_version(module, raw, url)

                if module.startswith("OpenSSL/"):
                    results.append(
                        Result(
                            f"OpenSSL Version Exposed: {module}",
                            Vulnerabilities.HTTP_BANNER_OPENSSL_VERSION,
                            url,
                            raw,
                        ))

    else:
        # this means that it's just a generic 'Apache' banner, with no info
        results.append(
            Result(
                "Generic Apache Server Banner Found",
                Vulnerabilities.HTTP_BANNER_GENERIC_APACHE,
                url,
                raw,
            ))

    return results