def check(self):
        csp = self.csp
        if not csp or not csp.parsedstring:
            return []

        findings = []

        directivesToCheck = csp.getEffectiveDirectives(
            csp.DIRECTIVES_CAUSING_XSS)

        for directive in directivesToCheck:
            values = []
            if directive in csp.parsedstring:
                values = csp[directive]

            for value in values:
                url = Util.getSchemeFreeUrl(value)
                if '*' in url and len(url) == 1:
                    findings.append(
                        Finding(
                            csp.headerkey, FindingType.PLAIN_WILDCARD,
                            directive.value +
                            ' should not allow \'*\' as source. This may enable execution of malicious JavaScript.',
                            FindingSeverity.HIGH, directive, value))

        return findings
    def checkIP(self, directive, directiveValues, findings):
        csp = self.csp
        for value in directiveValues:
            url = '//' + Util.getSchemeFreeUrl(value)
            host = urlparse(url).netloc
            ip = None
            validip = True

            try:
                ip = ipaddress.ip_address(u'' + host)
            except ValueError:
                validip = False
            if validip:
                ipString = str(ip) + ''

                if '127.0.0.1' in ipString:
                    findings.append(
                        Finding(
                            csp.headerkey, FindingType.IP_SOURCE,
                            directive.value +
                            ' directive allows localhost as source. Please make sure to remove this in production environments.',
                            FindingSeverity.INFO, directive, value))
                else:
                    findings.append(
                        Finding(
                            csp.headerkey, FindingType.IP_SOURCE,
                            directive.value +
                            ' directive has an IP-Address as source: ' +
                            ipString + ' (will be ignored by browsers!). ',
                            FindingSeverity.INFO, directive, value))
示例#3
0
    def check(self, headers, opt_options=dict()):
        policy = self.getfeaturepolicy(headers)
        if not policy or not policy.parsedstring:
            return []

        findings = []

        directivesToCheck = policy.getEffectiveDirectives()

        for directive in directivesToCheck:
            values = policy.getEffectiveValues(directive)

            for value in values:
                url = Util.getSchemeFreeUrl(value)
                if url and str(FeaturePolicyKeyword.STAR) in url and len(
                        url
                ) == 1 and directive != FeaturePolicyDirective.PICTURE_IN_PICTURE:
                    findings.append(
                        Finding(
                            policy.headerkey, FindingType.PLAIN_WILDCARD,
                            directive.value +
                            ' should not allow \'*\' as source. It enables the current page and nesting contexts, such as iframes, to use the feature. It may be better to disable and explicitly tell the iframe which feature is allowed.',
                            FindingSeverity.LOW, directive, value))

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

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

        directive = csp.getEffectiveDirective(csp.directive.OBJECT_SRC)
        objectSrcValues = []
        try:
            objectSrcValues = csp[directive]
        except KeyError:
            objectSrcValues = []
        if csp.directive.PLUGIN_TYPES in csp.parsedstring:
            pluginTypes = csp[csp.directive.PLUGIN_TYPES]
        else:
            pluginTypes = None

        if pluginTypes and not 'application/x-shockwave-flash' in pluginTypes:
            return []

        for value in objectSrcValues:
            if value == csp.keyword.NONE:
                return []

            url = '//' + Util.getSchemeFreeUrl(value)
            flashBypass = Util.matchWildcardUrls(url, bypasses)
            if (flashBypass):
                findings.append(
                    Finding(
                        csp.headerkey, FindingType.OBJECT_WHITELIST_BYPASS,
                        flashBypass.netloc +
                        ' is known to host Flash files which allow to bypass this CSP.',
                        FindingSeverity.HIGH, directive, value))
            elif (directive == csp.directive.OBJECT_SRC):
                findings.append(
                    Finding(csp.headerkey, FindingType.OBJECT_WHITELIST_BYPASS,
                            'Can you restrict object-src to \'none\' only?',
                            FindingSeverity.MEDIUM_MAYBE, directive, value))

        return findings
    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
示例#6
0
 def test_getSchemeFreeUrlNone(self):
     self.assertEqual(Util.getSchemeFreeUrl(None), None)
示例#7
0
 def test_getSchemeFreeUrlCapitals(self):
     self.assertEqual(Util.getSchemeFreeUrl('HTTPS://www.synopsys.com'),
                      'www.synopsys.com')
示例#8
0
 def test_getSchemeFreeUrlValid(self):
     self.assertEqual(Util.getSchemeFreeUrl('http://www.synopsys.com'),
                      'www.synopsys.com')
    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