예제 #1
0
    def check(self):
        csp = self.csp
        if not csp or not csp.parsedstring:
            return []

        findings = []
        if csp.directive.REPORT_URI in csp.parsedstring:
            findings.append(
                Finding(
                    csp.headerkey, FindingType.DEPRECATED_DIRECTIVE,
                    'report-uri is deprecated in CSP3. Please use the report-to directive instead.',
                    FindingSeverity.INFO, csp.directive.REPORT_URI))
            return findings
        return []
예제 #2
0
    def check(self, headers, opt_options=dict()):
        findings = []
        hsts = self.gethsts(headers)

        if not hsts:
            return findings
        if not hsts.includesubdomains():
            return [
                Finding(HSTS.headerkey, FindingType.NO_SUBDOMAINS,
                        'include subdomains was not specified.',
                        FindingSeverity.LOW, HSTS.directive.INCLUDESUBDOMAINS)
            ]

        return findings
예제 #3
0
    def mycheck(self, headers, header):
        if not header or not headers:
            return []

        if header in headers.keys() or header.lower() in headers.keys():
            value = headers[header] if header in headers.keys() else headers[
                header.lower()]
            return [
                Finding(
                    header, FindingType.DEPRECATED_HEADER, header +
                    ' header present. This header is deprecated and should not be used.',
                    FindingSeverity.INFO, None, value)
            ]
        return []
    def check(self, headers, opt_options=dict()):
        headers = self.getexposeheaders(headers)
        if not headers:
            return []

        result = []
        for header in headers.headers():
            if self.__issensitive__(header):
                result.append(
                    Finding(
                        AccessControlExposeHeaders.headerkey,
                        FindingType.SENSITIVE_HEADER_EXPOSED,
                        str(AccessControlExposeHeaders.headerkey) +
                        " exposes sensitive headers to JavaScript. An attacker can deceive the victim into browsing to an untrusted origin containing JavaScript that makes an HTTP request to the target origin. The malicious JavaScript code reads the value of the sensitive header and shares it with the attacker. If the header contains session information, the attacker can hijack the victim's session.",
                        FindingSeverity.MEDIUM, str(header), None))
        return result
예제 #5
0
    def check(self, headers, opt_options=dict()):
        findings = []
        expectct = self.getexpectct(headers)

        if not expectct:
            return findings

        findings = []
        if expectct.reporturi() and expectct.reporturi().startswith('http://'):
            findings.append(
                Finding(
                    expectct.headerkey, FindingType.SRC_HTTP,
                    expectct.headerkey +
                    'communicates its reports via an insecure channel.',
                    FindingSeverity.LOW, expectct.reporturi()))
        return findings
예제 #6
0
    def check(self):
        csp = self.csp
        if not csp or not csp.parsedstring:
            return []

        # Check if unsafe-inline is present.
        if csp.keyword.UNSAFE_INLINE in self.values or str(
                csp.keyword.UNSAFE_INLINE) in self.values:
            return [
                Finding(
                    csp.headerkey, FindingType.SCRIPT_UNSAFE_INLINE,
                    '\'' + csp.keyword.UNSAFE_INLINE.value +
                    '\' allows the execution of unsafe in-page scripts and event handlers.',
                    FindingSeverity.HIGH, self.directive,
                    csp.keyword.UNSAFE_INLINE.value)
            ]
        return []
예제 #7
0
    def check(self, headers, opt_options=dict()):
        origins = self.getorigins(headers)
        hascreds = self.getallowcreds(headers)
        findings = []

        if hascreds and hascreds.value() and origins:
            for origin in origins.origins():
                if origin.startswith('http:'):
                    findings.append(
                        Finding(
                            AccessControlAllowOrigin.headerkey,
                            FindingType.HTTP_ORIGIN,
                            str(AccessControlAllowOrigin.headerkey) +
                            " should be HTTPS rather than HTTP when " +
                            str(AccessControlAllowCredentials.headerkey) +
                            " is true", FindingSeverity.LOW, origin, None))
        return findings
    def check(self):
        csp = self.csp
        if not csp or not csp.parsedstring:
            return []

        # Check if unsafe-eval is present.
        if csp.keyword.UNSAFE_EVAL in self.values or str(
                csp.keyword.UNSAFE_EVAL) in self.values:
            return [
                Finding(
                    csp.headerkey, FindingType.SCRIPT_UNSAFE_EVAL,
                    csp.keyword.UNSAFE_EVAL.value +
                    ' allows the execution of code injected into DOM APIs such as eval().',
                    FindingSeverity.MEDIUM_MAYBE, self.directive,
                    csp.keyword.UNSAFE_EVAL.value)
            ]
        return []
예제 #9
0
    def check(self, headers, opt_options=dict()):
        xpcdp = self.getxpcdp(headers)

        if not xpcdp:
            return []

        if not xpcdp.is_none():
            directives = [str(x) for x in xpcdp.keys()]
            return [
                Finding(
                    XPermittedCrossDomainPolicies.headerkey,
                    FindingType.INSECURE_HEADER,
                    'The policy is not set to none. Make sure that you do not use flash.',
                    FindingSeverity.MEDIUM_MAYBE,
                    XPermittedCrossDomainPolicies.directive.NONE,
                    ",".join(directives))
            ]
        return []
예제 #10
0
    def mycheck(self, data):
        findings = []

        if not data:
            return findings

        for mydirective in data.keys():
            if data.directive.isDirective(mydirective):
                value = data[mydirective]
                if value:
                    valstr = ''
                    for val in value:
                        valstr = valstr + ' ' + str(val)
                else:
                    valstr = ""
                findings.append(
                    Finding(data.headerkey, FindingType.INFO_DIRECTIVE, valstr,
                            FindingSeverity.NONE, mydirective))
        return findings
    def check(self):
        csp = self.csp
        if not csp or not csp.parsedstring:
            return []
        findings = []
        directivesToCheck = self.values
        for directive in directivesToCheck:
            values = []
            if directive in csp.parsedstring:
                values = csp[directive]
            for value in values:
                if value in csp.URL_SCHEMES_CAUSING_XSS:
                    findings.append(
                        Finding(
                            csp.headerkey, FindingType.PLAIN_URL_SCHEMES,
                            value + ' URI in ' + directive.value +
                            ' allows the execution of unsafe scripts.',
                            FindingSeverity.HIGH, directive, value))

        return findings
