diff --git a/.travis.yml b/.travis.yml index fd00ddc..934c3bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: python cache: pip -addons: - firefox: "45.4.0esr" os: - linux python: @@ -10,11 +8,6 @@ install: - pip install -r requirements.txt - pip install flake8 before_script: - # download and extract geckodrive to /usr/local/bin - - wget https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz - - mkdir geckodriver - - tar -xzf geckodriver-v0.23.0-linux64.tar.gz -C geckodriver - - export PATH=$PATH:$PWD/geckodriver # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/CHANGELOG.md b/CHANGELOG.md index 025e61c..bf79899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### 3.1.3 +- Removed browser engine emulation +- Fixed a few bugs +- Added a plugin to scan for outdated JS libraries +- Improved crawling and DOM scanning + ### 3.1.2 - Fixed POST data handling - Support for JSON POST data diff --git a/README.md b/README.md index 52d2cfe..1d0cbd2 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Apart from that, XSStrike has crawling, fuzzing, parameter discovery, WAF detect - Context analysis - Configurable core - WAF detection & evasion -- Browser engine integration for zero false positive rate +- Outdated JS lib scanning - Intelligent payload generator - Handmade HTML & JavaScript parser - Powerful fuzzing engine @@ -65,7 +65,6 @@ Apart from that, XSStrike has crawling, fuzzing, parameter discovery, WAF detect - [Compatibility & Dependencies](https://github.com/s0md3v/XSStrike/wiki/Compatibility-&-Dependencies) ### FAQ -- [There's some error related to `geckodriver`.](https://github.com/s0md3v/XSStrike/wiki/FAQ#theres-some-error-related-to-geckodriver) - [It says fuzzywuzzy isn't installed but it is.](https://github.com/s0md3v/XSStrike/wiki/FAQ#it-says-fuzzywuzzy-is-not-installed-but-its) - [What's up with Blind XSS?](https://github.com/s0md3v/XSStrike/wiki/FAQ#whats-up-with-blind-xss) - [Why XSStrike boasts that it is the most advanced XSS detection suite?](https://github.com/s0md3v/XSStrike/wiki/FAQ#why-xsstrike-boasts-that-it-is-the-most-advanced-xss-detection-suite) @@ -103,4 +102,5 @@ Ways to contribute Licensed under the GNU GPLv3, see [LICENSE](LICENSE) for more information. -The WAF signatures in `/db/wafSignatures.json` are taken & modified from [sqlmap](https://github.com/sqlmapproject/sqlmap). I extracted them from sqlmap's waf detection modules which can found [here](https://github.com/sqlmapproject/sqlmap/blob/master/waf/) and converted them to JSON. +The WAF signatures in `/db/wafSignatures.json` are taken & modified from [sqlmap](https://github.com/sqlmapproject/sqlmap). I extracted them from sqlmap's waf detection modules which can found [here](https://github.com/sqlmapproject/sqlmap/blob/master/waf/) and converted them to JSON.\ +`/plugins/retireJS.py` is a modified version of [retirejslib](https://github.com/FallibleInc/retirejslib/). diff --git a/core/browserEngine.py b/core/browserEngine.py deleted file mode 100644 index c4783fd..0000000 --- a/core/browserEngine.py +++ /dev/null @@ -1,28 +0,0 @@ -import re -import os -import sys -from core.config import xsschecker -from core.utils import writer -from selenium import webdriver -from selenium.webdriver.firefox.options import Options -from selenium.common.exceptions import UnexpectedAlertPresentException - -def browserEngine(response): - options = Options() - options.add_argument('--headless') - browser = webdriver.Firefox(options=options) - response = re.sub(r'', '', response) + scripts = re.findall(r'(?i)(?s)]*>(.*?)', response) for script in scripts: script = script.split('\n') num = 1 diff --git a/core/photon.py b/core/photon.py index 2c043d5..4642eb8 100644 --- a/core/photon.py +++ b/core/photon.py @@ -3,6 +3,7 @@ from re import findall from urllib.parse import urlparse +from plugins.retireJs import retireJs from core.utils import getUrl, getParams from core.requester import requester from core.zetanize import zetanize @@ -36,6 +37,7 @@ def photon(seedUrl, headers, level, threadCount, delay, timeout): inps.append({'name': name, 'value': value}) forms.append({0: {'action': url, 'method': 'get', 'inputs': inps}}) response = requester(url, params, headers, True, delay, timeout).text + retireJs(url, response) forms.append(zetanize(response)) matches = findall(r'<[aA].*href=["\']{0,1}(.*?)["\']', response) for link in matches: # iterate over the matches @@ -53,9 +55,11 @@ def photon(seedUrl, headers, level, threadCount, delay, timeout): storage.add(main_url + '/' + link) for x in range(level): urls = storage - processed # urls to crawl = all urls - urls that have been crawled + # for url in urls: + # rec(url) threadpool = concurrent.futures.ThreadPoolExecutor( max_workers=threadCount) futures = (threadpool.submit(rec, url) for url in urls) - for i, _ in enumerate(concurrent.futures.as_completed(futures)): + for i in concurrent.futures.as_completed(futures): pass return [forms, processed] diff --git a/core/requester.py b/core/requester.py index 052f92e..e379e8e 100644 --- a/core/requester.py +++ b/core/requester.py @@ -5,8 +5,7 @@ from urllib3.exceptions import ProtocolError import warnings import core.config -from core.config import globalVariables -from core.utils import converter +from core.utils import converter, getVar from core.log import setup_logger logger = setup_logger(__name__) @@ -15,9 +14,9 @@ warnings.filterwarnings('ignore') # Disable SSL related warnings def requester(url, data, headers, GET, delay, timeout): - if core.config.globalVariables['jsonData']: + if getVar('jsonData'): data = converter(data) - elif core.config.globalVariables['path']: + elif getVar('path'): url = converter(data, url) data = [] GET, POST = True, False @@ -37,7 +36,7 @@ def requester(url, data, headers, GET, delay, timeout): if GET: response = requests.get(url, params=data, headers=headers, timeout=timeout, verify=False, proxies=core.config.proxies) - elif core.config.globalVariables['jsonData']: + elif getVar('jsonData'): response = requests.get(url, json=data, headers=headers, timeout=timeout, verify=False, proxies=core.config.proxies) else: diff --git a/core/utils.py b/core/utils.py index b6ea2c3..31f9e64 100644 --- a/core/utils.py +++ b/core/utils.py @@ -163,7 +163,7 @@ def getParams(url, data, GET): if data[:1] == '?': data = data[1:] elif data: - if core.config.globalVariables['jsonData'] or core.config.globalVariables['path']: + if getVar('jsonData') or getVar('path'): params = data else: try: @@ -197,6 +197,51 @@ def writer(obj, path): def reader(path): with open(path, 'r') as f: - result = [line.strip( + result = [line.rstrip( '\n').encode('utf-8').decode('utf-8') for line in f] return result + +def js_extractor(response): + """Extract js files from the response body""" + scripts = [] + matches = re.findall(r'<(?:script|SCRIPT).*?(?:src|SRC)=([^\s>]+)', response) + for match in matches: + match = match.replace('\'', '').replace('"', '').replace('`', '') + scripts.append(match) + return scripts + + +def handle_anchor(parent_url, url): + if parent_url.count('/') > 2: + replacable = re.search(r'/[^/]*?$', parent_url).group() + if replacable != '/': + parent_url = parent_url.replace(replacable, '') + scheme = urlparse(parent_url).scheme + if url[:4] == 'http': + return url + elif url[:2] == '//': + return scheme + ':' + url + elif url[:1] == '/': + return parent_url + url + else: + if parent_url.endswith('/') or url.startswith('/'): + return parent_url + url + else: + return parent_url + '/' + url + + +def deJSON(data): + return data.replace('\\\\', '\\') + + +def getVar(name): + return core.config.globalVariables[name] + +def updateVar(name, data, mode=None): + if mode: + if mode == 'append': + core.config.globalVariables[name].append(data) + elif mode == 'add': + core.config.globalVariables[name].add(data) + else: + core.config.globalVariables[name] = data diff --git a/db/definitions.json b/db/definitions.json new file mode 100644 index 0000000..8fc5c78 --- /dev/null +++ b/db/definitions.json @@ -0,0 +1,1519 @@ +{ + "retire-example": { + "vulnerabilities" : [ + { + "below" : "0.0.2", + "severity" : "low", + "identifiers" : { + "CVE" : [ "CVE-XXXX-XXXX" ], + "bug" : "1234", + "summary" : "bug summary" + }, + "info" : [ "http://github.com/eoftedal/retire.js/" ] + } + ], + "extractors" : { + "func" : [ "retire.VERSION" ], + "filename" : [ "retire-example-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "/\\*!? Retire-example v([0-9][0-9.a-z_-]+)" ], + "hashes" : { "07f8b94c8d601a24a1914a1a92bec0e4fafda964" : "0.0.1" } + } + }, + + "jquery": { + "bowername": [ "jQuery" ], + "vulnerabilities" : [ + { + "below" : "1.6.3", + "severity" : "medium", + "identifiers" : { + "CVE": [ "CVE-2011-4969" ], + "summary": "XSS with location.hash" + }, + "info" : [ "https://nvd.nist.gov/vuln/detail/CVE-2011-4969" , "http://research.insecurelabs.org/jquery/test/", "https://bugs.jquery.com/ticket/9521" ] + }, + { + "below" : "1.9.0b1", + "identifiers": { + "CVE" : [ "CVE-2012-6708" ], + "bug": "11290", + "summary": "Selector interpreted as HTML" + }, + "severity": "medium", + "info" : [ "http://bugs.jquery.com/ticket/11290" , "https://nvd.nist.gov/vuln/detail/CVE-2012-6708", "http://research.insecurelabs.org/jquery/test/" ] + }, + { + "atOrAbove" : "1.4.0", + "below" : "1.12.0", + "identifiers": { + "issue" : "2432", + "summary": "3rd party CORS request may execute", + "CVE": [ "CVE-2015-9251" ] + }, + "severity": "medium", + "info" : [ "https://github.com/jquery/jquery/issues/2432", "http://blog.jquery.com/2016/01/08/jquery-2-2-and-1-12-released/", "https://nvd.nist.gov/vuln/detail/CVE-2015-9251", "http://research.insecurelabs.org/jquery/test/" ] + }, + { + "atOrAbove" : "1.12.3", + "below" : "3.0.0-beta1", + "identifiers": { + "issue" : "2432", + "summary": "3rd party CORS request may execute", + "CVE": [ "CVE-2015-9251" ] + }, + "severity": "medium", + "info" : [ "https://github.com/jquery/jquery/issues/2432", "http://blog.jquery.com/2016/01/08/jquery-2-2-and-1-12-released/", "https://nvd.nist.gov/vuln/detail/CVE-2015-9251", "http://research.insecurelabs.org/jquery/test/" ] + }, + { + "atOrAbove" : "1.8.0", + "below" : "1.12.0", + "identifiers": { + "CVE" : [ "CVE-2015-9251" ], + "issue" : "11974", + "summary": "parseHTML() executes scripts in event handlers" + }, + "severity": "medium", + "info" : [ "https://bugs.jquery.com/ticket/11974", "https://nvd.nist.gov/vuln/detail/CVE-2015-9251", "http://research.insecurelabs.org/jquery/test/" ] + }, + { + "atOrAbove" : "1.12.2", + "below" : "2.2.0", + "identifiers": { + "CVE" : [ "CVE-2015-9251" ], + "issue" : "11974", + "summary": "parseHTML() executes scripts in event handlers" + }, + "severity": "medium", + "info" : [ "https://bugs.jquery.com/ticket/11974", "https://nvd.nist.gov/vuln/detail/CVE-2015-9251", "http://research.insecurelabs.org/jquery/test/" ] + }, + { + "atOrAbove" : "2.2.2", + "below" : "3.0.0", + "identifiers": { + "CVE" : [ "CVE-2015-9251" ], + "issue" : "11974", + "summary": "parseHTML() executes scripts in event handlers" + }, + "severity": "medium", + "info" : [ "https://bugs.jquery.com/ticket/11974", "https://nvd.nist.gov/vuln/detail/CVE-2015-9251", "http://research.insecurelabs.org/jquery/test/" ] + } + + + + ], + "extractors" : { + "func" : [ + "(jQuery || $ || $jq || $j).fn.jquery", + "require('jquery').fn.jquery" + ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/jquery(\\.min)?\\.js" ], + "filename" : [ "jquery-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontent" : [ + "/\\*!? jQuery v([0-9][0-9.a-z_-]+)", "\\* jQuery JavaScript Library v([0-9][0-9.a-z_-]+)", + "\\* jQuery ([0-9][0-9.a-z_-]+) - New Wave Javascript", "// \\$Id: jquery.js,v ([0-9][0-9.a-z_-]+)", + "/\\*! jQuery v([0-9][0-9.a-z_-]+)", + "[^a-z]f=\"([0-9][0-9.a-z_-]+)\",.*[^a-z]jquery:f,", + "[^a-z]m=\"([0-9][0-9.a-z_-]+)\",.*[^a-z]jquery:m,", + "[^a-z.]jquery:[ ]?\"([0-9][0-9.a-z_-]+)\"", + "\\$\\.documentElement,Q=e.jQuery,Z=e\\.\\$,ee=\\{\\},te=\\[\\],ne=\"([0-9][0-9.a-z_-]+)\"" + ], + "filecontentreplace" : [ + "/var [a-z]=[a-z]\\.document,([a-z])=\"([0-9][0-9.a-z_-]+)\",([a-z])=.{130,160};\\3\\.fn=\\3\\.prototype=\\{jquery:\\1/$2/" + ], + "hashes" : {} + } + }, + "jquery-migrate" : { + "vulnerabilities" : [ + { + "below" : "1.2.0", + "severity": "medium", + "identifiers": { + "release": "jQuery Migrate 1.2.0 Released", + "summary": "cross-site-scripting" + }, + "info" : [ "http://blog.jquery.com/2013/05/01/jquery-migrate-1-2-0-released/" ] + }, + { + "below" : "1.2.2", + "severity": "medium", + "identifiers": { + "bug": "11290", + "summary": "Selector interpreted as HTML" + }, + "info" : [ "http://bugs.jquery.com/ticket/11290" , "http://research.insecurelabs.org/jquery/test/" ] + } + ], + "extractors" : { + "filename" : [ "jquery-migrate-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "/\\*!?(?:\n \\*)? jQuery Migrate(?: -)? v([0-9][0-9.a-z_-]+)" ], + "hashes" : {} + } + }, + "jquery.validator" : { + "bowername": [ "jquery-validator" ], + "vulnerabilities" : [ + ], + "extractors" : { + "func" : [ "jQuery.validation.version" ], + "filename" : [ "jquery.validation-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/jquery.validation(\\.min)?\\.js" ], + "filecontent" : [ "/\\*!?(?:\n \\*)? jQuery Validation Plugin v([0-9][0-9.a-z_-]+)" ], + "hashes" : {} + } + }, + "jquery-mobile" : { + "bowername": [ "jquery-mobile", "jquery-mobile-min", "jquery-mobile-build", "jquery-mobile-dist", "jquery-mobile-bower" ], + "vulnerabilities" : [ + { + "below" : "1.0RC2", + "severity": "high", + "identifiers": {"osvdb": ["94563", "93562", "94316", "94561", "94560"]}, + "info" : [ "http://osvdb.org/show/osvdb/94563", "http://osvdb.org/show/osvdb/94562", "http://osvdb.org/show/osvdb/94316", "http://osvdb.org/show/osvdb/94561", "http://osvdb.org/show/osvdb/94560" ] + }, + { + "below" : "1.0.1", + "severity": "high", + "identifiers": {"osvdb": ["94317"]}, + "info": [ "http://osvdb.org/show/osvdb/94317" ] + }, + { + "below" : "1.1.2", + "severity": "medium", + "identifiers": { + "issue": "4787", + "release": "http://jquerymobile.com/changelog/1.1.2/", + "summary": "location.href cross-site scripting" + }, + "info": [ "http://jquerymobile.com/changelog/1.1.2/", "https://github.com/jquery/jquery-mobile/issues/4787" ] + }, + { + "below" : "1.2.0", + "severity": "medium", + "identifiers": { + "issue": "4787", + "release": "http://jquerymobile.com/changelog/1.2.0/", + "summary": "location.href cross-site scripting" + }, + "info": [ "http://jquerymobile.com/changelog/1.2.0/", "https://github.com/jquery/jquery-mobile/issues/4787" ] + }, + { + "below" : "100.0.0", + "severity": "medium", + "identifiers": { + "summary": "open redirect leads to cross site scripting" + }, + "info": [ "http://sirdarckcat.blogspot.no/2017/02/unpatched-0day-jquery-mobile-xss.html" ] + } + ], + "extractors" : { + "func" : [ "jQuery.mobile.version" ], + "filename" : [ "jquery.mobile-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/jquery.mobile(\\.min)?\\.js" ], + "filecontent" : [ "/\\*!?(?:\n \\*)? jQuery Mobile(?: -)? v([0-9][0-9.a-z_-]+)" ], + "hashes" : {} + } + }, + "jquery-ui-dialog" : { + "bowername": [ "jquery-ui", "jquery.ui" ], + "vulnerabilities" : [ + { + "atOrAbove": "1.8.9", + "below" : "1.10.0", + "severity": "medium", + "identifiers": { + "CVE": [ "CVE-2010-5312" ], + "bug": "6016", + "summary": "Title cross-site scripting vulnerability" + }, + "info" : [ "http://bugs.jqueryui.com/ticket/6016", "https://nvd.nist.gov/vuln/detail/CVE-2010-5312" ] + }, + { + "below" : "1.12.0", + "severity": "high", + "identifiers": { + "CVE": [ "CVE-2016-7103" ], + "bug": "281", + "summary": "XSS Vulnerability on closeText option" + }, + "info" : [ "https://github.com/jquery/api.jqueryui.com/issues/281", "https://nvd.nist.gov/vuln/detail/CVE-2016-7103", "https://snyk.io/vuln/npm:jquery-ui:20160721" ] + } + ], + "extractors" : { + "func" : [ "jQuery.ui.dialog.version" ], + "filecontent" : [ + "/\\*!? jQuery UI - v([0-9][0-9.a-z_-]+)(.*\n){1,3}.*jquery\\.ui\\.dialog\\.js", + "/\\*!?[\n *]+jQuery UI ([0-9][0-9.a-z_-]+)(.*\n)*.*\\.ui\\.dialog", + "/\\*!?[\n *]+jQuery UI Dialog ([0-9][0-9.a-z_-]+)", + "/\\*!? jQuery UI - v([0-9][0-9.a-z_-]+)(.*\n){1,3}\\* Includes: .* dialog\\.js" + ], + "hashes" : {} + } + }, + "jquery-ui-autocomplete" : { + "bowername": [ "jquery-ui", "jquery.ui" ], + "vulnerabilities" : [ ], + "extractors" : { + "func" : [ "jQuery.ui.autocomplete.version" ], + "filecontent" : [ + "/\\*!? jQuery UI - v([0-9][0-9.a-z_-]+)(.*\n){1,3}.*jquery\\.ui\\.autocomplete\\.js", + "/\\*!?[\n *]+jQuery UI ([0-9][0-9.a-z_-]+)(.*\n)*.*\\.ui\\.autocomplete", + "/\\*!?[\n *]+jQuery UI Autocomplete ([0-9][0-9.a-z_-]+)", + "/\\*!? jQuery UI - v([0-9][0-9.a-z_-]+)(.*\n){1,3}\\* Includes: .* autocomplete\\.js" + ], + "hashes" : {} + } + }, + "jquery-ui-tooltip" : { + "bowername": [ "jquery-ui", "jquery.ui" ], + "vulnerabilities" : [ + { + "atOrAbove": "1.9.2", + "below" : "1.10.0", + "severity": "high", + "identifiers": { + "CVE" : [ "CVE-2012-6662" ], + "bug": "8859", + "summary": "Autocomplete cross-site scripting vulnerability" + }, + "info" : [ "http://bugs.jqueryui.com/ticket/8859", "https://nvd.nist.gov/vuln/detail/CVE-2012-6662" ] + } + ], + "extractors" : { + "func" : [ "jQuery.ui.tooltip.version" ], + "filecontent" : [ + "/\\*!? jQuery UI - v([0-9][0-9.a-z_-]+)(.*\n){1,3}.*jquery\\.ui\\.tooltip\\.js", + "/\\*!?[\n *]+jQuery UI ([0-9][0-9.a-z_-]+)(.*\n)*.*\\.ui\\.tooltip", + "/\\*!?[\n *]+jQuery UI Tooltip ([0-9][0-9.a-z_-]+)" + ], + "hashes" : {} + } + }, + "jquery.prettyPhoto" : { + "bowername": [ "jquery-prettyPhoto" ], + "vulnerabilities" : [ + { + "below" : "3.1.5", + "severity" : "high", + "identifiers" : { "CVE" : [ "CVE-2013-6837" ] }, + "info" : [ "https://nvd.nist.gov/vuln/detail/CVE-2013-6837" ] + }, + { + "below" : "3.1.6", + "severity" : "high", + "info" : [ "https://github.com/scaron/prettyphoto/issues/149", "https://blog.anantshri.info/forgotten_disclosure_dom_xss_prettyphoto" ] + } + + ], + "extractors" : { + "func" : [ "jQuery.prettyPhoto.version" ], + "filecontent" : [ + "/\\*(?:.*[\n\r]+){1,3}.*Class: prettyPhoto(?:.*[\n\r]+){1,3}.*Version: ([0-9][0-9.a-z_-]+)", + "\\.prettyPhoto[ ]?=[ ]?\\{version:[ ]?(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")\\}" + ], + "hashes" : {} + } + }, + "jPlayer" : { + "bowername": [ "jPlayer" ], + "vulnerabilities" : [ + { + "below" : "2.3.1", + "severity": "high", + "identifiers": { + "CVE": [ "CVE-2013-2023" ], + "release" : "2.3.1", + "summary" : "XSS vulnerability in actionscript/Jplayer.as in the Flash SWF component" }, + "info" : [ "http://jplayer.org/latest/release-notes/", "https://nvd.nist.gov/vuln/detail/CVE-2013-2023" ] + }, + { + "below" : "2.3.23", + "severity": "high", + "identifiers": { + "CVE": [ "CVE-2013-2022" ], + "release": "2.3.23", + "summary": "XSS vulnerabilities in actionscript/Jplayer.as in the Flash SWF component" + }, + "info" : [ "http://jplayer.org/latest/release-notes/", "https://nvd.nist.gov/vuln/detail/CVE-2013-2022" ] + }, + { + "below" : "2.2.20", + "severity": "high", + "identifiers": { + "CVE": [ "CVE-2013-1942" ], + "release": "2.2.20", + "summary": "XSS vulnerabilities in actionscript/Jplayer.as in the Flash SWF component" + }, + "info" : [ "http://jplayer.org/latest/release-notes/", "https://nvd.nist.gov/vuln/detail/CVE-2013-1942" ] + } + ], + "extractors" : { + "func" : [ "new jQuery.jPlayer().version.script" ], + "filecontent" : [ + "/\\*(?:.*[\n\r]+){1,3}.*jPlayer Plugin for jQuery(?:.*[\n\r]+){1,10}.*Version: ([0-9][0-9.a-z_-]+)" + ], + "hashes" : {} + } + }, + "knockout": { + "vulnerabilities" : [ + { + "below" : "3.5.0-beta", + "severity": "medium", + "identifiers": {"summary": "XSS injection point in attr name binding for browser IE7 and older"}, + "info" : [ "https://github.com/knockout/knockout/issues/1244" ] + } + ], + "extractors" : { + "func" : [ "ko.version" ], + "filename" : [ "knockout-([0-9][0-9.a-z_-]+)(.min)?\\.js"], + "filecontent" : [ + "\\* Knockout JavaScript library v([0-9][0-9.a-z_-]+)" + ], + "hashes" : {} + } + }, + "sessvars": { + "vulnerabilities" : [ + { + "below" : "1.01", + "severity": "low", + "identifiers": {"summary": "Unsanitized data passed to eval()"}, + "info" : [ "http://www.thomasfrank.se/sessionvars.html" ] + } + ], + "extractors" : { + "filename" : [ "sessvars-([0-9][0-9.a-z_-]+)(.min)?\\.js"], + "filecontent" : [ "sessvars ver ([0-9][0-9.a-z_-]+)"], + "hashes" : {} + } + }, + "swfobject": { + "bowername": [ "swfobject", "swfobject-bower" ], + "vulnerabilities" : [ + { + "below" : "2.1", + "severity": "medium", + "identifiers": {"summary": "DOM-based XSS"}, + "info" : [ "https://github.com/swfobject/swfobject/wiki/SWFObject-Release-Notes#swfobject-v21-beta7-june-6th-2008" ] + } + ], + "extractors" : { + "filename" : [ "swfobject_([0-9][0-9.a-z_-]+)(.min)?\\.js"], + "filecontent" : [ "SWFObject v([0-9][0-9.a-z_-]+) "], + "hashes" : {} + } + }, + + "tinyMCE" : { + "bowername": [ "tinymce", "tinymce-dist" ], + "vulnerabilities" : [ + { + "below" : "1.4.2", + "severity" : "high", + "identifiers" : { + "summary" : "Static code injection vulnerability in inc/function.base.php", + "CVE" : [ "CVE-2011-4825" ] + }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2011-4825/" ] + }, + { + "below" : "4.2.4", + "severity" : "medium", + "identifiers" : { "summary" : "xss issues with media plugin not properly filtering out some script attributes." }, + "info" : [ "https://www.tinymce.com/docs/changelog/" ] + + }, + { + "below" : "4.2.0", + "severity" : "medium", + "identifiers" : { "summary" : "FIXED so script elements gets removed by default to prevent possible XSS issues in default config implementations" }, + "info" : [ "https://www.tinymce.com/docs/changelog/" ] + + }, + { + "below" : "4.7.12", + "severity" : "medium", + "identifiers" : { "summary" : "FIXED so links with xlink:href attributes are filtered correctly to prevent XSS." }, + "info" : [ "https://www.tinymce.com/docs/changelog/" ] + + } + ], + "extractors" : { + "filecontent" : [ "// ([0-9][0-9.a-z_-]+) \\([0-9\\-]+\\)[\n\r]+.{0,1200}l=.tinymce/geom/Rect." ], + "filecontentreplace" : [ + "/tinyMCEPreInit.*majorVersion:.([0-9]+).,minorVersion:.([0-9.]+)./$1.$2/", + "/majorVersion:.([0-9]+).,minorVersion:.([0-9.]+).,.*tinyMCEPreInit/$1.$2/" + ], + "func" : [ "tinyMCE.majorVersion + '.'+ tinyMCE.minorVersion" ] + } + }, + + "YUI" : { + "bowername": [ "yui", "yui3" ], + "vulnerabilities" : [ + { + "atOrAbove" : "3.5.0" , + "below" : "3.9.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-4942" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2013-4942/" ] + }, + { + "atOrAbove" : "3.2.0" , + "below" : "3.9.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-4941" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2013-4941/" ] + }, + { + "atOrAbove" : "3.0.0", + "below" : "3.10.3", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-4940" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2013-4940/" ] + }, + { + "atOrAbove" : "3.0.0" , + "below" : "3.9.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-4939" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2013-4939/" ] + }, + { + "atOrAbove" : "2.8.0" , + "below" : "2.9.1", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2012-5883" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2012-5883/" ] + }, + { + "atOrAbove" : "2.5.0" , + "below" : "2.9.1", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2012-5882" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2012-5882/" ] + }, + { + "atOrAbove" : "2.4.0" , + "below" : "2.9.1", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2012-5881" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2012-5881/" ] + }, + { + "below" : "2.9.0", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2010-4710" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2010-4710/" ] + }, + { + "atOrAbove" : "2.8.0" , + "below" : "2.8.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2010-4209" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2010-4209/" ] + }, + { + "atOrAbove" : "2.5.0" , + "below" : "2.8.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2010-4208" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2010-4208/" ] + }, + { + "atOrAbove" : "2.4.0" , + "below" : "2.8.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2010-4207" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2010-4207/" ] + } + ], + "extractors" : { + "func" : [ "YUI.Version", "YAHOO.VERSION" ], + "filename" : [ "yui-([0-9][0-9.a-z_-]+)(.min)?\\.js"], + "filecontent" : [ "/*\nYUI ([0-9][0-9.a-z_-]+)", "/yui/license.(?:html|txt)\nversion: ([0-9][0-9.a-z_-]+)"], + "hashes" : {} + } + }, + "prototypejs" : { + "bowername": [ "prototypejs", "prototype.js", "prototypejs-bower" ], + "vulnerabilities" : [ + { + "atOrAbove" : "1.6.0", + "below" : "1.6.0.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2008-7220" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2008-7220/", "http://prototypejs.org/2008/01/25/prototype-1-6-0-2-bug-fixes-performance-improvements-and-security/" ] }, + { + "below" : "1.5.1.2", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2008-7220" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2008-7220/", "http://prototypejs.org/2008/01/25/prototype-1-6-0-2-bug-fixes-performance-improvements-and-security/" ] } + ], + "extractors" : { + "func" : [ "Prototype.Version" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/prototype(\\.min)?\\.js" ], + "filename" : [ "prototype-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "Prototype JavaScript framework, version ([0-9][0-9.a-z_-]+)", + "Prototype[ ]?=[ ]?\\{[ \r\n\t]*Version:[ ]?(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")" ], + "hashes" : {} + } + }, + "ember" : { + "vulnerabilities" : [ + { + "atOrAbove" : "1.8.0", + "below" :"1.11.4", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "atOrAbove" : "1.12.0", + "below" :"1.12.2", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "atOrAbove" : "1.13.0", + "below" : "1.13.12", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "atOrAbove" : "2.0.0", + "below" : "2.0.3", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "atOrAbove" : "2.1.0", + "below" : "2.1.2", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "atOrAbove" : "2.2.0", + "below" : "2.2.1", + "severity" : "medium", + "identifiers": {"CVE": [ "CVE-2015-7565" ] }, + "info": [ "https://groups.google.com/forum/#!topic/ember-security/OfyQkoSuppY" ] + }, + { + "below" : "1.5.0", + "severity": "medium", + "identifiers": { + "CVE": [ "CVE-2014-0046" ], + "summary": "ember-routing-auto-location can be forced to redirect to another domain" + }, + "info" : [ "https://github.com/emberjs/ember.js/blob/v1.5.0/CHANGELOG.md" ] + }, + { + "atOrAbove" : "1.3.0-*", + "below" : "1.3.2", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2014-0046" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/1h6FRgr8lXQ" ] + }, + { + "atOrAbove" : "1.2.0-*", + "below" : "1.2.2", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2014-0046" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/1h6FRgr8lXQ" ] }, + { + "atOrAbove" : "1.4.0-*", + "below" : "1.4.0-beta.2", + "severity": "high", + "identifiers": {"CVE": ["CVE-2014-0013", "CVE-2014-0014"]}, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/2kpXXCxISS4", "https://groups.google.com/forum/#!topic/ember-security/PSE4RzTi6l4" ] + }, + { + "atOrAbove" : "1.3.0-*", + "below" : "1.3.1", + "severity": "high", + "identifiers": {"CVE": ["CVE-2014-0013", "CVE-2014-0014"]}, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/2kpXXCxISS4", "https://groups.google.com/forum/#!topic/ember-security/PSE4RzTi6l4" ] + }, + { + "atOrAbove" : "1.2.0-*", + "below" : "1.2.1", + "severity": "high", + "identifiers": {"CVE": ["CVE-2014-0013", "CVE-2014-0014"]}, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/2kpXXCxISS4", "https://groups.google.com/forum/#!topic/ember-security/PSE4RzTi6l4" ] + }, + { + "atOrAbove" : "1.1.0-*", + "below" : "1.1.3", + "severity": "high", + "identifiers": {"CVE": ["CVE-2014-0013", "CVE-2014-0014"]}, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/2kpXXCxISS4", "https://groups.google.com/forum/#!topic/ember-security/PSE4RzTi6l4" ] + }, + { + "atOrAbove" : "1.0.0-*", + "below" : "1.0.1", + "severity": "high", + "identifiers": {"CVE": ["CVE-2014-0013", "CVE-2014-0014"]}, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/2kpXXCxISS4", "https://groups.google.com/forum/#!topic/ember-security/PSE4RzTi6l4" ] + }, + { + "atOrAbove" : "1.0.0-rc.1", + "below" : "1.0.0-rc.1.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "atOrAbove" : "1.0.0-rc.2", + "below" : "1.0.0-rc.2.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "atOrAbove" : "1.0.0-rc.3", + "below" : "1.0.0-rc.3.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "atOrAbove" : "1.0.0-rc.4", + "below" : "1.0.0-rc.4.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "atOrAbove" : "1.0.0-rc.5", + "below" : "1.0.0-rc.5.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "atOrAbove" : "1.0.0-rc.6", + "below" : "1.0.0-rc.6.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2013-4170" ] }, + "info" : [ "https://groups.google.com/forum/#!topic/ember-security/dokLVwwxAdM" ] + }, + { + "below" : "0.9.7.1", + "info" : [ "https://github.com/emberjs/ember.js/blob/master/CHANGELOG" ] + }, + { + "below" : "0.9.7", + "severity": "high", + "identifiers": { + "bug": "699", + "summary": "Bound attributes aren't escaped properly" + }, + "info" : [ "https://github.com/emberjs/ember.js/issues/699" ] + } + ], + "extractors" : { + "func" : [ "Ember.VERSION" ], + "uri" : [ "/(?:v)?([0-9][0-9.a-z_-]+)/ember(\\.min)?\\.js" ], + "filename" : [ "ember-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontent" : [ + "Project: Ember -(?:.*\n){9,11}// Version: v([0-9][0-9.a-z_-]+)", + "// Version: v([0-9][0-9.a-z_-]+)(.*\n){10,15}(Ember Debug|@module ember|@class ember)", + "Ember.VERSION[ ]?=[ ]?(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")" + ], + "hashes" : {} + } + }, + "dojo" : { + "vulnerabilities" : [ + { + "atOrAbove" : "0.4", + "below" : "0.4.4", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2272"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2272/" ] + }, + { + "atOrAbove" : "1.0", + "below" : "1.0.3", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2274", "CVE-2010-2273"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2274/", "http://www.cvedetails.com/cve/CVE-2010-2273/" ] + }, + { + "atOrAbove" : "1.1", + "below" : "1.1.2", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2274", "CVE-2010-2273"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2274/", "http://www.cvedetails.com/cve/CVE-2010-2273/" ] + }, + { + "atOrAbove" : "1.2", + "below" : "1.2.4", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2274", "CVE-2010-2273"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2274/", "http://www.cvedetails.com/cve/CVE-2010-2273/" ] + }, + { + "atOrAbove" : "1.3", + "below" : "1.3.3", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2274", "CVE-2010-2273"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2274/", "http://www.cvedetails.com/cve/CVE-2010-2273/" ] + }, + { + "atOrAbove" : "1.4", + "below" : "1.4.2", + "severity": "high", + "identifiers": {"CVE": ["CVE-2010-2276", "CVE-2010-2274", "CVE-2010-2273"]}, + "info" : [ "http://dojotoolkit.org/blog/dojo-security-advisory", "http://www.cvedetails.com/cve/CVE-2010-2276/", "http://www.cvedetails.com/cve/CVE-2010-2274/", "http://www.cvedetails.com/cve/CVE-2010-2273/" ] + }, + { + "below" : "1.4.2", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2010-2275" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2010-2275/"] + }, + { + "below" : "1.1", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2008-6681" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2008-6681/"] + }, + { + "below" : "1.10.10", + "severity": "medium", + "identifiers": { "PR" : "307" }, + "info" : [ "https://github.com/dojo/dojo/pull/307" , "https://dojotoolkit.org/blog/dojo-1-14-released"] + }, + { + "atOrAbove" : "1.11.0", + "below" : "1.11.6", + "severity": "medium", + "identifiers": { "PR" : "307" }, + "info" : [ "https://github.com/dojo/dojo/pull/307" , "https://dojotoolkit.org/blog/dojo-1-14-released"] + }, + { + "atOrAbove" : "1.12.0", + "below" : "1.12.4", + "severity": "medium", + "identifiers": { "PR" : "307" }, + "info" : [ "https://github.com/dojo/dojo/pull/307" , "https://dojotoolkit.org/blog/dojo-1-14-released"] + }, + { + "atOrAbove" : "1.13.0", + "below" : "1.13.1", + "severity": "medium", + "identifiers": { "PR" : "307" }, + "info" : [ "https://github.com/dojo/dojo/pull/307" , "https://dojotoolkit.org/blog/dojo-1-14-released"] + } + ], + "extractors" : { + "func" : [ "dojo.version.toString()" ], + "uri" : [ "/(?:dojo-)?([0-9][0-9.a-z_-]+)/dojo(\\.min)?\\.js" ], + "filename" : [ "dojo-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontentreplace" : [ "/dojo.version=\\{major:([0-9]+),minor:([0-9]+),patch:([0-9]+)/$1.$2.$3/"], + "hashes" : { + "73cdd262799aab850abbe694cd3bfb709ea23627" : "1.4.1", + "c8c84eddc732c3cbf370764836a7712f3f873326" : "1.4.0", + "d569ce9efb7edaedaec8ca9491aab0c656f7c8f0" : "1.0.0", + "ad44e1770895b7fa84aff5a56a0f99b855a83769" : "1.3.2", + "8fc10142a06966a8709cd9b8732f7b6db88d0c34" : "1.3.1", + "a09b5851a0a3e9d81353745a4663741238ee1b84" : "1.3.0", + "2ab48d45abe2f54cdda6ca32193b5ceb2b1bc25d" : "1.2.3", + "12208a1e649402e362f528f6aae2c614fc697f8f" : "1.2.0", + "72a6a9fbef9fa5a73cd47e49942199147f905206" : "1.1.1" + } + + } + }, + "angularjs" : { + "bowername": [ "angularjs", "angular.js" ], + "vulnerabilities" : [ + { + "atOrAbove" : "1.5.0", + "below" : "1.6.9", + "severity": "low", + "identifiers": { + "summary": "XSS through SVG if enableSvg is set" + }, + "info" : [ "https://github.com/angular/angular.js/blob/master/CHANGELOG.md#169-fiery-basilisk-2018-02-02", "https://vulnerabledoma.in/ngSanitize1.6.8_bypass.html" ] + }, + { + "atOrAbove" : "1.3.0", + "below" : "1.5.0-rc2", + "severity": "medium", + "identifiers": { + "summary": "The attribute usemap can be used as a security exploit" + }, + "info" : [ "https://github.com/angular/angular.js/blob/master/CHANGELOG.md#1230-patronal-resurrection-2016-07-21" ] + }, + { + "atOrAbove" : "1.0.0", + "below" : "1.2.30", + "severity": "medium", + "identifiers": { + "summary": "The attribute usemap can be used as a security exploit" + }, + "info" : [ "https://github.com/angular/angular.js/blob/master/CHANGELOG.md#1230-patronal-resurrection-2016-07-21" ] + }, + { + "below" : "1.6.3", + "severity": "medium", + "identifiers": { + "summary": "Universal CSP bypass via add-on in Firefox" + }, + "info" : [ "https://github.com/mozilla/addons-linter/issues/1000#issuecomment-282083435", "http://pastebin.com/raw/kGrdaypP" ] + }, + { + "below" : "1.6.3", + "severity": "medium", + "identifiers": { + "summary": "DOS in $sanitize" + }, + "info" : [ "https://github.com/angular/angular.js/blob/master/CHANGELOG.md" ] + }, + { + "below" : "1.6.5", + "severity": "low", + "identifiers": { + "summary": "XSS in $sanitize in Safari/Firefox" + }, + "info" : [ "https://github.com/angular/angular.js/commit/8f31f1ff43b673a24f84422d5c13d6312b2c4d94" ] + } + ], + "extractors" : { + "func" : [ "angular.version.full" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/angular(\\.min)?\\.js" ], + "filename" : [ "angular(?:js)?-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ + "/\\*[ \n]+AngularJS v([0-9][0-9.a-z_-]+)", + "http://errors\\.angularjs\\.org/([0-9][0-9.a-z_-]+)/" + ], + "hashes" : {} + } + }, + "backbone.js" : { + "bowername": [ "backbonejs", "backbone" ], + "vulnerabilities" : [ + { + "below" : "0.5.0", + "severity": "medium", + "identifiers": { + "release": "0.5.0", + "summary": "cross-site scripting vulnerability" + }, + "info" : [ "http://backbonejs.org/#changelog" ] + } + ], + "extractors" : { + "func" : [ "Backbone.VERSION" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/backbone(\\.min)?\\.js" ], + "filename" : [ "backbone(?:js)?-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "//[ ]+Backbone.js ([0-9][0-9.a-z_-]+)", "a=t.Backbone={}}a.VERSION=\"([0-9][0-9.a-z_-]+)\"" ], + "hashes" : {} + } + }, + "mustache.js" : { + "bowername": [ "mustache.js", "mustache" ], + "vulnerabilities" : [ + { + "below" : "0.3.1", + "severity": "high", + "identifiers": { + "bug": "112", + "summary": "execution of arbitrary javascript" + }, + "info" : [ "https://github.com/janl/mustache.js/issues/112" ] + }, + { + "below" : "2.2.1", + "severity": "medium", + "identifiers": { + "bug": "pull request 530", + "summary": "weakness in HTML escaping" + }, + "info" : [ "https://github.com/janl/mustache.js/releases/tag/v2.2.1", "https://github.com/janl/mustache.js/pull/530" ] + } + ], + "extractors" : { + "func" : [ "Mustache.version" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/mustache(\\.min)?\\.js" ], + "filename" : [ "mustache(?:js)?-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "name:\"mustache.js\",version:\"([0-9][0-9.a-z_-]+)\"", + "[^a-z]mustache.version[ ]?=[ ]?(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")", + "exports.name[ ]?=[ ]?\"mustache.js\";[\n ]*exports.version[ ]?=[ ]?(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\");" + ], + "hashes" : {} + } + }, + "handlebars.js" : { + "bowername": [ "handlebars", "handlebars.js" ], + "vulnerabilities" : [ + { + "below" : "1.0.0.beta.3", + "severity": "medium", + "identifiers": { + "summary": "poorly sanitized input passed to eval()" + }, + "info" : [ "https://github.com/wycats/handlebars.js/pull/68" ] + }, + { + "below" : "4.0.0", + "severity": "medium", + "identifiers": { + "summary": "Quoteless attributes in templates can lead to XSS" + }, + "info" : [ "https://github.com/wycats/handlebars.js/pull/1083" ] + } + ], + "extractors" : { + "func" : [ "Handlebars.VERSION" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/handlebars(\\.min)?\\.js" ], + "filename" : [ "handlebars(?:js)?-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ + "Handlebars.VERSION = \"([0-9][0-9.a-z_-]+)\";", "Handlebars=\\{VERSION:(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")", + "this.Handlebars=\\{\\};[\n\r \t]+\\(function\\([a-z]\\)\\{[a-z].VERSION=(?:'|\")([0-9][0-9.a-z_-]+)(?:'|\")", + "/\\*![\n\r \t]+handlebars v([0-9][0-9.a-z_-]+)" + ], + "hashes" : {} + } + }, + "easyXDM" : { + "vulnerabilities" : [ + { + "below" : "2.4.18", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-5212" ] }, + "info" : [ "http://blog.kotowicz.net/2013/09/exploiting-easyxdm-part-1-not-usual.html", "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5212" ] + }, + { + "below" : "2.4.19", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2014-1403" ] }, + "info" : [ "http://blog.kotowicz.net/2014/01/xssing-with-shakespeare-name-calling.html", "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1403" ] + } + ], + "extractors" : { + "uri" : [ "/(?:easyXDM-)?([0-9][0-9.a-z_-]+)/easyXDM(\\.min)?\\.js" ], + "filename" : [ "easyXDM-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ " \\* easyXDM\n \\* http://easyxdm.net/(?:\r|\n|.)+version:\"([0-9][0-9.a-z_-]+)\"", + "@class easyXDM(?:.|\r|\n)+@version ([0-9][0-9.a-z_-]+)(\r|\n)" ], + "hashes" : { "cf266e3bc2da372c4f0d6b2bd87bcbaa24d5a643" : "2.4.6"} + } + }, + + "plupload" : { + "bowername": [ "Plupload", "plupload" ], + "vulnerabilities" : [ + { + "below" : "1.5.4", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2012-2401" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2012-2401/" ] + }, + { + "below" : "1.5.5", + "severity": "high", + "identifiers": {"CVE": [ "CVE-2013-0237" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2013-0237/" ] + }, + { + "below" : "2.1.9", + "severity": "medium", + "identifiers": {"CVE": [ "CVE-2016-4566" ] }, + "info" : [ "https://github.com/moxiecode/plupload/releases" ] + } + ], + "extractors" : { + "func" : [ "plupload.VERSION" ], + "uri" : [ "/([0-9][0-9.a-z_-]+)/plupload(\\.min)?\\.js" ], + "filename" : [ "plupload-([0-9][0-9.a-z_-]+)(.min)?\\.js" ], + "filecontent" : [ "\\* Plupload - multi-runtime File Uploader(?:\r|\n)+ \\* v([0-9][0-9.a-z_-]+)", + "var g=\\{VERSION:\"([0-9][0-9.a-z_-]+)\",.*;window.plupload=g\\}" + ], + "hashes" : {} + } + }, + + "DOMPurify" : { + "bowername": [ "dompurify", "DOMPurify" ], + "vulnerabilities" : [ + { + "below" : "0.6.1", + "severity": "medium", + "identifiers": { }, + "info" : [ "https://github.com/cure53/DOMPurify/releases/tag/0.6.1" ] + }, + { + "below" : "0.8.6", + "severity": "medium", + "identifiers": { }, + "info" : [ "https://github.com/cure53/DOMPurify/releases/tag/0.8.6" ] + }, + { + "below" : "0.8.9", + "severity": "low", + "identifiers": { "summary": "safari UXSS" }, + "info" : [ "https://github.com/cure53/DOMPurify/releases/tag/0.8.9", "https://lists.ruhr-uni-bochum.de/pipermail/dompurify-security/2017-May/000006.html" ] + }, + { + "below" : "0.9.0", + "severity": "low", + "identifiers": { "summary": "safari UXSS" }, + "info" : [ "https://github.com/cure53/DOMPurify/releases/tag/0.9.0" ] + } + ], + "extractors" : { + "func" : [ "DOMPurify.version" ], + "filecontent" : [ + "DOMPurify.version = '([0-9][0-9.a-z_-]+)';", + "DOMPurify.version=\"([0-9][0-9.a-z_-]+)\"", + "DOMPurify=.[^\\r\\n]{10,500}\\.version=\"([0-9][0-9.a-z_-]+)\"" + ], + "hashes" : {} + } + }, + + "react" : { + "vulnerabilities" : [ + { + "atOrAbove" : "0.4.0", "below" : "0.4.2", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2013-7035" ] , + "summary":"potential XSS vulnerability can arise when using user data as a key" + }, + "info": [ "https://facebook.github.io/react/blog/2013/12/18/react-v0.5.2-v0.4.2.html" ] + }, + { + "atOrAbove" : "0.5.0", "below" : "0.5.2", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2013-7035" ], + "summary":"potential XSS vulnerability can arise when using user data as a key" + }, + "info": [ "https://facebook.github.io/react/blog/2013/12/18/react-v0.5.2-v0.4.2.html" ] + }, + { + "below" : "0.14.0", + "severity" : "low", + "identifiers" : { "summary":" including untrusted objects as React children can result in an XSS security vulnerability" }, + "info": [ "http://danlec.com/blog/xss-via-a-spoofed-react-element", "https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html" ] + }, + { + "atOrAbove" : "16.0.0", "below" : "16.0.1", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2018-6341" ], + "summary":"potential XSS vulnerability when the attacker controls an attribute name" + }, + "info": [ "https://github.com/facebook/react/blob/master/CHANGELOG.md", "https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html" ] + }, + { + "atOrAbove" : "16.1.0", "below" : "16.1.2", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2018-6341" ], + "summary":"potential XSS vulnerability when the attacker controls an attribute name" + }, + "info": [ "https://github.com/facebook/react/blob/master/CHANGELOG.md", "https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html" ] + }, + { + "atOrAbove" : "16.2.0", "below" : "16.2.1", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2018-6341" ], + "summary":"potential XSS vulnerability when the attacker controls an attribute name" + }, + "info": [ "https://github.com/facebook/react/blob/master/CHANGELOG.md", "https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html" ] + }, + { + "atOrAbove" : "16.3.0", "below" : "16.3.3", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2018-6341" ], + "summary":"potential XSS vulnerability when the attacker controls an attribute name" + }, + "info": [ "https://github.com/facebook/react/blob/master/CHANGELOG.md", "https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html" ] + }, + { + "atOrAbove" : "16.4.0", "below" : "16.4.2", + "severity" : "low", + "identifiers" : { + "CVE": [ "CVE-2018-6341" ], + "summary":"potential XSS vulnerability when the attacker controls an attribute name" + }, + "info": [ "https://github.com/facebook/react/blob/master/CHANGELOG.md", "https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html" ] + } + ], + "extractors" : { + "func" : [ + "react.version", + "require('react').version" + ], + "filecontent" : [ + "/\\*\\*\n +\\* React \\(with addons\\) ?v([0-9][0-9.a-z_-]+)", + "/\\*\\*\n +\\* React v([0-9][0-9.a-z_-]+)", + "\"\\./ReactReconciler\":[0-9]+,\"\\./Transaction\":[0-9]+,\"fbjs/lib/invariant\":[0-9]+\\}\\],[0-9]+:\\[function\\(require,module,exports\\)\\{\"use strict\";module\\.exports=\"([0-9][0-9.a-z_-]+)\"\\}", + "ReactVersion\\.js[\\*! \\\\/\n\r]{0,100}function\\(e,t\\)\\{\"use strict\";e\\.exports=\"([0-9][0-9.a-z_-]+)\"", + "expected a ReactNode.[\\s\\S]{0,1800}?function\\(e,t\\)\\{\"use strict\";e\\.exports=\"([0-9][0-9.a-z_-]+)\"" + ] + } + }, + + "flowplayer" : { + "vulnerabilities" : [ + { + "below" : "5.4.3", + "severity": "medium", + "identifiers": { "summary" : "XSS vulnerability in Flash fallback" }, + "info" : [ "https://github.com/flowplayer/flowplayer/issues/381" ] + } + ], + "extractors" : { + "uri" : [ "flowplayer-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filename" : [ "flowplayer-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ] + } + }, + + "DWR" : { + "vulnerabilities" : [ + { + "below" : "1.1.4", + "severity": "high", + "identifiers": { "CVE" : [ "CVE-2007-01-09" ] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2014-5326/", "http://www.cvedetails.com/cve/CVE-2014-5326/" ] + }, + { + "below" : "2.0.11", + "severity": "medium", + "identifiers": { "CVE" : ["CVE-2014-5326", "CVE-2014-5325"] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2014-5326/", "http://www.cvedetails.com/cve/CVE-2014-5326/" ] + }, + { + "above" : "3", + "below" : "3.0.RC3", + "severity": "medium", + "identifiers": { "CVE" : ["CVE-2014-5326", "CVE-2014-5325"] }, + "info" : [ "http://www.cvedetails.com/cve/CVE-2014-5326/", "http://www.cvedetails.com/cve/CVE-2014-5326/" ] + } + ], + "extractors" : { + "func" : [ "dwr.version" ], + "filecontent" : [ + " dwr-([0-9][0-9.a-z_-]+).jar" + ] + } + }, + + "moment.js" : { + "bowername": [ "moment", "momentjs" ], + "vulnerabilities" : [ + { + "below" : "2.11.2", + "severity": "low", + "identifiers": { "summary":"reDOS - regular expression denial of service" }, + "info" : [ "https://github.com/moment/moment/issues/2936" ] + } + ], + "extractors" : { + "func" : [ "moment.version" ], + "filecontent" : [ "//! moment.js(?:[\n\r]+)//! version : ([0-9][0-9.a-z_-]+)" ] + } + }, + + "bootstrap": { + "vulnerabilities" : [ + { + "below" : "4.3.1", + "atOrAbove" : "4.0.0", + "identifiers": { + "issue" : "28236", + "summary": "XSS in data-template, data-content and data-title properties of tooltip/popover", + "CVE" : ["CVE-2019-8331"] + }, + "severity" : "high", + "info" : [ "https://github.com/twbs/bootstrap/issues/28236" ] + }, + { + "below" : "3.4.1", + "identifiers": { + "issue" : "28236", + "summary": "XSS in data-template, data-content and data-title properties of tooltip/popover", + "CVE" : ["CVE-2019-8331"] + }, + "severity" : "high", + "info" : [ "https://github.com/twbs/bootstrap/issues/28236" ] + }, + { + "below" : "4.1.2", + "atOrAbove" : "4.0.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in data-target property of scrollspy", + "CVE" : ["CVE-2018-14041"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "3.4.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in data-target property of scrollspy", + "CVE" : ["CVE-2018-14041"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "4.1.2", + "atOrAbove" : "4.0.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in collapse data-parent attribute", + "CVE" : ["CVE-2018-14040"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "3.4.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in collapse data-parent attribute", + "CVE" : ["CVE-2018-14040"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "4.1.2", + "atOrAbove" : "4.0.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in data-container property of tooltip", + "CVE" : ["CVE-2018-14042"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "3.4.0", + "identifiers": { + "issue" : "20184", + "summary": "XSS in data-container property of tooltip", + "CVE" : ["CVE-2018-14042"] + }, + "severity" : "medium", + "info" : [ "https://github.com/twbs/bootstrap/issues/20184" ] + }, + { + "below" : "2.1.0", + "severity": "medium", + "identifiers": { + "summary": "cross-site scripting vulnerability" + }, + "info" : [ "https://github.com/twbs/bootstrap/pull/3421" ] + } + ], + "extractors" : { + "uri" : [ "/([0-9][0-9.a-z_-]+)/bootstrap(\\.min)?\\.js" ], + "filename" : [ "bootstrap-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontent" : [ + "/\\*!? Bootstrap v([0-9][0-9.a-z_-]+)", + "\\* Bootstrap v([0-9][0-9.a-z_-]+)", + "/\\*! Bootstrap v([0-9][0-9.a-z_-]+)" + ], + "hashes" : {} + } + }, + + "ckeditor" : { + "vulnerabilities": [ + { + "below" : "4.4.3", + "identifiers" : { + "summary" : "XSS" + }, + "severity" : "medium", + "info": [ "https://github.com/ckeditor/ckeditor-dev/blob/master/CHANGES.md#ckeditor-443" ] + }, + { + "below" : "4.4.6", + "identifiers" : { + "summary" : "XSS" + }, + "severity" : "medium", + "info": [ "https://github.com/ckeditor/ckeditor-dev/blob/master/CHANGES.md#ckeditor-446" ] + }, + { + "below" : "4.4.8", + "identifiers" : { + "summary" : "XSS" + }, + "severity" : "medium", + "info": [ "https://github.com/ckeditor/ckeditor-dev/blob/master/CHANGES.md#ckeditor-448" ] + }, + { + "below" : "4.5.11", + "identifiers" : { + "summary" : "XSS" + }, + "severity" : "medium", + "info": [ "https://github.com/ckeditor/ckeditor-dev/blob/master/CHANGES.md#ckeditor-4511" ] + }, + { + "below" : "4.9.2", + "atOrAbove" : "4.5.11", + "identifiers" : { + "summary" : "XSS if the enhanced image plugin is installed" + }, + "severity" : "medium", + "info": [ "https://ckeditor.com/blog/CKEditor-4.9.2-with-a-security-patch-released/", "https://ckeditor.com/cke4/release-notes" ] + }, + { + "atOrAbove" : "4.0.0", + "below" : "4.11.0", + "identifiers" : { + "summary" : "XSS vulnerability in the HTML parser" + }, + "severity" : "medium", + "info" : [ + "https://ckeditor.com/blog/CKEditor-4.11-with-emoji-dropdown-and-auto-link-on-typing-released/", + "https://snyk.io/vuln/SNYK-JS-CKEDITOR-72618" + ] + } + ], + "extractors" : { + "uri" : [ "/([0-9][0-9.a-z_-]+)/ckeditor(\\.min)?\\.js" ], + "filename" : [ "ckeditor-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontent" : [ + "ckeditor..js.{4,20}=\\{timestamp:\"[^\"]+\",version:\"([0-9][0-9.a-z_-]+)", + "window.CKEDITOR=function\\(\\)\\{var [a-z]=\\{timestamp:\"[^\"]+\",version:\"([0-9][0-9.a-z_-]+)" + ], + "hashes" : {}, + "func" : [ "CKEDITOR.version" ] + } + }, + + + "vue" : { + "vulnerabilities" : [ + { + "below" : "2.5.17", + "severity" : "medium", + "identifiers" : { + "summary" : "potential xss in ssr when using v-bind" + }, + "info" : [ "https://github.com/vuejs/vue/releases/tag/v2.5.17" ] + }, + { + "below" : "2.4.3", + "severity" : "medium", + "identifiers" : { + "summary" : "possible xss vector " + }, + "info" : [ "https://github.com/vuejs/vue/releases/tag/v2.4.3" ] + } + ], + "extractors" : { + "uri" : [ + "/vue@([0-9][0-9.a-z_-]+)/dist/vue\\.js" + ], + "filename" : [ "vue-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" ], + "filecontent" : [ + "/\\*!\\n * Vue.js v([0-9][0-9.a-z_-]+)", + "Vue.version = '([0-9][0-9.a-z_-]+)';", + "'([0-9][0-9.a-z_-]+)'[^\\n]{0,8000}Vue compiler" + ], + "func" : [ "Vue.version" ] + } + }, + + "ExtJS" : { + "vulnerabilities" : [ + { + "below" : "6.6.0", + "atOrAbove" : "4.0.0", + "severity" : "high", + "identifiers" : { + "CVE" : [ + "CVE-2018-8046" + ], + "summary" : "XSS in Sencha Ext JS 4 to 6 via getTip() method of Action Columns" + }, + "info" : [ + "http://seclists.org/fulldisclosure/2018/Jul/8", + "https://nvd.nist.gov/vuln/detail/CVE-2018-8046" + ] + }, + { + "below" : "6.0.0", + "severity" : "high", + "identifiers" : { + "CVE" : [ + "CVE-2007-2285" + ], + "summary" : "Directory traversal and arbitrary file read" + }, + "info" : [ + "https://www.cvedetails.com/cve/CVE-2007-2285/", + "https://packetstormsecurity.com/files/132052/extjs-Arbitrary-File-Read.html", + "https://www.akawebdesign.com/2018/08/14/should-js-frameworks-prevent-xss/" + ] + }, + { + "below" : "4.0.0", + "atOrAbove" : "3.0.0", + "severity" : "high", + "identifiers" : { + "CVE" : [ + "CVE-2010-4207", + "CVE-2012-5881" + ], + "summary" : "XSS vulnerability in ExtJS charts.swf" + }, + "info" : [ + "https://www.acunetix.com/vulnerabilities/web/extjs-charts-swf-cross-site-scripting", + "https://typo3.org/security/advisory/typo3-core-sa-2014-001/", + "https://www.akawebdesign.com/2018/08/14/should-js-frameworks-prevent-xss/" + ] + } + ], + "extractors" : { + "uri" : [ + "/extjs/([0-9][0-9.a-z_-]+)/.*\\.js" + ], + "filename" : [ + "/ext-all-([0-9][0-9.a-z_-]+)(\\.min)?\\.js", + "/ext-all-debug-([0-9][0-9.a-z_-]+)(\\.min)?\\.js", + "/ext-base-([0-9][0-9.a-z_-]+)(\\.min)?\\.js" + ], + "filecontent" : [ + "/*!\n * Ext JS Library ([0-9][0-9.a-z_-]+)" + ], + "func" : [ + "Ext && Ext.versions && Ext.versions.extjs.version", + "Ext && Ext.version" + ] + } + }, + + + "dont check" : { + "extractors" : { + "uri" : [ + "^http[s]?://(ssl|www).google-analytics.com/ga.js", + "^http[s]?://apis.google.com/js/plusone.js", + "^http[s]?://cdn.cxense.com/cx.js" + ] + } + } +} diff --git a/modes/scan.py b/modes/scan.py index 15afa6a..c16aecc 100644 --- a/modes/scan.py +++ b/modes/scan.py @@ -3,7 +3,6 @@ import re from urllib.parse import urlparse, quote, unquote from core.arjun import arjun -from core.browserEngine import browserEngine from core.checker import checker from core.colors import good, bad, end, info, green, red, que import core.config @@ -13,7 +12,7 @@ from core.filterChecker import filterChecker from core.generator import generator from core.htmlParser import htmlParser from core.requester import requester -from core.utils import getUrl, getParams +from core.utils import getUrl, getParams, getVar from core.wafDetector import wafDetector from core.log import setup_logger @@ -33,7 +32,6 @@ def scan(target, paramData, encoding, headers, delay, timeout, skipDOM, find, sk logger.debug('Scan target: {}'.format(target)) response = requester(target, {}, headers, GET, delay, timeout).text - if not skipDOM: logger.run('Checking for DOM vulnerabilities') highlighted = dom(response) @@ -101,48 +99,27 @@ def scan(target, paramData, encoding, headers, delay, timeout, skipDOM, find, sk loggerVector = vect progress += 1 logger.run('Progress: %i/%i\r' % (progress, total)) - if confidence == 10: - if not GET: - vect = unquote(vect) - efficiencies = checker( - url, paramsCopy, headers, GET, delay, vect, positions, timeout, encoding) - if not efficiencies: - for i in range(len(occurences)): - efficiencies.append(0) - bestEfficiency = max(efficiencies) - if bestEfficiency == 100 or (vect[0] == '\\' and bestEfficiency >= 95): - logger.red_line() - logger.good('Payload: %s' % loggerVector) - logger.info('Efficiency: %i' % bestEfficiency) - logger.info('Confidence: %i' % confidence) - if not skip: - choice = input( - '%s Would you like to continue scanning? [y/N] ' % que).lower() - if choice != 'y': - quit() - elif bestEfficiency > minEfficiency: - logger.red_line() - logger.good('Payload: %s' % loggerVector) - logger.info('Efficiency: %i' % bestEfficiency) - logger.info('Confidence: %i' % confidence) - else: - if re.search(r'<(a|d3|details)|lt;(a|d3|details)', vect.lower()): - continue + if not GET: vect = unquote(vect) - if encoding: - paramsCopy[paramName] = encoding(vect) - else: - paramsCopy[paramName] = vect - response = requester(url, paramsCopy, headers, GET, delay, timeout).text - success = browserEngine(response) - if success: - logger.red_line() - logger.good('Payload: %s' % loggerVector) - logger.info('Efficiency: %i' % 100) - logger.info('Confidence: %i' % 10) - if not skip: - choice = input( - '%s Would you like to continue scanning? [y/N] ' % que).lower() - if choice != 'y': - quit() + efficiencies = checker( + url, paramsCopy, headers, GET, delay, vect, positions, timeout, encoding) + if not efficiencies: + for i in range(len(occurences)): + efficiencies.append(0) + bestEfficiency = max(efficiencies) + if bestEfficiency == 100 or (vect[0] == '\\' and bestEfficiency >= 95): + logger.red_line() + logger.good('Payload: %s' % loggerVector) + logger.info('Efficiency: %i' % bestEfficiency) + logger.info('Confidence: %i' % confidence) + if not skip: + choice = input( + '%s Would you like to continue scanning? [y/N] ' % que).lower() + if choice != 'y': + quit() + elif bestEfficiency > minEfficiency: + logger.red_line() + logger.good('Payload: %s' % loggerVector) + logger.info('Efficiency: %i' % bestEfficiency) + logger.info('Confidence: %i' % confidence) logger.no_format('') diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/plugins/__init__.py @@ -0,0 +1 @@ + diff --git a/plugins/retireJs.py b/plugins/retireJs.py new file mode 100644 index 0000000..c45dfb7 --- /dev/null +++ b/plugins/retireJs.py @@ -0,0 +1,218 @@ +import re +import json +import hashlib +from urllib.parse import urlparse + +from core.colors import green, end +from core.requester import requester +from core.utils import deJSON, js_extractor, handle_anchor, getVar, updateVar +from core.log import setup_logger + +logger = setup_logger(__name__) + + +def is_defined(o): + return o is not None + + +def scan(data, extractor, definitions, matcher=None): + matcher = matcher or _simple_match + detected = [] + for component in definitions: + extractors = definitions[component].get( + "extractors", None).get( + extractor, None) + if (not is_defined(extractors)): + continue + for i in extractors: + match = matcher(i, data) + if (match): + detected.append({"version": match, + "component": component, + "detection": extractor}) + return detected + + +def _simple_match(regex, data): + regex = deJSON(regex) + match = re.search(regex, data) + return match.group(1) if match else None + + +def _replacement_match(regex, data): + try: + regex = deJSON(regex) + group_parts_of_regex = r'^\/(.*[^\\])\/([^\/]+)\/$' + ar = re.search(group_parts_of_regex, regex) + search_for_regex = "(" + ar.group(1) + ")" + match = re.search(search_for_regex, data) + ver = None + if (match): + ver = re.sub(ar.group(1), ar.group(2), match.group(0)) + return ver + + return None + except: + return None + + +def _scanhash(hash, definitions): + for component in definitions: + hashes = definitions[component].get("extractors", None).get("hashes", None) + if (not is_defined(hashes)): + continue + for i in hashes: + if (i == hash): + return [{"version": hashes[i], + "component": component, + "detection": 'hash'}] + + return [] + + +def check(results, definitions): + for r in results: + result = r + + if (not is_defined(definitions[result.get("component", None)])): + continue + vulns = definitions[ + result.get( + "component", + None)].get( + "vulnerabilities", + None) + for i in range(len(vulns)): + if (not _is_at_or_above(result.get("version", None), + vulns[i].get("below", None))): + if (is_defined(vulns[i].get("atOrAbove", None)) and not _is_at_or_above( + result.get("version", None), vulns[i].get("atOrAbove", None))): + continue + + vulnerability = {"info": vulns[i].get("info", None)} + if (vulns[i].get("severity", None)): + vulnerability["severity"] = vulns[i].get("severity", None) + + if (vulns[i].get("identifiers", None)): + vulnerability["identifiers"] = vulns[ + i].get("identifiers", None) + + result["vulnerabilities"] = result.get( + "vulnerabilities", None) or [] + result["vulnerabilities"].append(vulnerability) + + return results + + +def unique(ar): + return list(set(ar)) + + +def _is_at_or_above(version1, version2): + # print "[",version1,",", version2,"]" + v1 = re.split(r'[.-]', version1) + v2 = re.split(r'[.-]', version2) + + l = len(v1) if len(v1) > len(v2) else len(v2) + for i in range(l): + v1_c = _to_comparable(v1[i] if len(v1) > i else None) + v2_c = _to_comparable(v2[i] if len(v2) > i else None) + # print v1_c, "vs", v2_c + if (not isinstance(v1_c, type(v2_c))): + return isinstance(v1_c, int) + if (v1_c > v2_c): + return True + if (v1_c < v2_c): + return False + + return True + + +def _to_comparable(n): + if (not is_defined(n)): + return 0 + if (re.search(r'^[0-9]+$', n)): + return int(str(n), 10) + + return n + + +def _replace_version(jsRepoJsonAsText): + return re.sub(r'[.0-9]*', '[0-9][0-9.a-z_\-]+', jsRepoJsonAsText) + + +def is_vulnerable(results): + for r in results: + if ('vulnerabilities' in r): + # print r + return True + + return False + + +def scan_uri(uri, definitions): + result = scan(uri, 'uri', definitions) + return check(result, definitions) + + +def scan_filename(fileName, definitions): + result = scan(fileName, 'filename', definitions) + return check(result, definitions) + + +def scan_file_content(content, definitions): + result = scan(content, 'filecontent', definitions) + if (len(result) == 0): + result = scan(content, 'filecontentreplace', definitions, _replacement_match) + + if (len(result) == 0): + result = _scanhash( + hashlib.sha1( + content.encode('utf8')).hexdigest(), + definitions) + + return check(result, definitions) + + +def main_scanner(uri, response): + definitions = getVar('definitions') + uri_scan_result = scan_uri(uri, definitions) + filecontent = response + filecontent_scan_result = scan_file_content(filecontent, definitions) + uri_scan_result.extend(filecontent_scan_result) + result = {} + if uri_scan_result: + result['component'] = uri_scan_result[0]['component'] + result['version'] = uri_scan_result[0]['version'] + result['vulnerabilities'] = [] + vulnerabilities = set() + for i in uri_scan_result: + k = set() + try: + for j in i['vulnerabilities']: + vulnerabilities.add(str(j)) + except KeyError: + pass + for vulnerability in vulnerabilities: + result['vulnerabilities'].append(json.loads(vulnerability.replace('\'', '"'))) + return result + +def retireJs(url, response): + scripts = js_extractor(response) + for script in scripts: + if script not in getVar('checkedScripts'): + updateVar('checkedScripts', script, 'add') + uri = handle_anchor(url, script) + response = requester(uri, '', getVar('headers'), True, getVar('delay'), getVar('timeout')).text + result = main_scanner(uri, response) + if result: + logger.red_line() + logger.good('Vulnerable component: ' + result['component'] + ' v' + result['version']) + logger.info('Component location: %s' % uri) + details = result['vulnerabilities'] + logger.info('Total vulnerabilities: %i' % len(details)) + for detail in details: + logger.info('%sSummary:%s %s' % (green, end, detail['identifiers']['summary'])) + logger.info('Severity: %s' % detail['severity']) + logger.info('CVE: %s' % detail['identifiers']['CVE'][0]) + logger.red_line() diff --git a/requirements.txt b/requirements.txt index 0dc1c04..3c25fb9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ tld fuzzywuzzy requests -selenium diff --git a/xsstrike.py b/xsstrike.py index 2da7f82..3ad07d3 100644 --- a/xsstrike.py +++ b/xsstrike.py @@ -6,7 +6,7 @@ from core.colors import end, red, white, bad, info # Just a fancy ass banner print('''%s -\tXSStrike %sv3.1.2 +\tXSStrike %sv3.1.3 %s''' % (red, white, end)) try: @@ -25,6 +25,8 @@ except ImportError: # throws error in python2 quit() # Let's import whatever we need from standard lib +import sys +import json import argparse # ... and configurations core lib @@ -129,6 +131,10 @@ elif type(args.add_headers) == str: else: from core.config import headers +core.config.globalVariables['headers'] = headers +core.config.globalVariables['checkedScripts'] = set() +core.config.globalVariables['definitions'] = json.loads('\n'.join(reader(sys.path[0] + '/db/definitions.json'))) + if path: paramData = converter(target, target) elif jsonData: