Adding --openapi-tags

This commit is contained in:
Miroslav Štampar 2026-07-09 14:13:21 +02:00
parent fc1ae6950e
commit 622cfa76c6
6 changed files with 37 additions and 4 deletions

View file

@ -150,6 +150,9 @@ def cmdLineParser(argv=None):
target.add_argument("--openapi-base", dest="openApiBase",
help="Base URL for a host-less OpenAPI/Swagger spec")
target.add_argument("--openapi-tags", dest="openApiTags",
help="Only derive targets from operations with these tag(s)")
# Request options
request = parser.add_argument_group("Request", "These options can be used to specify how to connect to the target URL")

View file

@ -206,15 +206,18 @@ def _baseUrl(spec, origin=None, servers=None):
_METHODS = ("get", "post", "put", "delete", "patch", "options", "head")
def openApiTargets(content, origin=None):
def openApiTargets(content, origin=None, tags=None):
"""
Returns a list of (url, method, data, headers) request tuples derived from an OpenAPI/Swagger
specification. 'headers' is a list of (name, value) tuples (matching conf.httpHeaders). 'origin'
(scheme://host[:port] of the specification's own location) is used only to resolve RELATIVE 'servers'
entries - absolute server URLs are used as declared. Path parameters and header/cookie values carry
the custom injection mark so they become testable injection points.
the custom injection mark so they become testable injection points. 'tags' (list) restricts extraction
to operations declaring at least one of those OpenAPI tags (to scope a scan of a large API).
"""
tagSet = set(tags) if tags else None
spec = _loadSpec(content)
if not isinstance(spec, dict) or not isinstance(spec.get("paths"), dict) or not spec.get("paths"):
errMsg = "no valid 'paths' object found in the provided OpenAPI/Swagger specification"
@ -236,6 +239,8 @@ def openApiTargets(content, origin=None):
for method, operation in item.items():
if str(method).lower() not in _METHODS or not isinstance(operation, dict): # str(): YAML keys can be non-string (e.g. 404, 'on'->bool)
continue
if tagSet is not None and not (tagSet & set(_ for _ in (operation.get("tags") or []) if isinstance(_, six.string_types))):
continue # '--openapi-tags' filter: operation carries none of the requested tags
try:
# effective base URL with OpenAPI precedence: operation 'servers' > path-item 'servers' > root
opServers = operation.get("servers") or item.get("servers")