Commit Graph

16 Commits

Author SHA1 Message Date
google-labs-jules[bot] 5b41d32f90 🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in webhooks
Adds validation to webhook URLs before attempting to deliver them to prevent
SSRF attacks targeting private IP ranges, local host, and cloud metadata endpoints.
Validates URL schema, hostname, and applies `is_private_ip()`. Also resolved ruff linting
errors. Tests have been expanded to ensure validation covers all cases.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-05-17 15:04:09 +00:00
Christian Krakau-Louis a3ea215a1c Merge branch 'main' into sentinel/ssrf-redirect-bypass-15997970627137004397 2026-04-07 11:33:59 +02:00
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
google-labs-jules[bot] a75e8b9297 🛡️ Sentinel: [HIGH] Fix SSRF bypass via HTTP redirects in url_upload
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-30 03:02:05 +00:00
google-labs-jules[bot] a57766ed7e 🛡️ Sentinel: [HIGH] Fix SSRF in integrations connection test
Adds validation using `is_private_ip()` for user-provided hosts in `_test_imap_connection` and `_test_s3_connection` to prevent Server-Side Request Forgery vulnerabilities.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-26 04:00:55 +00:00
Christian Krakau-Louis 1e7f2275d3 Merge branch 'main' into sentinel-fix-ssrf-dns-resolution-16520734505214840647 2026-03-23 17:16:53 +01:00
Christian Krakau-Louis f9b4975093 Merge branch 'main' into sentinel-ssrf-imap-9566695902417221069 2026-03-23 17:14:50 +01:00
Christian Krakau-Louis c25e1b0e21 Merge branch 'main' into sentinel/fix-path-traversal-3335474446649715249 2026-03-23 17:07:30 +01:00
google-labs-jules[bot] 1018ea17d9 🛡️ Sentinel: [CRITICAL] Fix path traversal vulnerability in file utilities
🚨 Severity: CRITICAL
💡 Vulnerability: The generic file hashing utility `app/utils/file_operations.py:hash_file` was vulnerable to path traversal. An attacker controlling the `filepath` argument could read arbitrary files on the system by passing relative paths like `../../../etc/passwd` or providing absolute paths directly.
🎯 Impact: This could lead to Arbitrary File Read and potential information disclosure.
🔧 Fix: Used `pathlib.Path.resolve()` to resolve both the target file path and the allowed base directory (`settings.workdir`). Added a strict check to ensure the resolved target path is strictly within the allowed boundary using `filepath_obj.relative_to(workdir_obj)`, catching the `ValueError` raised when the path is out of bounds. This safely blocks both relative traversal attacks and arbitrary absolute paths, without breaking legitimate relative application paths.
 Verification: Ran the test suite `pytest tests/test_path_traversal_security.py -v` successfully, which explicitly checks for `FileNotFoundError` upon traversal attempts.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 15:53:18 +00:00
google-labs-jules[bot] 06b0fced38 🛡️ Sentinel: [HIGH] Fix SSRF bypass on DNS resolution failure
Modified `is_private_ip` in `app/utils/network.py` to fail securely by returning True (blocking the request) when a hostname cannot be resolved. The previous implementation failed open, creating a risk for Server-Side Request Forgery (SSRF) and DNS rebinding attacks.

Updated corresponding tests to expect the secure behavior and correctly appended the security finding to the Sentinel journal.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 15:25:53 +00:00
google-labs-jules[bot] d22175310a 🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in IMAP connections
🚨 Severity: HIGH
💡 Vulnerability: User-provided IMAP `host` in `_test_imap_connection` and `pull_inbox` was not validated against private IPs, creating an SSRF risk.
🎯 Impact: Attackers could abuse the endpoints to port-scan or interact with internal/private network services.
🔧 Fix: Integrated `is_private_ip` from `app.utils.network` to block connections resolving to private, loopback, link-local, or reserved IPs.
 Verification: Ran `test_imap_tasks.py` and `test_api_imap_accounts.py` successfully. Checked `ruff` output and diffs. Removed all scratch files from the commit.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 14:45:22 +00:00
Christian Krakau-Louis d94e9ca4bc Merge branch 'main' into sentinel-ssrf-imap-9566695902417221069 2026-03-23 15:39:29 +01:00
google-labs-jules[bot] d71945b7b9 🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in IMAP connections
🚨 Severity: HIGH
💡 Vulnerability: User-provided IMAP `host` in `_test_imap_connection` and `pull_inbox` was not validated against private IPs, creating an SSRF risk.
🎯 Impact: Attackers could abuse the endpoints to port-scan or interact with internal/private network services.
🔧 Fix: Integrated `is_private_ip` from `app.utils.network` to block connections resolving to private, loopback, link-local, or reserved IPs.
 Verification: Ran `test_imap_tasks.py` and `test_api_imap_accounts.py` successfully. Checked `ruff` output and diffs.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 14:38:34 +00:00
google-labs-jules[bot] 8b4280d5dd 🛡️ Sentinel: [HIGH] Fix SSRF bypass on DNS resolution failure
Modified `is_private_ip` in `app/utils/network.py` to fail securely by returning True (blocking the request) when a hostname cannot be resolved. The previous implementation failed open, creating a risk for Server-Side Request Forgery (SSRF) and DNS rebinding attacks.

Updated corresponding tests to expect the secure behavior.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 13:42:14 +00:00
google-labs-jules[bot] b5ed16c1c8 Security: Replace urllib.request with httpx in WebDAV testing
The `_test_webdav_connection` function previously used `urllib.request.urlopen`
to verify connection credentials. This triggers a Bandit B310 warning because
`urllib` supports multiple schemes (like file://, ftp://) and implicitly follows
redirects.

Although scheme checking and a basic `is_private_ip` validation were implemented,
using `urllib.request` remains risky because a public URL could return an
HTTP redirect to a private IP (e.g., 127.0.0.1) which `urllib` would blindly follow,
causing an SSRF (Server-Side Request Forgery) bypass.

This commit replaces `urllib.request` with `httpx.request` using explicitly
`follow_redirects=False`. This eliminates the B310 vulnerability, ensures
requests only hit the specified URL without following potentially malicious
redirects, and standardizes the application on `httpx` for safer HTTP connections.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-22 03:58:07 +00:00
google-labs-jules[bot] 8079db7893 🛡️ Sentinel: [HIGH] Fix SSRF in WebDAV connection test
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 04:10:11 +00:00