Link Guard Thunderbird v0.14.0 Source on GitHub

Warning rules

Warning rules add your own warnings. A rule has a label, a target and a pattern; when the pattern matches, the label is shown as a warning and the link behaves like any link with a warning: it stays inactive until you approve its exact host, and the label stays visible next to it.

Rules can only add warnings. Nothing in a rule or warning list can approve a link or remove a block.

You can add rules in two ways:

Targets

Target Setting label Matched against
host Host the destination host, e.g. login.example.org
url Full URL the full destination URL, both as written and percent-decoded
text Link text the visible text of the link (its first 1,024 characters)

The full URL is the destination as Thunderbird would open it, resolved against a <base href> in the message where there is one. Matching it percent-decoded as well means %77p-admin cannot slip past a rule for wp-admin.

Pattern syntax

Patterns are regular expressions from a deliberately small syntax that can be matched in linear time. They are case-insensitive and match anywhere in the target unless anchored.

Syntax Meaning
abc literal characters
. any character, including line breaks (unlike JavaScript)
[abc], [a-z], [^/] character classes, ranges and negated classes
\d \w \s digit, word character (a–z, A–Z, 0–9, _), whitespace
\D \W \S their negations
\t \n \r tab, line feed, carriage return
\. \/ \( … escaped punctuation, matched literally
( … ), (?: … ) groups (both only group; nothing is captured)
a|b alternatives
^, $ start and end of the target
* + ? zero or more, one or more, optional
{n} {n,} {n,m} repetition, with counts up to 50

A lazy marker after a quantifier (*?, +?) is accepted and has no effect, since only whether a pattern matches is relevant.

Not supported, and rejected with a message: backreferences (\1), lookahead and lookbehind ((?=…), (?<=…)), word boundaries (\b, \B), \u, \x and other letter escapes, and named groups. These features either need backtracking or are easy to misread.

Limits

Limit Value
Pattern length 200 characters
Repetition count 50
Group nesting 16 levels
Compiled size 512 instructions (a pattern like (a{50}){50} is too complex)
Label 1 to 60 characters
Characters no control, bidirectional or zero-width characters in labels or patterns
Own rules 50
Warning lists 10, with up to 50 rules each
Rules in effect 200 in total

Why matching cannot freeze Thunderbird

Patterns never run on the JavaScript regular-expression engine. Link Guard compiles them into a small automaton and simulates it breadth-first, so the work grows linearly with the length of the input. Patterns such as (a+)+$, which can take exponential time in ordinary engines, run in milliseconds.

The total matching work per message is also capped. If a message exhausts it, the remaining links show ⚠ Rules not checked and stay inactive until you approve them, rather than passing unchecked.

Examples

Rules can only say "warn if this matches". A rule such as "warn about every host of our domain except the login host" would need lookahead, which is not supported; write a rule for the hosts you want to warn about instead – as in the recommended rule below.

Phishing mail often uses domains that contain a well-known name but do not belong to its owner: nullringresearch-support.de, my-nullringresearch.de, nullringresearch.com or nullringresearch.de.evil.example. If your organisation's domain is nullringresearch.de, this rule warns about every such host while nullringresearch.de itself and all its subdomains stay quiet:

The name is suspicious when the character right before it is a letter, digit or hyphen (my-nullringresearch), or when anything other than exactly .de at the end follows it:

Part Catches
[a-z0-9-]nullringresearch my-nullringresearch.de, xnullringresearch.de
nullringresearch[a-z0-9-] nullringresearch-support.de, nullringresearchs.de
nullringresearch\.[^d] nullringresearch.com, nullringresearch.net
nullringresearch\.d[^e], nullringresearch\.d$ nullringresearch.dk
nullringresearch\.de. nullringresearch.de.evil.example, nullringresearch.dev

It stays quiet for nullringresearch.de, www.nullringresearch.de and mail.nullringresearch.de, because there the name is preceded by nothing or a dot and followed by exactly .de. Patterns are case-insensitive, so NullRingResearch-Login.net warns too.

For another domain, replace the name in both places and spell out its top-level domain letter by letter in the last group: every shorter or different ending, and the full ending followed by more. For example.com:

[a-z0-9-]example|example([a-z0-9-]|\.([^c]|c[^o]|co[^m]|c$|co$|com.))

The rule complements the built-in warnings: typing errors such as nullringreseach.de are caught by the lookalike warning once your domain is approved, and look-alike letters from other alphabets by the internationalized domain name warning. Mail from partners whose domains legitimately contain your name will warn as well; approve those hosts exactly.

Warning list format

{
  "format": "link-guard-warnings",
  "version": 1,
  "name": "Example warning rules",
  "rules": [
    { "label": "Archive download", "target": "url", "pattern": "\\.(zip|rar|7z|iso)$" },
    { "label": "Payment request", "target": "text", "pattern": "pay\\s*now|invoice|overdue" }
  ]
}
Field Value
format always "link-guard-warnings"
version always 1
name 1 to 60 characters, same character restrictions as labels
rules 1 to 50 rules, each with exactly label, target (host, url or text) and pattern

In JSON, every backslash in a pattern is written twice: the pattern \.zip$ becomes "\\.zip$".

Warning lists may be at most 64 KiB and use the same remote-source requirements as host lists. They are shown for review, start disabled and change only when you click Review remote update – they are never updated automatically.

In the notice, a rule's warning names its source, for example My rule: Archive download or Example warning rules: Archive download, so you can always tell which list raised it.

A complete example is in the repository: warnings-example.json.

What a hostile warning list can do

Very little: it can add misleading or excessive warnings, which keep links inactive until you approve them. It cannot approve a link, remove a block, switch off a built-in warning or slow Thunderbird down. Labels are always shown together with the name of the list that contains them.