Duobox

Privacy

Images in your email without a button and without handing the sender your IP: the image proxy

Why loading an email's images told the sender your IP and your device, and how a signed proxy shows them anyway without the request ever leaving your browser.

October 30, 2026

If you use the Duobox webmail, this is for you: why the images in your mail now show on their own, without the Show images button, and what happens behind the scenes when they load.

An HTML email almost never carries its images inside. It carries addresses: <img src="https://newsletter.example.com/logo.png">. To draw them, someone has to fetch them from that server, which belongs to the sender.

The problem

There were two ways to handle it, and both were wrong.

Block them and show a button. That's what we did: every message arrived with Images hidden on top, and you had to click Show. Today almost all business mail —invoices, newsletters, notices from a supplier— comes with images, so the button got clicked every time. A permission you always grant doesn't protect anything: it just gets in the way.

Load them directly. Your browser asks the sender's server for each image, and that request tells it your IP —and with it roughly where you are and which network you're on—, which browser and which device you use. If the message also uses a different address per recipient, the sender knows it was you. And if the page isn't careful, the message also loads outside stylesheets and fonts, which tell the same story.

What we did

Images go through our own proxy. Your browser never asks the sender for them: it asks api.duobox.io/img, and our server fetches them and hands them back. What reaches the other side is a request from a Duobox server, not from you.

An open proxy would let anyone use our server as a middleman, so it has three fences:

  • Signature. When you open a message, the API finds every image in the HTML and signs its address with a key only we hold. The proxy only fetches signed addresses: it can't be used to ask for anything else.
  • Public addresses only. An image could point at an internal address —localhost, our servers' network— to get the proxy in through it. Every address, and every redirect it follows, is resolved and rejected if it isn't public. There are limits on time (10 seconds), size (8 MB) and type: images only, never SVG, which can carry code.
  • The message page. The message is drawn in a frame with no scripts, under a policy that only lets images load from the proxy or from inside the message itself. An image written in a way we didn't recognize simply doesn't show. It never goes straight to the sender.

Images aren't stored on our side: your browser is what remembers them, for a day.

What doesn't change

The sender can still know that you opened the message and when: the request for the pixel still happens, even if our server makes it. What they stop knowing is where you are and what you opened it with. Fetching images as soon as the message arrives, before you open it, would hide that too; we don't do that yet.

What you need to do

Nothing. Open a message with images and they show, no button. In the installed app, messages that were already saved are fetched again once so their images go through the proxy.

← Back to the changelog