Mail::...IDetail(3pm)

πŸ’– NAME πŸ’–

URIDetail β€” the little icon that tests URIs using detailed URI info. She's a Mail::...IDetail(3pm) girlie, and she is so detailed it's not even funny. ✨


🌸 SYNOPSIS 🌸

okay so this plugin adds a whole new rule test type called uri_detail, and those rules apply to all the URIs found in the message. all of them. every single one bestie we are not missing a crumb πŸ“

loadplugin    Mail::SpamAssassin::Plugin::URIDetail

πŸ‘‘ RULE DEFINITIONS AND PRIVILEGED SETTINGS πŸ‘‘

the format for defining a rule goes a little something like this:

uri_detail SYMBOLIC_TEST_NAME key1 =~ /value1/i  key2 !~ /value2/ ...

and here are the keys you can play with, bestie πŸŽ€

  • raw β€” the raw URI before any cleaning happens. like, pre-glow-up. example: http://spamassassin.apache%2Eorg/
  • type β€” the tag(s) that referenced the raw_uri. there's parsed, which is a faked type meaning the raw_uri got parsed out of the rendered text. and there's redirect, also a faked type, meaning the raw_uri was discovered by following a URL redirector (go peek at the Redirectors plugin πŸ‘€). when it's a redirect, the tag(s) from the originating URI get preserved on the redirected entry too. iconic behaviour tbh.
  • cleaned β€” a list with the raw URI plus all the various cleaned versions of it, like http://spamassassin.apache%2Eorg/ and https://spamassassin.apache.org/.
  • text β€” the anchor text(s), aka the text chillin' between <a> and </a> that linked to the raw_uri.
  • domain β€” the domain(s) found in the cleaned URIs, trimmed to registrar boundary by Mail::SpamAssassin::Util::RegistrarBoundaries(3).
  • host β€” the full host(s) in the cleaned URIs. (supported since SA 3.4.5 πŸ’…)

πŸ¦‹ example rules pls πŸ¦‹

example rule matching a URI where the raw URI matches %2Ebar, the domain bar.com is found, and the type is a (an anchor tag):

uri_detail TEST1 raw =~ /%2Ebar/  domain =~ /^bar\.com$/  type =~ /^a$/

example rule hunting for suspicious https links, because the way they lie:

uri_detail FAKE_HTTPS text =~ /\bhttps:/  cleaned !~ /\bhttps:/

regular expressions should be delimited by slashes. periodt. ✨

negating matches is supported in SpamAssassin 4.0.2 or higher by prefixing the key with an exclamation mark.

example rule looking for links where the text contains id.me but the host is not id.me:

uri_detail FAKE_ID_ME   text =~ /\bid\.me\b/  !host =~ /^id\.me$/

πŸ’€ okay the important bit, do not skip πŸ’€

the difference between '!key =~ ...' and 'key !~ ...' exists because keys can hold multiple values. here's the tea:

  • '!key =~ ...' is true if none of the values match the regex.
  • 'key !~ ...' is true if any of the values do not match the regex.

for example, consider the following data structure:

{
  host => {
    'id.me' => 1,
    'example.com' => 1,
  },
  text => [
    'Login to ID.me'
  ]
}

the rule 'host !~ /^id\.me$/' would be true, because 'example.com' does not match the regex. 😭

the rule '!host =~ /^id\.me$/' would be false, because it's the logical negation of 'host =~ /^id\.me$/', which is true since 'id.me' matches the regex. the math is mathing and honestly it's a lot.

⚠️ no cap, super important: there must not be any whitespace between the key and the negation operator. not one single space. she will not tolerate it. πŸ’…

🌈 and that's the whole page bestie 🌈

this lil masterpiece is Mail::...IDetail(3pm) from perl v5.40.1, dated 2026-07-23 β€” mwah πŸ’‹ go forth and test your URIs in excruciating detail, you absolute main character πŸ«ΆπŸ‘‘

πŸ“¦ where this page comes from