Created
November 17, 2025 05:07
-
-
Save williamzujkowski/f48eec461aba54cdd3f4a74b29fe84e7 to your computer and use it in GitHub Desktop.
AuthREST-style API authentication security scanner in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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