-
Notifications
You must be signed in to change notification settings - Fork 35
BUG: Empty OAuth endpoint paths concatenate as "null" string #1970
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't workingtriagePending triage from maintainersPending triage from maintainers
Description
Description
Current Behavior:
When auth_code_endpoint or access_token_endpoint are empty strings in globalConfig.json,
UCC generates code that stringifies them as "null" in OAuth URLs.
Example:
- Config:
"auth_code_endpoint": "" - Generated URL:
https://oauth.provider.com/oauth/authorizenull?... - Expected URL:
https://oauth.provider.com/oauth/authorize?...
Root Causes:
Python:
Line 128 in 1b02b4f
| return f"https://{host}/{TOKEN_ENDPOINT.lstrip('/')}" |
- Using
||instead of??causes empty string coercion - No validation that paths are paths (not full URLs)
- String concatenation instead of URL construction APIs
Proposed Fixes:
- Use nullish coalescing (
??) to preserve null semantics - Add validation: paths must start with
/, cannot contain:// - Use
URLconstructor (JS) andurlunsplit(Python) for safe URL building - Throw explicit errors on invalid configuration
Python example
def normalize_oauth_endpoint_path(maybe_path: Optional[str]) -> str:
"""
Normalizes OAuth endpoint path with validation.
Args:
maybe_path: The endpoint path (can be None or string)
Returns:
Normalized path string (empty if None)
Raises:
ValueError: If path is invalid
TypeError: If path is not a string
"""
# None or empty → no path
if not maybe_path:
return ""
if not isinstance(maybe_path, str):
raise TypeError("OAuth endpoint must be a string")
# Validate: must be a path, not a full URL
if "://" in maybe_path:
raise ValueError(
"OAuth endpoint must be a path (e.g., '/oauth/token'), not a full URL"
)
# Validate: prevent protocol-relative URLs
if maybe_path.startswith("//"):
raise ValueError("Protocol-relative URLs not allowed in OAuth endpoint")
# Ensure leading slash for proper URL construction
return maybe_path if maybe_path.startswith("/") else f"/{maybe_path}"
def build_oauth_url(host: str, endpoint_path: Optional[str]) -> str:
"""
Build OAuth URL from host and optional path.
Args:
host: The host (e.g., 'accounts.google.com' or '127.0.0.1:5001')
endpoint_path: Optional path component
Returns:
Complete HTTPS URL
"""
path = normalize_oauth_endpoint_path(endpoint_path)
return urlunsplit(("https", host, path, "", ""))
In the oauth helper:
TOKEN_ENDPOINT = self.oauth_conf_mgr.get_oauth_spec(conf_type).get(
"access_token_endpoint"
)
# TOKEN_ENDPOINT is None if absent, string if present
return build_oauth_url(host, TOKEN_ENDPOINT)
except (ValueError, TypeError) as e:
raise ValueError(f"Invalid OAuth token endpoint configuration: {e}")
For javascript you could make two functions one to normalize to null and one specifically to interpret any absence or empty string to "" for the url concatenation.
Benefits:
- Prevents "null" stringification
- Prevents absolute URL injection in path fields
- Clear error messages for misconfiguration
- Maintains semantic distinction: null = absent, "" = empty path
Use Case:
Allows users to specify full OAuth endpoint URLs in the endpoint field when
paths are non-standard or when endpoint differs between authorization/token #
What UCC version are you using?
splunk-add-on-ucc-framework==6.1.0
Additional System Info
Python 3.13.1, MacOS 26.2, Splunk 9.4
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingtriagePending triage from maintainersPending triage from maintainers