예제 #12
0
 def check(self, headers, opt_options=dict()):
     findings = []
     headernames = ModelFactory().getheadernames()
     for header in headernames:
         hdr = ModelFactory().getheader(header)
         try:
             obj = self.extractheader(headers, hdr)
             if not obj:
                 obj = hdr("")
                 if hasattr(obj, 'required') and obj.required:
                     description = obj.description if hasattr(
                         obj, 'description') else ''
                     result = Finding(
                         header, FindingType.MISSING_HEADER,
                         str(obj.headerkey) + ' header not present. ' +
                         str(description), FindingSeverity.INFO, None)
                     findings.append(result)
         except:
             pass
     return findings
    def mycheck(self, data):
        if not hasattr(data, 'directive'):
            return []
        directive = data.directive

        if not hasattr(directive, 'requireddirectives'):
            return []
        if not directive.requireddirectives:
            return []
        result = []
        for required in directive.requireddirectives:
            required = directive(required)
            allkeys = [str(key) for key in data.keys()]
            if not required in data.keys():
                result.append(
                    Finding(data.headerkey, FindingType.MISSING_DIRECTIVES,
                            str(required) + ' directive is missing.',
                            FindingSeverity.SYNTAX, required,
                            ",".join(allkeys)))
        return result
    def check(self, opt_options=dict()):
        csp = self.csp
        if not csp:
            return []

        findings = []
        cdn = []
        if 'cdn' not in opt_options.keys():
            cdn = []
        elif 'cdn' in opt_options.keys():
            cdn = opt_options['cdn']
        effectiveScriptSrcDirective = csp.getEffectiveDirective(
            csp.directive.SCRIPT_SRC)
        scriptSrcValues = []
        try:
            scriptSrcValues = csp[effectiveScriptSrcDirective]
        except KeyError:
            scriptSrcValues = []
        for value in scriptSrcValues:
            if value.startswith('\''):
                continue
            if Util.isUrlScheme(value) or value.find('.') == -1:
                continue

            url = '//' + Util.getSchemeFreeUrl(value)
            cdnbypass = Util.matchWildcardUrls(url, cdn)
            if cdnbypass:
                bypassDomain = ''
                bypassUrl = '//' + cdnbypass.netloc + cdnbypass.path
                bypassDomain = cdnbypass.netloc
                findings.append(
                    Finding(
                        csp.headerkey, FindingType.SCRIPT_WHITELIST_BYPASS,
                        bypassDomain +
                        ' is known to host many libraries which allow to bypass this CSP. Do not whitelist all scripts of a CDN.',
                        FindingSeverity.HIGH, effectiveScriptSrcDirective,
                        value))

        return findings
    def check(self, opt_options=dict()):
        csp = self.csp
        if not csp:
            return []

        findings = []
        angular = []
        jsonp = []
        jsonpeval = []
        if 'angular' not in opt_options.keys():
            angular = []
        elif 'angular' in opt_options.keys():
            angular = opt_options['angular']
        if 'jsonp' not in opt_options.keys():
            jsonp = []
        if 'jsonp' in opt_options.keys():
            jsonp = opt_options['jsonp']
        if 'jsonpeval' not in opt_options.keys():
            jsonpeval = []
        if 'jsonpeval' in opt_options.keys():
            jsonpeval = opt_options['jsonpeval']

        effectiveScriptSrcDirective = csp.getEffectiveDirective(
            csp.directive.SCRIPT_SRC)
        scriptSrcValues = []
        try:
            scriptSrcValues = csp[effectiveScriptSrcDirective]
        except KeyError:
            scriptSrcValues = []
        for value in scriptSrcValues:
            if value == csp.keyword.SELF or value == str(csp.keyword.SELF):
                findings.append(
                    Finding(
                        csp.headerkey, FindingType.SCRIPT_WHITELIST_BYPASS,
                        '\'self\' can be problematic if you host JSONP, Angular or user uploaded files.',
                        FindingSeverity.MEDIUM_MAYBE,
                        effectiveScriptSrcDirective, value))
                continue

            if value.startswith('\''):
                continue
            if Util.isUrlScheme(value) or value.find('.') == -1:
                continue

            url = '//' + Util.getSchemeFreeUrl(value)
            angularBypass = Util.matchWildcardUrls(url, angular)
            jsonpBypass = Util.matchWildcardUrls(url, jsonp)

            if jsonpBypass:
                bypassUrl = '//' + jsonpBypass.netloc + jsonpBypass.path
                evalRequired = jsonpBypass.netloc in jsonpeval
                evalPresent = csp.keyword.UNSAFE_EVAL in scriptSrcValues
                if evalRequired and not evalPresent:
                    jsonpBypass = None
            if jsonpBypass or angularBypass:
                bypassDomain = ''
                bypassTxt = ''
                if jsonpBypass:
                    bypassDomain = jsonpBypass.netloc
                    bypassTxt = ' JSONP endpoints'
                if angularBypass:
                    bypassDomain = angularBypass.netloc
                    if not bypassTxt:
                        bypassTxt += ''
                    else:
                        bypassTxt += ' and'
                    bypassTxt += ' Angular libraries'
                    findings.append(
                        Finding(
                            csp.headerkey, FindingType.SCRIPT_WHITELIST_BYPASS,
                            bypassDomain + ' is known to host' + bypassTxt +
                            ' which allow to bypass this CSP.',
                            FindingSeverity.HIGH, effectiveScriptSrcDirective,
                            value))
            else:
                findings.append(
                    Finding(
                        csp.headerkey, FindingType.SCRIPT_WHITELIST_BYPASS,
                        'No bypass found; make sure that this URL doesn\'t serve JSONP replies or Angular libraries.',
                        FindingSeverity.MEDIUM_MAYBE,
                        effectiveScriptSrcDirective, value))
        return findings