Mail::...ortURLs(3pm)
π DecodeShortURLs β Mail::...ortURLs(3pm) π
okay bestie, sit down, hydrate, because we're decoding short URLs today and it's lowkey iconic. this is the page for Mail::...ortURLs, part of the user contributed Perl documentation for Mail::SpamAssassin::Plugin::DecodeShortURLs π¦
β¨ NAME β¨
DecodeShortURLs β Check for shortened URLs π
πΈ SYNOPSIS πΈ
like, here's the whole vibe, copy-paste ready:
loadplugin Mail::SpamAssassin::Plugin::DecodeShortURLs
url_shortener tinyurl.com
url_shortener_get bit.ly
url_shortener_custom_user_agent t.co curl/8.6.0
body HAS_SHORT_URL eval:short_url()
describe HAS_SHORT_URL Message has one or more shortened URLs
body SHORT_URL_REDIR eval:short_url_redir()
describe SHORT_URL_REDIR Message has shortened URL that resulted in a valid redirection
body SHORT_URL_CHAINED eval:short_url_chained()
describe SHORT_URL_CHAINED Message has shortened URL chained to other shorteners
body SHORT_URL_MAXCHAIN eval:short_url_maxchain()
describe SHORT_URL_MAXCHAIN Message has shortened URL that causes too many redirections
body SHORT_URL_LOOP eval:short_url_loop()
describe SHORT_URL_LOOP Message has short URL that loops back to itself
body SHORT_URL_200 eval:short_url_code('200') # Can check any non-redirect HTTP code
describe SHORT_URL_200 Message has shortened URL returning HTTP 200
body SHORT_URL_404 eval:short_url_code('404') # Can check any non-redirect HTTP code
describe SHORT_URL_404 Message has shortened URL returning HTTP 404
uri URI_TINYURL_BLOCKED m,https://tinyurl\.com/app/nospam,
describe URI_TINYURL_BLOCKED Message contains a tinyurl that has been disabled due to abuse
uri URI_BITLY_BLOCKED m,^https://bitly\.com/a/blocked,
describe URI_BITLY_BLOCKED Message contains a bit.ly URL that has been disabled due to abuse
π DESCRIPTION π
so the whole point of this plugin? it looks for URLs that got shortened by a whole list of URL shortening services π. the moment it spots a URL that matches, it sends an HTTP request over to the shortening service and grabs the Location-header that points at the actual shortened-away URL β¨. then it drops that URL into the list of URIs that SpamAssassin extracted, so uri rules and plugins like URIDNSBL can get their hands on it π«Ά
it also follows chained redirections, meaning a short URL that redirects to another short URL, and so on. you can set the redirection depth limit with max_short_url_redirections π
maximum of max_short_urls short URLs get checked per message (that's 10 by default, bestie). setting it to 0 disables HTTP requests entirely, which means only the short_url() test works, and it just reports the shorteners it found π
every supported rule type for checking short URLs and redirection status is documented in the SYNOPSIS section up there ^^^ π
π NOTES π
this plugin runs at priority -10, so it can modify the parsed URI list before normal uri rules or the URIDNSBL plugin do their thing β but after the Redirector plugin. it's giving main character timing, honestly β°
π USER SETTINGS π
url_shortener domain [domain...] β (default: none)
domains that should be considered an URL shortener π. and here's the cute part: if the domain begins with a ., then the 3rd level tld of the main domain gets checked π
example:
url_shortener tinyurl.com
url_shortener .page.link
url_shortener_get domain [domain...] β (default: none)
an alias to url_shortener β¨. the difference? the HTTP request goes out with the GET method instead of the default HEAD. this is required for some services, like bit.ly, to return the blocked URL correctly π¨
example:
url_shortener_get bit.ly
url_shortener_custom_user_agent domain user-agent β (default: none)
a custom HTTP user-agent for specific domains, instead of whatever's set as the default in url_shortener_user_agent π
. also required for some services, like t.co, to return the blocked URL correctly π―
example:
url_shortener_custom_user_agent t.co curl/8.6.0
clear_url_shortener [domain] [domain...]
clears the configured url_shortener and url_shortener_get domains β super handy when you wanna override default settings that came from an update channel π. if you specify domains, then only those get removed from the list π§Ή
π PRIVILEGED SETTINGS π
url_shortener_cache_type β (default: none)
the cache type being utilized. right now the only supported value is dbi, which implies url_shortener_cache_dsn is a DBI connect string. the DBI module is required β οΈ
example: url_shortener_cache_type dbi
url_shortener_cache_dsn β (default: none)
the DBI dsn of the database to use ποΈ
for SQLite, the database gets created automatically if it doesn't already exist, and the supplied path and file must be read/writable by whoever's running spamassassin or spamd βοΈ
for MySQL/MariaDB or PostgreSQL, check the sql-directory for the database table creation clauses π
you'll need the proper DBI module for your database β like DBD::SQLite, DBD::mysql, DBD::MariaDB or DBD::Pg π§©
minimum required SQLite version is 3.24.0 (available from DBD::SQLite 1.59_01) π§
examples:
url_shortener_cache_dsn dbi:SQLite:dbname=/var/lib/spamassassin/DecodeShortURLs.db
url_shortener_cache_username β (default: none)
the username used to connect to the database π. not used for SQLite.
url_shortener_cache_password β (default: none)
the password used to connect to the database π€«. not used for SQLite.
url_shortener_cache_ttl β (default: 86400)
how long a cache entry stays valid, in seconds β³. default is 86400, aka 1 day.
for database cleaning, go peek at url_shortener_cache_autoclean π§Ό
π¦ ADMINISTRATOR SETTINGS π¦
url_shortener_cache_autoclean β (default: 1000)
automatically purges old entries from the database π§½. the value describes a random run chance of 1/x. the default of 1000 means cleaning runs approximately once for every 1000 messages processed. a value of 1 would mean the database gets cleaned every single time a message is processed π
set 0 to disable automatic cleaning and just do it manually πͺ
url_shortener_loginfo β (default: 0 (off))
if this is enabled (set to 1), then short URLs and the decoded URLs get logged with info priority π
url_shortener_timeout β (default: 5)
maximum time a short URL HTTP request can take, in seconds β±οΈ
max_short_urls β (default: 10)
maximum amount of short URLs that get looked up per message π’. chained redirections are not counted β only the initial short URLs found, bestie.
setting it to 0 disables HTTP requests, which means only the short_url() test works, reporting any found shortener URLs π
max_short_url_redirections β (default: 10)
maximum depth of chained redirections that a short URL can generate π
url_shortener_user_agent β (default: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36)
sets the default User-Agent header for HTTP requests π΅οΈβοΈ. some services require it to look like a common browser. and fyi, the User-Agent can be overridden on a per url_shortener basis using the url_shortener_ua setting π
π«Ά ACKNOWLEDGEMENTS π«Ά
the original DecodeShortURLs plugin was developed by Steve Freegard π β legend behavior, fr fr.
aaaand that's the whole page, bestie π this was Mail::...ortURLs(3pm) from the User Contributed Perl Documentation, shipping with perl v5.40.1 and dated 2026-07-23 β¨ go forth, decode those short URLs, and slay π
ππΈ
π¦ where this page comes from
- ubuntu stonking: spamassassin 4.0.2+svn1935691-1build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms