Commit 189ad6f
feat(signing): wire SSRF guard into legacy webhooks.deliver()
Closes #299.
`adcp.webhooks.deliver()` (the legacy AdCP 3.x HMAC-SHA256 / Bearer auth
path) constructed an unpinned `httpx.AsyncClient(timeout=...)` and POSTed
to a buyer-controlled URL when no operator client was supplied. No SSRF
guard. A buyer-supplied URL pointing at 127.0.0.1 or AWS metadata would
deliver successfully — same security hole that PR #297 closed for
`WebhookSender`.
Surfaced by security-reviewer on PR #297 as L4 — explicitly deferred
from the prep PR scope. Now addressed.
The fix mirrors the WebhookSender pattern at webhook_sender.py:_send_bytes:
- When operator supplies a client, trust them completely (vetted egress
proxy with mTLS, ASGI test transport, etc.).
- When sender owns the client, build a per-request
AsyncIpPinnedTransport via build_async_ip_pinned_transport(url, ...).
trust_env=False prevents HTTPS_PROXY env-var bypass.
follow_redirects=False prevents rebinding-via-redirect.
New kwargs forwarded to the pinned-transport build:
- allow_private: bool = False — dev/CI escape hatch for internal endpoints
- allowed_ports: frozenset[int] | None = None — opt-in port-allowlist hardening
Three regression tests:
- test_deliver_owned_client_rejects_loopback_destination
- test_deliver_allow_private_dev_escape_hatch
- test_deliver_operator_supplied_client_skips_ssrf_guard
This is a behavior change for adopters on the legacy `deliver()` path
posting to private/internal endpoints (dev/test fixtures); they need to
add `allow_private=True` to preserve workflow. Production deployments
posting to real buyer URLs are unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 2fdc3d6 commit 189ad6f
2 files changed
Lines changed: 146 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
705 | 705 | | |
706 | 706 | | |
707 | 707 | | |
| 708 | + | |
| 709 | + | |
708 | 710 | | |
709 | 711 | | |
710 | 712 | | |
| |||
728 | 730 | | |
729 | 731 | | |
730 | 732 | | |
731 | | - | |
732 | | - | |
733 | | - | |
734 | | - | |
735 | | - | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
736 | 750 | | |
737 | 751 | | |
738 | 752 | | |
| |||
768 | 782 | | |
769 | 783 | | |
770 | 784 | | |
771 | | - | |
772 | | - | |
773 | | - | |
774 | | - | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
775 | 792 | | |
776 | 793 | | |
777 | 794 | | |
| |||
862 | 879 | | |
863 | 880 | | |
864 | 881 | | |
865 | | - | |
866 | 882 | | |
867 | | - | |
868 | | - | |
869 | | - | |
870 | | - | |
871 | | - | |
872 | | - | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
873 | 908 | | |
874 | 909 | | |
875 | 910 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
546 | 546 | | |
547 | 547 | | |
548 | 548 | | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
0 commit comments