mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
* fix(security): prevent auth header leakage across redirects * fix(security): harden redirect credential handling Address Copilot and Qodo review findings for #947. - Remove unused variables, imports, and unnecessary pass statements from tests. - Harden cross-origin redirect handling for per-request auth credentials. - Strip session-level auth handlers before cross-origin redirect hops. - Prevent session.auth from regenerating Authorization headers. - Disable trust_env during cross-origin hops to prevent .netrc credential injection. - Restore session auth and trust_env state reliably with try/finally. - Add regression coverage for auth=, session.auth, trust_env, and multi-hop redirects. - Preserve existing security behavior and same-origin authentication semantics. Validated with 189/189 security and affected tests passing. * fix(security): scope allow_private_ips to same-host redirects, fix error handling gaps Follow-up to review findings on #1067: - MCPClient hardcoded allow_private_ips=True for every redirect hop, not just its operator-configured host, so a compromised/malicious MCP server could 302 into private address space (e.g. cloud metadata) unchecked. request_with_ssrf_guard() gains allow_private_ips_on_redirect: a redirect target inherits the original host's private-IP trust only when it matches that host; MCPClient now pins it to False. - detect_public_api() only caught requests.exceptions.RequestException, but the SSRF guard raises ValidationError for blocked hosts/redirects, unlike its sibling ingest_public_api(). Now catches and re-raises it the same way. - detect_public_api()/ingest_public_api() forwarded session/allow_private_ips through **options into request_with_ssrf_guard(), which already passes both explicitly -- a caller supplying either would hit a duplicate-kwarg TypeError. Both are now popped from request_options first. New regression coverage for all three in tests/ingest/, plus a CHANGELOG entry under Unreleased/Security. --------- Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""
|
|
Shared pytest fixtures for the ingest test suite.
|
|
|
|
The ``mock_dns`` fixture is applied to *every* test in this directory
|
|
(``autouse=True``). It stubs out ``socket.getaddrinfo`` inside the SSRF
|
|
guard module so that unit tests that mock ``requests.Session.request`` do not
|
|
accidentally hit the network for DNS resolution — which would fail in offline
|
|
CI environments and cause intermittent timeouts.
|
|
|
|
Tests that explicitly need to exercise DNS-related behaviour (e.g. checking
|
|
that a hostname resolving to a private IP is blocked) override this fixture
|
|
by patching ``semantica.ingest.ssrf.socket.getaddrinfo`` with their own
|
|
``side_effect`` *inside* the test body; that inner patch wins because
|
|
``unittest.mock.patch`` applies patches in innermost-last order.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import socket
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
_PUBLIC_IP = "93.184.216.34" # example.com — a safe, routable public address
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def mock_dns():
|
|
"""Map every hostname to a safe public IP for the duration of each test."""
|
|
with patch(
|
|
"semantica.ingest.ssrf.socket.getaddrinfo",
|
|
return_value=[
|
|
(socket.AF_INET, socket.SOCK_STREAM, 6, "", (_PUBLIC_IP, 0))
|
|
],
|
|
):
|
|
yield
|