mirror of
https://github.com/apidoorman/doorman.git
synced 2026-04-24 09:38:14 -05:00
fix tests
This commit is contained in:
@@ -200,6 +200,13 @@ def archive_existing_proto(proto_path: Path, api_name: str, api_version: str):
|
||||
# Re-sanitize inputs to be paranoid
|
||||
safe_name = sanitize_filename(api_name)
|
||||
safe_ver = sanitize_filename(api_version)
|
||||
# Ensure the source path matches the exact expected sanitized filename under proto/
|
||||
expected_src = (PROJECT_ROOT / 'proto' / f"{safe_name}_{safe_ver}.proto").resolve()
|
||||
if expected_src != proto_path:
|
||||
logger.warning(
|
||||
f"Archive source path mismatch: expected {expected_src}, got {proto_path}; skipping archive"
|
||||
)
|
||||
return
|
||||
filename = f"{safe_name}_{safe_ver}_{timestamp}.proto"
|
||||
|
||||
dest = (archive_dir / filename).resolve() # codeql[py/uncontrolled-data-in-path-expression]: Destination path built from sanitized components and constrained to archive_dir via validate_path
|
||||
@@ -312,9 +319,35 @@ async def upload_proto_file(
|
||||
if not validate_path(PROJECT_ROOT, proto_path):
|
||||
raise ValueError('Invalid proto path detected')
|
||||
|
||||
# Archive existing before overwrite
|
||||
# Archive existing before overwrite (with strict filename equality guard)
|
||||
archive_existing_proto(proto_path, api_name, api_version)
|
||||
|
||||
# Write only if the computed path matches the sanitized expectation
|
||||
try:
|
||||
expected_src = (
|
||||
PROJECT_ROOT / 'proto' / f"{sanitize_filename(api_name)}_{sanitize_filename(api_version)}.proto"
|
||||
).resolve()
|
||||
except Exception:
|
||||
return process_response(
|
||||
ResponseModel(
|
||||
status_code=400,
|
||||
response_headers={Headers.REQUEST_ID: request_id},
|
||||
error_code=ErrorCodes.PATH_VALIDATION,
|
||||
error_message='Failed to compute expected proto path',
|
||||
).dict(),
|
||||
'rest',
|
||||
)
|
||||
if expected_src != proto_path:
|
||||
return process_response(
|
||||
ResponseModel(
|
||||
status_code=400,
|
||||
response_headers={Headers.REQUEST_ID: request_id},
|
||||
error_code=ErrorCodes.PATH_VALIDATION,
|
||||
error_message='Computed proto path mismatch after sanitization',
|
||||
).dict(),
|
||||
'rest',
|
||||
)
|
||||
|
||||
proto_path.write_text(proto_content)
|
||||
try:
|
||||
# Ensure grpc_tools is available before attempting compilation
|
||||
|
||||
@@ -21,6 +21,7 @@ from xml.etree import ElementTree as ET
|
||||
import defusedxml.ElementTree as SafeET
|
||||
|
||||
import httpx
|
||||
import os
|
||||
|
||||
logger = logging.getLogger('doorman.gateway')
|
||||
|
||||
@@ -278,10 +279,21 @@ def create_ws_security_header(
|
||||
nonce_value = secrets.token_bytes(16)
|
||||
nonce_b64 = __import__('base64').b64encode(nonce_value).decode('ascii')
|
||||
|
||||
if password and password_type in ('PasswordDigest', 'PasswordDigestSHA256'):
|
||||
# Gate legacy SHA-1 UsernameToken digests behind an env flag for security hardening.
|
||||
# Default behavior prefers SHA-256 unless explicitly allowed to use SHA-1.
|
||||
allow_sha1 = os.getenv('DOORMAN_ALLOW_WSSE_SHA1', '').lower() in ('1', 'true', 'yes', 'on')
|
||||
effective_type = password_type
|
||||
if password_type == 'PasswordDigest' and not allow_sha1:
|
||||
try:
|
||||
logger.warning('WS-Security PasswordDigest (SHA-1) disabled by default; using SHA-256. Set DOORMAN_ALLOW_WSSE_SHA1=true to enable SHA-1 for interop.')
|
||||
except Exception:
|
||||
pass
|
||||
effective_type = 'PasswordDigestSHA256'
|
||||
|
||||
if password and effective_type in ('PasswordDigest', 'PasswordDigestSHA256'):
|
||||
# Digest = Base64(HASH(Nonce + Created + Password))
|
||||
digest_input = nonce_value + created.encode('utf-8') + password.encode('utf-8')
|
||||
if password_type == 'PasswordDigestSHA256':
|
||||
if effective_type == 'PasswordDigestSHA256':
|
||||
# WS-Security 1.1 requires SHA-256 for PasswordDigestSHA256.
|
||||
# This is a network digest, NOT used for local password storage.
|
||||
digest_bytes = hashlib.sha256(digest_input).digest() # codeql[py/weak-cryptographic-algorithm]: WS-Security UsernameToken digest (transport-level), not password storage
|
||||
|
||||
Reference in New Issue
Block a user