- Resolved the GitHub Actions CI deprecation warning by upgrading checkout/setup-python actions to support Node.js 24 (`v4.2.2` and `v5.4.0` respectively).
- Addressed the `pip-audit` failure (CVE-2026-4750) triggered by the malicious `fastar` dependency injection in `fastapi==0.136.3` by explicitly blocking that version (`fastapi[all]!=0.136.3`) in `requirements.txt`.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Added an `_escapeHtml` function to properly sanitize `file.name` before it is dynamically rendered into the DOM using `row.innerHTML`. This mitigates a DOM-based Cross-Site Scripting (XSS) vulnerability.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Combined duplicated `event_hooks` keyword arguments into a single dictionary parameter with both `validate_redirect` and `verify_redirect` in `app/api/url_upload.py`. This fixes a `SyntaxError: keyword argument repeated: event_hooks` and ensures that all redirect validations run.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Combined duplicated `event_hooks` keyword arguments into a single dictionary parameter with both `validate_redirect` and `verify_redirect` in `app/api/url_upload.py`. This fixes a `SyntaxError: keyword argument repeated: event_hooks` and ensures that all redirect validations run.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
🚨 Severity: HIGH
💡 Vulnerability: The `/process-url` endpoint used `httpx.AsyncClient` with `follow_redirects=True`. While the initial user-provided URL was validated against SSRF protections (blocking private/internal IPs), the client implicitly followed subsequent HTTP redirects without validating their target locations. This allowed an attacker to bypass the initial check by supplying a valid URL that redirected to an internal IP or cloud metadata endpoint.
🎯 Impact: An attacker could potentially access internal network services or cloud metadata endpoints.
🔧 Fix: Implemented an `event_hooks` listener (`validate_redirect`) on the `httpx.AsyncClient` that intercepts responses, extracts the `Location` header, resolves the absolute target URL, and applies the same `validate_url_safety` check before allowing the redirect to be followed.
✅ Verification: Ran `pytest tests/test_url_upload.py`, formatting checks via `ruff format` and linting via `ruff check`.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Resolve merge conflicts with main (PR #834 also fixed S3 SSRF)
- Add isinstance(endpoint_url, str) type check before urlparse to prevent TypeError on non-string values
- Reject endpoint_url with empty/missing hostname after parsing (malformed URLs like 'https://')
- Keep scheme validation (http/https only) and private IP blocking via is_private_ip()
- Add logger.warning for SSRF block events
- Add regression tests: non-string endpoint_url and empty hostname cases
- Update sentinel.md with consolidated SSRF entry
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>