Preserve POST semantics through proxies (#2498)

This commit is contained in:
Matt
2026-08-06 21:32:02 -04:00
committed by GitHub
parent 9ff9115dcf
commit 8d8bbdc060
3 changed files with 31 additions and 29 deletions
+1
View File
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added root contributor and security policies, structured issue forms, repository agent guidance, discovery terminology, and an operator-focused documentation wiki ([d090a29a](https://github.com/laramies/theHarvester/commit/d090a29a), [7c491ef5](https://github.com/laramies/theHarvester/commit/7c491ef5), [8b9d420b](https://github.com/laramies/theHarvester/commit/8b9d420b)).
### Changed
- Fixed proxied POST requests so they retain the request method, body, and query parameters.
- Migrated Pentest-Tools discovery to its API v2 Bearer-authenticated scan, status, and output endpoints.
- Included HIBP verified-domain in `all` and matching capability selectors like every other P0 source, with REST operator authentication applied after source expansion when its provider key is configured.
- Allowed REST `/query` requests to select discovery sources by result capability, matching the CLI's union semantics while preserving explicit source selection.
+14 -4
View File
@@ -494,7 +494,7 @@ async def test_post_fetch_can_include_response_metadata(monkeypatch) -> None:
@pytest.mark.asyncio
async def test_post_fetch_proxy_branch_uses_get_with_http_proxy(monkeypatch) -> None:
async def test_post_fetch_proxy_branch_posts_body_and_params_with_http_proxy(monkeypatch) -> None:
reset_dummy_sessions()
created_connectors = []
monkeypatch.setattr(core_module.aiohttp, 'ClientSession', DummySession)
@@ -509,12 +509,22 @@ async def test_post_fetch_proxy_branch_uses_get_with_http_proxy(monkeypatch) ->
monkeypatch.setattr(AsyncFetcher, '_create_connector', fake_create_connector)
result = await AsyncFetcher.post_fetch('https://example.com/resource', proxy=True)
result = await AsyncFetcher.post_fetch(
'https://example.com/resource',
json_body={'scan': 'example'},
params={'page': 2},
json=True,
proxy=True,
)
assert result == 'response-text'
assert result == {'ok': True}
assert created_connectors == [('http://proxy.local:8080', 'http', 'ssl-context')]
session = DummySession.instances[0]
assert session.connector == 'connector'
assert session.requests == [
('GET', 'https://example.com/resource', {'proxy': 'http://proxy.local:8080'})
(
'POST',
'https://example.com/resource',
{'json': {'scan': 'example'}, 'params': {'page': 2}, 'proxy': 'http://proxy.local:8080'},
)
]
+16 -25
View File
@@ -610,32 +610,23 @@ class AsyncFetcher:
if proxy:
proxy_url, proxy_type = cls._resolve_proxy(proxy)
sslcontext = cls._ssl_context()
request_kwargs: dict[str, Any] = {
'data': cls._normalize_data(data) if json_body is None else None,
'proxy': proxy_url if proxy_type == 'http' else None,
}
if params != '':
async with await cls._build_session(headers, timeout, proxy_url, proxy_type, sslcontext) as session:
return await cls._request(
session,
'GET',
url,
params=params,
proxy=proxy_url if proxy_type == 'http' else None,
json=json,
json_body=json_body,
delay=5,
include_metadata=include_metadata,
)
else:
async with await cls._build_session(headers, timeout, proxy_url, proxy_type, sslcontext) as session:
return await cls._request(
session,
'GET',
url,
proxy=proxy_url if proxy_type == 'http' else None,
json=json,
json_body=json_body,
delay=5,
include_metadata=include_metadata,
)
request_kwargs['params'] = params
async with await cls._build_session(headers, timeout, proxy_url, proxy_type, sslcontext) as session:
return await cls._request(
session,
'POST',
url,
json=json,
json_body=json_body,
delay=3,
include_metadata=include_metadata,
**request_kwargs,
)
elif params == '':
async with await cls._build_session(headers, timeout) as session:
return await cls._request(