apache / apache/infrastructure-asfquart
Dynamic OAuth Callback URL Constructed from Host Header
- Dominant language
- Python
- Stars
- 7
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
## Issue: FINDING-164 - Dynamic OAuth Callback URL Constructed from Host Header
**Labels:** bug, security, priority:medium, asvs-level:L1
**ASVS Level(s):** L1
**Description:**
### Summary
The OAuth `redirect_uri` parameter is dynamically derived from the HTTP Host header (`callback_host = quart.request.host_url.replace('http://', 'https://')`). This violates ASVS 10.4.1 because: (1) The client sends a variable callback URL instead of a fixed, pre-registered one; (2) If the deployment violates the documented `ProxyPreserveHost On` assumption, an attacker controlling the Host header can craft an arbitrary callback URL; (3) If the authorization server uses pattern-based or prefix matching instead of exact string comparison, the authorization code could be redirected to an attacker-controlled domain. This could lead to authorization code theft and account takeover, contingent on AS redirect URI validation strictness and deployment configuration.
### Details
The vulnerability exists in `src/asfquart/generics.py` lines 63-68, where the callback URL is constructed from `quart.request.host_url`. This creates a dynamic redirect URI that varies based on the incoming request's Host header.
### Recommended Remediation
Pre-configure the callback host using an environment variable instead of deriving it from the request:
```python
import os
import urllib.parse
# In configuration
CALLBACK_HOST = os.environ.get('OAUTH_CALLBACK_HOST', 'https://myapp.apache.org')
# Modify setup_oauth() to accept callback_host parameter
def setup_oauth(app, uri: str, callback_host: str):
@app.route(uri)
async def oauth_endpoint():
state = secrets.token_urlsafe(16)
# Use fixed callback_host instead of request.host_url
callback_url = urllib.parse.urljoin(callback_host, f'{uri}?state={state}')
# ... rest of implementation
```
This ensures the callback URL is fixed and can be pre-registered with exact string matching at the Authorization Server.
### Acceptance Criteria
- [ ] `OAUTH_CALLBACK_HOST` environment variable added to configuration
- [ ] `setup_oauth()` modified to accept `callback_host` parameter
- [ ] Callback URL constructed from fixed configuration instead of Host header
- [ ] Unit tests verify callback URL is not affected by Host header
- [ ] Integration tests verify OAuth flow with fixed callback URL
- [ ] Documentation updated with required environment variable
- [ ] Deployment guide updated to emphasize fixed callback URL registration
### References
- Source reports: L1:10.4.1.md
- Related findings: FINDING-273
- ASVS sections: 10.4.1
- CWE: CWE-601
### Priority
Medium
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.