Skip to content

Security & Privacy

This page answers the "why does this add-on exist" and "is it safe" questions in one place. The short version: the proxy hides visitor IPs from external image origins, protects your server against being used as an SSRF gadget, and never sends secrets to the browser.

What the Proxy Hides

When the Image Proxy is active, image bytes are fetched server-side and streamed to the browser from your own host. As a result, the third-party image origin no longer learns:

  • Visitor IP address — the only IP it sees is your server's.
  • Visitor User-Agent — the outbound fetch uses the plugin's own User-Agent.
  • Referer — not set on the outbound fetch.
  • Cookies for the origin domain — never sent.

What Still Leaves the Server

The outbound fetch itself is real network traffic. The image origin learns the server's IP address (which is by definition a single value, not a stream of visitor IPs) and the URL of the image being fetched. This is the intentional trade-off: one server-to-origin connection per cache miss, zero visitor-to-origin connections.

SSRF Protection

The pipeline includes a security guard designed to prevent server-side request forgery — i.e. an attacker convincing the proxy to fetch a URL that hits your internal network.

The check happens in this order:

  1. Scheme allowlist. Only http:// and https:// URLs are accepted. Anything else fails with invalid_scheme.
  2. DNS resolution. The host is resolved to its IP addresses once.
  3. Private IP blocklist. Every resolved IP is checked against a blocklist that covers loopback (127.0.0.0/8, ::1), link-local (169.254.0.0/16, fe80::/10), multicast, RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), and the IPv6 equivalents. A match fails with ip_blocked.
  4. DNS pinning. The resolved IPs are passed straight to cURL via CURLOPT_RESOLVE so the second DNS lookup (the actual fetch) cannot resolve to a different (private) IP. This closes the DNS-rebinding window between the security check and the fetch.
  5. No HTTP redirects. The fetcher disables redirect following, so an origin cannot redirect the proxy to a private URL after the fact.
  6. Maximum body size. Responses larger than the configured cap fail with too_large — keeps the proxy from being used to slurp huge files through your bandwidth.

Origin Allowlist

The security guard supports an origin allowlist — a list of host names the proxy is allowed to fetch from. When the list is non-empty, any URL whose host is not on the list fails with origin_not_allowed.

The default list is empty, which means every HTTPS origin is permitted (subject to the SSRF checks above). The in-product editor for the allowlist is on the roadmap; until it ships, the allowlist is empty by default and can be customised programmatically.

Signed Proxy URLs

By default proxy URLs are unsigned — anyone who knows the URL pattern can ask your proxy to fetch any (allowed) origin. For most sites that's fine. If you want to prevent third parties from using your proxy as an open relay, enable URL signing.

When signing is active:

  • Every proxy URL emitted by the plugin carries an HMAC-SHA256 signature derived from a secret stored on your server.
  • Requests without a signature fail with signature_missing.
  • Requests with a tampered signature fail with signature_invalid.
  • The secret is never sent to the browser.

The signing secret can be rotated at any time from Tools → Signing secret. Rotation invalidates every previously emitted signed URL — that's the point. Pages that still reference the old URLs will display broken images until they re-render.

What Happens When an Image Fails to Load

If any stage of the pipeline fails — signature check, SSRF guard, origin fetch, decoding — the proxy returns an HTTP error response (403, 502, or 500 depending on the stage) with the body Image proxy error. The visitor's browser shows the standard broken-image icon.

There is no fallback to the original third-party URL under any circumstance. The original URL is never sent to the visitor's browser on error. This is by design — the entire purpose of the proxy is that the visitor's IP, User-Agent, and Referer never reach the image origin. A fallback to the original URL would silently void that guarantee whenever the proxy malfunctions, which is precisely the moment the user least wants their privacy posture to change.

If you need "always show the image, even at the cost of revealing the visitor to the origin", the right tool is ASA2 Core's Local Images feature, which downloads images permanently to your media library. Different trade-off (storage and freshness instead of dynamic), same end-state ("no third-party request from the visitor").

What is Logged

The plugin records pipeline activity in two layers:

  • Built-in (always on). Short rolling counters and a small ring buffer of recent error codes. This is what powers the Dashboard. Data is stored in WordPress transients and does not include visitor IPs, User-Agents, or request URLs.
  • ASA2 Advanced Log (optional). When Advanced Log is installed and a database (or external) handler is configured, every proxy event is also written to the persistent log. This gives you historical search and the Open full log link in the Dashboard's recent-errors panel.

If you want full request-by-request history, install Advanced Log and enable its database handler. If you only want a rolling overview, the built-in counters are enough.

ASA2 - The Amazon Affiliate Plugin for WordPress