This commit is contained in:
donnd-t 2021-09-17 15:49:06 +10:00
parent 8f13e35f3f
commit 59e8bb94f2

View File

@ -10,27 +10,47 @@ import json
from lib.core.data import logger from lib.core.data import logger
from lib.core.exception import SqlmapSyntaxException from lib.core.exception import SqlmapSyntaxException
def _operationParameters(parameters, types): class Operation:
return list(filter(lambda p: (p["in"] in types), parameters))
def _operationQueryString(parameters): def __init__(self, op):
queryParameters = _operationParameters(parameters, ["query"]) self.op = op
if len(queryParameters) < 1:
def tags(self):
return self.op["tags"]
def parameters(self):
return self.op["parameters"]
def parametersForTypes(self, types):
return list(filter(lambda p: (p["in"] in types), self.parameters()))
def bodyRef(self):
if "requestBody" in self.op:
return self.op["requestBody"]["content"]["application/json"]["schema"]["$ref"]
return None return None
queryString = ""
for qp in queryParameters:
queryString += "&%s=%s" %(qp["name"], qp["example"])
return queryString.replace('&', '', 1) # header injection is not currently supported
def injectable(self, body):
return len(self.parametersForTypes(["query", "path"])) > 0 or body
def _operationPath(path, parameters): def queryString(self):
pathParameters = _operationParameters(parameters, ["path"]) queryParameters = self.parametersForTypes(["query"])
if len(pathParameters) < 1: if len(queryParameters) < 1:
return path return None
parameterPath = path queryString = ""
for p in pathParameters: for qp in queryParameters:
parameterPath = parameterPath.replace("{%s}" %p["name"], "%s*" %p["example"]) queryString += "&%s=%s" %(qp["name"], qp["example"])
return parameterPath
return queryString.replace('&', '', 1)
def path(self, path):
pathParameters = self.parametersForTypes(["path"])
if len(pathParameters) < 1:
return path
parameterPath = path
for p in pathParameters:
parameterPath = parameterPath.replace("{%s}" %p["name"], "%s*" %p["example"])
return parameterPath
def _ref(swagger, refPath): def _ref(swagger, refPath):
paths = refPath.replace("#/", "", 1).split('/') paths = refPath.replace("#/", "", 1).split('/')
@ -39,21 +59,21 @@ def _ref(swagger, refPath):
r = r[p] r = r[p]
return r return r
def _body(swagger, refPath): def _example(swagger, refPath):
body = {} example = {}
ref = _ref(swagger, refPath) ref = _ref(swagger, refPath)
if "type" in ref and ref["type"] == "object" and "properties" in ref: if "type" in ref and ref["type"] == "object" and "properties" in ref:
properties = ref["properties"] properties = ref["properties"]
for prop in properties: for prop in properties:
if "example" in properties[prop]: if "example" in properties[prop]:
value = properties[prop]["example"] value = properties[prop]["example"]
body[prop] = value example[prop] = value
elif "$ref" in properties[prop]: elif "$ref" in properties[prop]:
body[prop] = _body(swagger, properties[prop]["$ref"]) example[prop] = _example(swagger, properties[prop]["$ref"])
elif properties[prop]["type"] == "array" and "$ref" in properties[prop]["items"]: elif properties[prop]["type"] == "array" and "$ref" in properties[prop]["items"]:
body[prop] = [ _body(swagger, properties[prop]["items"]["$ref"]) ] example[prop] = [ _example(swagger, properties[prop]["items"]["$ref"]) ]
return body return example
def parse(content, tags): def parse(content, tags):
""" """
@ -81,19 +101,18 @@ def parse(content, tags):
for path in swagger["paths"]: for path in swagger["paths"]:
for operation in swagger["paths"][path]: for operation in swagger["paths"][path]:
op = swagger["paths"][path][operation] op = Operation(swagger["paths"][path][operation])
# skip any operations without one of our tags # skip any operations without one of our tags
if tags is not None and not any(tag in op["tags"] for tag in tags): if tags is not None and not any(tag in op.tags() for tag in tags):
continue continue
body = {} body = {}
if "requestBody" in op: bodyRef = op.bodyRef()
ref = op["requestBody"]["content"]["application/json"]["schema"]["$ref"] if bodyRef:
body = _body(swagger, ref) body = _example(swagger, bodyRef)
# header injection is not currently supported if not op.injectable(body):
if (len(_operationParameters(op["parameters"], ["query", "path"]))) < 1 and not body:
logger.info("excluding path '%s', operation '%s' as there are no parameters to inject" %(path, operation)) logger.info("excluding path '%s', operation '%s' as there are no parameters to inject" %(path, operation))
continue continue
@ -102,8 +121,8 @@ def parse(content, tags):
data = None data = None
cookie = None cookie = None
parameterPath = _operationPath(path, op["parameters"]) parameterPath = op.path(path)
qs = _operationQueryString(op["parameters"]) qs = op.queryString()
url = "%s%s" % (server, parameterPath) url = "%s%s" % (server, parameterPath)
method = operation.upper() method = operation.upper()
if body: if body:
@ -112,7 +131,7 @@ def parse(content, tags):
if qs is not None: if qs is not None:
url += "?" + qs url += "?" + qs
logger.debug("swagger url '%s', method '%s', data '%s', cookie '%s'" %(url, method, data, cookie)) logger.debug("including url '%s', method '%s', data '%s', cookie '%s'" %(url, method, data, cookie))
yield (url, method, data, cookie, None) yield (url, method, data, cookie, None)
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError: