security: fix #1 — wire SSRF hook into E621Client custom client

E621 maintains its own httpx.AsyncClient because their TOS requires
a per-user User-Agent string that BooruClient's shared client can't
carry. The client is rebuilt on User-Agent change, so the hook must
be installed in the same construction path.

Also installs BooruClient._log_request as a second hook (this
additionally closes finding #16 for the e621 client — e621 requests
previously bypassed the connection log entirely, and this wires
them in consistently with the base client).

Audit-Ref: SECURITY_AUDIT.md finding #1
Also-Closes: SECURITY_AUDIT.md finding #16 (e621 half)
Severity: High
This commit is contained in:
pax 2026-04-11 16:11:12 -05:00
parent ec79be9c83
commit ef95509551

View File

@ -8,6 +8,7 @@ import threading
import httpx
from ..config import DEFAULT_PAGE_SIZE, USER_AGENT
from ._safety import validate_public_request
from .base import BooruClient, Post, _parse_date
log = logging.getLogger("booru")
@ -47,6 +48,12 @@ class E621Client(BooruClient):
headers={"User-Agent": ua},
follow_redirects=True,
timeout=20.0,
event_hooks={
"request": [
validate_public_request,
BooruClient._log_request,
],
},
limits=httpx.Limits(max_connections=10, max_keepalive_connections=5),
)
E621Client._e621_client = c