fix: resolve ssrf verification issue and xss in frontend
Resolves a Cross-Site Scripting (XSS) vulnerability in `frontend/templates/files.html` by applying `escapeHtml` and `sanitizeHighlight` functions when injecting search result attributes directly into the DOM via `innerHTML`. Also fixes an issue in `app/api/url_upload.py` where providing the `event_hooks` argument twice caused a `SyntaxError` (and potentially bypassed security hooks). Both `validate_redirect` and `verify_redirect` hooks are now safely consolidated into a single list for the `httpx.AsyncClient` initialization. Also updates tests and .gitignore to prevent CI issues. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
+1
-15
@@ -170,19 +170,6 @@ async def process_url(
|
||||
if not safe_filename:
|
||||
safe_filename = "download"
|
||||
|
||||
# Hook to validate redirects and prevent SSRF
|
||||
async def validate_redirect(response: httpx.Response):
|
||||
if response.is_redirect:
|
||||
location = response.headers.get("Location")
|
||||
if location:
|
||||
# Resolve relative URLs
|
||||
next_url = urllib.parse.urljoin(str(response.url), location)
|
||||
try:
|
||||
validate_url_safety(next_url)
|
||||
except HTTPException as e:
|
||||
# Reraise as a RequestError so httpx aborts the request
|
||||
raise httpx.RequestError(f"Unsafe redirect target: {e.detail}", request=response.request)
|
||||
|
||||
# Download file with security measures
|
||||
# Initialize target_path to None to prevent UnboundLocalError in exception handlers
|
||||
# that may execute before target_path is assigned during error cases
|
||||
@@ -194,11 +181,10 @@ async def process_url(
|
||||
async with httpx.AsyncClient(
|
||||
timeout=settings.http_request_timeout,
|
||||
follow_redirects=True,
|
||||
event_hooks={"response": [validate_redirect]},
|
||||
event_hooks={"response": [verify_redirect]},
|
||||
headers={
|
||||
"User-Agent": "DocuElevate/1.0", # Identify ourselves
|
||||
},
|
||||
event_hooks={"response": [verify_redirect]},
|
||||
) as client:
|
||||
async with client.stream("GET", url) as response:
|
||||
response.raise_for_status()
|
||||
|
||||
Reference in New Issue
Block a user