Skip to content

Instantly share code, notes, and snippets.

@williamzujkowski
Created November 17, 2025 05:07
Show Gist options
  • Select an option

  • Save williamzujkowski/f48eec461aba54cdd3f4a74b29fe84e7 to your computer and use it in GitHub Desktop.

Select an option

Save williamzujkowski/f48eec461aba54cdd3f4a74b29fe84e7 to your computer and use it in GitHub Desktop.
AuthREST-style API authentication security scanner in Python
#!/usr/bin/env python3
"""
AuthREST-style API Authentication Scanner
Parses OpenAPI specs and tests authentication patterns
"""
import json
import requests
from typing import Dict, List, Optional
from dataclasses import dataclass
@dataclass
class AuthTest:
endpoint: str
method: str
auth_required: bool
test_type: str
class AuthRestScanner:
def __init__(self, openapi_spec: Dict, base_url: str):
self.spec = openapi_spec
self.base_url = base_url
self.results = []
def parse_auth_requirements(self) -> List[AuthTest]:
"""Extract auth requirements from OpenAPI spec"""
tests = []
for path, methods in self.spec.get('paths', {}).items():
for method, config in methods.items():
if method == 'parameters':
continue
security = config.get('security', [])
auth_required = len(security) > 0
tests.append(AuthTest(
endpoint=path,
method=method.upper(),
auth_required=auth_required,
test_type='auth_bypass'
))
return tests
def test_auth_bypass(self, test: AuthTest) -> Dict:
"""Test if endpoint enforces authentication"""
url = f"{self.base_url}{test.endpoint}"
try:
# Test without auth token
resp_no_auth = requests.request(test.method, url, timeout=5)
# Test with invalid token
headers = {'Authorization': 'Bearer invalid_token'}
resp_bad_auth = requests.request(
test.method, url, headers=headers, timeout=5
)
# Auth should be enforced
vulnerable = (
test.auth_required and
resp_no_auth.status_code == 200
)
return {
'endpoint': test.endpoint,
'method': test.method,
'vulnerable': vulnerable,
'status_no_auth': resp_no_auth.status_code,
'status_bad_auth': resp_bad_auth.status_code
}
except Exception as e:
return {'error': str(e)}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment