Пример #1
0
 def normalizeDirectiveValue(self, directiveValue):
     directiveValue = directiveValue.strip()
     directiveValueLower = directiveValue.lower()
     if self.directivekeyword:
         if self.directivekeyword.isKeyword(directiveValueLower):
             return self.directivekeyword[directiveValueLower]
         elif self.directivekeyword.isValue(directiveValueLower):
             return self.directivekeyword(directiveValueLower)
         elif Util.isUrlScheme(directiveValue):
             return directiveValueLower
     return directiveValue
    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
Пример #3
0
 def test_isUrlSchemeInvalid(self):
     self.assertFalse(Util.isUrlScheme('noscheme'))
Пример #4
0
 def test_isUrlSchemeHttps(self):
     self.assertTrue(Util.isUrlScheme('https:'))
Пример #5
0
 def test_isUrlSchemeNone(self):
     self.assertFalse(Util.isUrlScheme(None))
    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