Files
gh-christianlouis-docuelevate/.jules/sentinel.md
T
google-labs-jules[bot] 46a9a30af0 🛡️ Sentinel: [HIGH] Fix SSRF bypass via httpx redirects
🚨 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>
2026-04-06 02:55:58 +00:00

4.9 KiB

2024-05-24 - SSRF in WebDAV connection test

Vulnerability: The _test_webdav_connection function had a custom SSRF check that failed to resolve DNS names, allowing attackers to bypass the check by providing a domain that resolves to an internal IP (e.g., 127.0.0.1). Learning: DNS resolution is required for robust SSRF protection when validating URLs provided by users. Prevention: Use a centralized is_private_ip function (now in app/utils/network.py) that resolves the hostname to its IPs and checks if any are private.

2026-03-22 - B310: urllib.request.urlopen replaced with httpx

Vulnerability: The _test_webdav_connection function used urllib.request.urlopen, which natively supports dangerous schemes like file:// or ftp:// and follows redirects by default, potentially allowing SSRF bypasses or Local File Inclusion. Learning: urllib.request should be avoided for user-supplied URLs. Even when URL schemes are manually validated, urllib's default redirect following behavior can bypass SSRF protections (e.g. redirecting to 127.0.0.1). Prevention: Use a modern, safer HTTP client like httpx with follow_redirects=False when testing user-provided URLs.

2026-03-20 - Safe Path Traversal Prevention in Low-Level Utilities

Vulnerability: The generic file utility hash_file in app/utils/file_operations.py accepted any file path and was vulnerable to reading arbitrary files via path traversal (e.g., ../../../etc/passwd) or absolute paths if an attacker could control the filepath argument. Learning: Naively checking for ".." in path breaks legitimate relative paths used internally by the application. Blocking absolute paths entirely also breaks functionality. Input validation should occur at the API boundary, but for defense-in-depth, low-level utilities must enforce expected boundaries (e.g., the application's workdir). Prevention: Use pathlib.Path.resolve() on both the target path and the allowed base directory (settings.workdir). Ensure the resolved target path is strictly within the allowed boundary using filepath_obj.relative_to(workdir_obj), catching the ValueError that is raised when the path is out of bounds. This safely blocks both relative traversal attacks and arbitrary absolute paths.

2025-05-18 - [SSRF Bypass via DNS Resolution Failure]

Vulnerability: The is_private_ip function in app/utils/network.py failed open (returned False) when a hostname could not be resolved (socket.gaierror). Learning: This fail-open pattern was originally added to allow external domains in tests, but in production, it created a severe SSRF risk. An attacker could bypass SSRF protections by providing a URL that fails to resolve during the security check but resolves later (DNS rebinding), or by exploiting internal routing behaviors via unresolvable addresses. Prevention: Always fail securely in network authorization functions. If a domain cannot be resolved to verify its safety, the request must be blocked (return True / default-deny). Tests should mock DNS resolution correctly instead of compromising production security logic.

2026-03-26 - SSRF in Integration Connection Tests

Vulnerability: The _test_imap_connection and _test_s3_connection functions in app/api/integrations.py did not validate user-provided host and endpoint_url variables against is_private_ip(). This allowed an attacker to test the presence of internal IMAP servers or direct S3 SDK API calls to internal infrastructure via SSRF. Learning: Any time a new generic connection or integration test is added, SSRF validation may be forgotten if the core network utility (is_private_ip) is not systematically applied to all outbound network operations, regardless of the protocol (e.g., IMAP, S3). Prevention: Establish a pattern where any user-configurable host or endpoint URL is immediately passed through the centralized is_private_ip validation function before any network call or third-party client initialization.

2026-03-27 - SSRF Bypass via HTTP Redirects in httpx

Vulnerability: The /process-url endpoint used httpx.AsyncClient(follow_redirects=True) after validating the initial user-provided URL against SSRF protections. However, it did not validate the target URLs of any subsequent HTTP redirects, allowing an attacker to provide a safe URL that redirects to an internal/private IP, bypassing the security check. Learning: Initial URL validation is insufficient when the HTTP client is configured to follow redirects automatically. The client must be explicitly configured to validate every redirect target. Prevention: When using httpx.AsyncClient(follow_redirects=True) for user-provided URLs, always implement a redirect validator hook function (e.g., using event_hooks={'response': [validate_redirect]}) that resolves the Location header and passes it through the same SSRF validation logic before the redirect is followed.