This commit is contained in:
jorgectf
2022-02-08 17:23:18 +01:00
parent d2f07e4df2
commit 8f9cd16806
23 changed files with 784 additions and 421 deletions

View File

@@ -1 +0,0 @@
experimental/Security/CWE-611/XXE.ql

View File

@@ -0,0 +1 @@
experimental/Security/CWE-611/XmlInjection.ql

View File

@@ -1,73 +0,0 @@
from flask import request, Flask
from io import StringIO, BytesIO
import xml.etree
import xml.etree.ElementTree
import lxml.etree
import xml.dom.minidom
import xml.dom.pulldom
import xmltodict
app = Flask(__name__)
# xml_content = '<?xml version="1.0"?><!DOCTYPE dt [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>'
@app.route("/lxml.etree.fromstring")
def lxml_fromstring():
xml_content = request.args['xml_content']
return lxml.etree.fromstring(xml_content).text
@app.route("/lxml.etree.XML")
def lxml_XML():
xml_content = request.args['xml_content']
return lxml.etree.XML(xml_content).text
@app.route("/lxml.etree.parse")
def lxml_parse():
xml_content = request.args['xml_content']
return lxml.etree.parse(StringIO(xml_content)).text
@app.route("/xmltodict.parse")
def xmltodict_parse():
xml_content = request.args['xml_content']
return xmltodict.parse(xml_content, disable_entities=False)
@app.route("/lxml.etree.XMLParser+lxml.etree.fromstring")
def lxml_XMLParser_fromstring():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser()
return lxml.etree.fromstring(xml_content, parser=parser).text
@app.route("/lxml.etree.get_default_parser+lxml.etree.fromstring")
def lxml_defaultParser_fromstring():
xml_content = request.args['xml_content']
parser = lxml.etree.get_default_parser()
return lxml.etree.fromstring(xml_content, parser=parser).text
@app.route("/lxml.etree.XMLParser+xml.etree.ElementTree.fromstring")
def lxml_XMLParser_xml_fromstring():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser()
return xml.etree.ElementTree.fromstring(xml_content, parser=parser).text
@app.route("/lxml.etree.XMLParser+xml.etree.ElementTree.parse")
def lxml_XMLParser_xml_parse():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser()
return xml.etree.ElementTree.parse(StringIO(xml_content), parser=parser).getroot().text

View File

@@ -0,0 +1,76 @@
from flask import request, Flask
from io import StringIO, BytesIO
import lxml.etree
app = Flask(__name__)
# Parsing
@app.route("/lxml_etree_fromstring")
def lxml_etree_fromstring():
xml_content = request.args['xml_content']
return lxml.etree.fromstring(xml_content).text
@app.route("/lxml_etree_fromstringlist")
def lxml_etree_fromstringlist():
xml_content = request.args['xml_content']
return lxml.etree.fromstringlist([xml_content]).text
@app.route("/lxml_etree_XML")
def lxml_etree_XML():
xml_content = request.args['xml_content']
return lxml.etree.XML(xml_content).text
@app.route("/lxml_etree_parse")
def lxml_etree_parse():
xml_content = request.args['xml_content']
return lxml.etree.parse(StringIO(xml_content)).getroot().text
# With parsers - Default
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser")
def lxml_parser():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser()
return lxml.etree.fromstring(xml_content, parser=parser).text
@app.route("/lxml_etree_fromstring-lxml.etree.get_default_parser")
def lxml_parser():
xml_content = request.args['xml_content']
parser = lxml.etree.get_default_parser()
return lxml.etree.fromstring(xml_content, parser=parser).text
# With parsers - With options
# XXE-safe
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
def lxml_parser():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser(resolve_entities=False)
return lxml.etree.fromstring(xml_content, parser=parser).text
# Billion laughs and quadratic blowup (huge_tree)
## Good (huge_tree=True but resolve_entities=False)
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
def lxml_parser():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser(resolve_entities=False, huge_tree=True)
return lxml.etree.fromstring(xml_content, parser=parser).text
## Bad
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
def lxml_parser():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser(huge_tree=True)
return lxml.etree.fromstring(xml_content, parser=parser).text

View File

@@ -0,0 +1,44 @@
from flask import request, Flask
from io import StringIO, BytesIO
import xml.dom.minidom
import xml.dom.pulldom
import xml.sax
app = Flask(__name__)
# Parsing
@app.route("/xml_minidom_parse")
def xml_minidom_parse():
xml_content = request.args['xml_content']
return xml.dom.minidom.parse(StringIO(xml_content)).documentElement.childNodes
@app.route("/xml_minidom_parseString")
def xml_minidom_parseString():
xml_content = request.args['xml_content']
return xml.dom.minidom.parseString(xml_content).documentElement.childNodes
@app.route("/xml_pulldom_parse")
def xml_pulldom_parse():
xml_content = request.args['xml_content']
return xml.dom.pulldom.parse(StringIO(xml_content))['START_DOCUMENT'][1].documentElement.childNodes
@app.route("/xml_pulldom_parseString")
def xml_pulldom_parseString():
xml_content = request.args['xml_content']
return xml.dom.pulldom.parseString(xml_content)['START_DOCUMENT'][1].documentElement.childNodes
# With parsers
@app.route("/xml_minidom_parse_xml_sax_make_parser")
def xml_minidom_parse_xml_sax_make_parser():
xml_content = request.args['xml_content']
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_external_ges, True)
return xml.dom.minidom.parse(StringIO(xml_content), parser=parser).documentElement.childNodes

View File

@@ -0,0 +1,66 @@
from flask import request, Flask
from io import StringIO, BytesIO
import xml.etree
import xml.etree.ElementTree
import lxml.etree
app = Flask(__name__)
# xxe = '<?xml version="1.0"?><!DOCTYPE dt [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>'
# Parsing
@app.route("/xml_etree_fromstring")
def xml_etree_fromstring():
xml_content = request.args['xml_content']
return xml.etree.ElementTree.fromstring(xml_content).text
@app.route("/xml_etree_fromstringlist")
def xml_etree_fromstringlist():
xml_content = request.args['xml_content']
return xml.etree.ElementTree.fromstringlist(xml_content).text
@app.route("/xml_etree_XML")
def xml_etree_XML():
xml_content = request.args['xml_content']
return xml.etree.ElementTree.XML(xml_content).text
@app.route("/xml_etree_parse")
def xml_etree_parse():
xml_content = request.args['xml_content']
return xml.etree.ElementTree.parse(StringIO(xml_content)).getroot().text
# With parsers
@app.route("/xml_etree_fromstring-xml_etree_XMLParser")
def xml_parser_1():
xml_content = request.args['xml_content']
parser = xml.etree.ElementTree.XMLParser()
return xml.etree.ElementTree.fromstring(xml_content, parser=parser).text
@app.route("/xml_etree_fromstring-lxml_etree_XMLParser")
def xml_parser_2():
xml_content = request.args['xml_content']
parser = lxml.etree.XMLParser()
return xml.etree.ElementTree.fromstring(xml_content, parser=parser).text
@app.route("/xml_etree_fromstring-lxml_get_default_parser")
def xml_parser_3():
xml_content = request.args['xml_content']
parser = lxml.etree.get_default_parser()
return xml.etree.ElementTree.fromstring(xml_content, parser=parser).text
@app.route("/xml_etree_fromstring-lxml_get_default_parser")
def xml_parser_4():
xml_content = request.args['xml_content']
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_external_ges, True)
return xml.etree.ElementTree.fromstring(xml_content, parser=parser).text

View File

@@ -2,7 +2,7 @@ from flask import request, Flask
from io import StringIO
import xml.sax
# xml_content = '<?xml version="1.0"?><!DOCTYPE dt [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>'
# xxe = '<?xml version="1.0"?><!DOCTYPE dt [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>'
app = Flask(__name__)
@@ -74,12 +74,28 @@ def xml_makeparser_minidom_entitiesTrue():
parser.setFeature(xml.sax.handler.feature_external_ges, True)
return xml.dom.minidom.parse(StringIO(xml_content), parser=parser).documentElement.childNodes
# Forward Type Tracker test
# Forward Type Tracking test
@app.route("forward_tracking1")
def forward_tracking1(action):
xml_content = request.args['xml_content']
def contrived_example(user_input, action):
parser = xml.sax.make_parser()
if action == 'load-config':
parser.setFeature(xml.sax.handler.feature_external_ges, False)
parser.parse("/not-user-controlled/default_config.xml")
else:
parser.parse(StringIO(user_input))
parser.parse(StringIO(xml_content))
return
@app.route("forward_tracking2")
def forward_tracking2(action):
xml_content = request.args['xml_content']
parser = xml.sax.make_parser()
if action == 'load-config':
parser.setFeature(xml.sax.handler.feature_external_ges, True)
parser.parse("/not-user-controlled/default_config.xml")
else:
parser.parse(StringIO(xml_content))
return

View File

@@ -0,0 +1,17 @@
from flask import request, Flask
from io import StringIO, BytesIO
import xmltodict
app = Flask(__name__)
@app.route("/xmltodict.parse")
def xmltodict_parse():
xml_content = request.args['xml_content']
return xmltodict.parse(xml_content)
@app.route("/xmltodict.parse2")
def xmltodict_parse2():
xml_content = request.args['xml_content']
return xmltodict.parse(xml_content, disable_entities=False)

View File

@@ -0,0 +1,10 @@
from xmlrpc.server import SimpleXMLRPCServer
def foo(n):
return n
server = SimpleXMLRPCServer(("127.0.0.1", 8000))
server.register_function(foo, "foo")
server.serve_forever()
# billion_laughs -> curl 127.0.0.1:8000 --data-raw '<?xml version="1.0"?><!DOCTYPE lolz [<!ENTITY lol "lol"><!ELEMENT lolz (#PCDATA)><!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"><!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"><!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"><!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"><!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"><!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"><!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"><!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><methodCall><methodName>foo</methodName><params><param><value>&lol9;</value></param></params></methodCall>'