Example #1
0
 def test_matchWildcardUrls(self):
     urls = [
         '//vk.com/swf/video.swf',
         '//ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/charts/assets/charts.swf'
     ]
     self.assertEqual(Util.matchWildcardUrls('https://*.vk.com', urls),
                      None)
     self.assertEqual(
         Util.matchWildcardUrls('https://ajax.googleapis.com', urls),
         urlparse(
             '//ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/charts/assets/charts.swf'
         ))
     self.assertEqual(
         Util.matchWildcardUrls('https://*.googleapis.com', urls),
         urlparse(
             '//ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/charts/assets/charts.swf'
         ))
     self.assertEqual(Util.matchWildcardUrls(None, urls), None)
     self.assertEqual(
         Util.matchWildcardUrls('https://*.googleapis.com', None), None)
     self.assertEqual(
         Util.matchWildcardUrls('https://*.googleapis.com', []), None)
     self.assertEqual(
         Util.matchWildcardUrls('*.googleapis.com', urls),
         urlparse(
             '//ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/charts/assets/charts.swf'
         ))
    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
    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