Writeups

User IP address leaked on email open.

Normally attacker-controlled email content is in a sandboxed iframe that can’t run javascript and the html is sanitized with DOMPurify.

<iframe
  title="Email content"
  src="about:blank"
  scrolling="yes"
  frameborder="0"
  class="w100"
  data-testid="content-iframe"
  data-subject="(No Subject)"
  sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"
  style="height: 58px;"></iframe>

To prevent HTTPLeaks values that would normally cause remote requests such as “src” and “url()” are prefixed with “proton-“.
If the user allows remote content to be loaded and the request is an image a proxy may be used to avoid sharing the users IP address.
But the CSS sanitization was missed if in an SVG tag, this could be exploited by the attacker to bypass privacy protections using a html contained email.

<svg>
  <style>
    circle {
      background-image: url(https://http.cat/200);
    }
  </style>
  <circle></circle>
</svg>

Link confirmation bypass

If a link did not start with the regex /^https?:\/\// it would be treated as internal this meant something like Https:// would bypass the check.

“This message contains remote content” bypass

By spoofing an email from a whitelisted address such as no-reply@news.protonvpn.com it’s possible to automatically load remote content.
Exceptions should not be made based of an attacker-controlled value. (Yes even if its sent to spam)

export const WHITE_LISTED_ADDRESSES = [
  // v3
  'notify@protonmail.com',
  // v4
  'no-reply@news.protonmail.com',
  'no-reply@news.protonvpn.com',
  'no-reply@app.protonmail.com',
  'no-reply@notify.protonmail.com',
  'no-reply@offer.protonmail.com',
  'no-reply@offer.protonvpn.com',
  'no-reply@notify.protonmail.com',
  'no-reply@notify.protonvpn.com',
  'no-reply@verify.protonmail.com',
  'no-reply@notify.protonmail.com',
  'no-reply@partners.protonvpn.com',
  'no-reply@notify.protonmail.com',
  // v5
  'no-reply@news.proton.me',
  'no-reply@news.protonvpn.com',
  'no-reply@news.proton.me',
  'no-reply@news.protonvpn.com',
  'no-reply@mail.proton.me',
  'no-reply@calendar.proton.me',
  'no-reply@drive.proton.me',
  'no-reply@vpn.proton.me',
  'no-reply@offers.proton.me',
  'no-reply@offer.protonvpn.com',
  'no-reply@notify.proton.me',
  'no-reply@notify.protonvpn.com',
  'no-reply@verify.proton.me',
  'no-reply@recovery.proton.me',
  'no-reply@partners.proton.me',
  'no-reply@referrals.proton.me'
];