Add LinkedIn outbound redirections (redir/redirect, safety/go)

Closes #284 by @kalvdans. The same wrapper was reported on the GitHub mirror as GitHub issue 252 by @patrick-goli. Its example link has no scheme, which this rule leaves alone on purpose (see the examples).

Prerequisites

  • This rule only prevents tracking.
  • This rule does not destroy the function of the page.

Description

LinkedIn wraps outbound links in two redirect pages: linkedin.com/redir/redirect?url=… (for example certificate links on public profiles, see GitHub issue 252) and linkedin.com/safety/go?url=… (the "You are leaving LinkedIn" page, for example for links in the feed, see #284). The destination is in the url parameter, URL-encoded. This adds one redirection to the existing LinkedIn provider, so the link opens the destination directly without the LinkedIn hop.

Safety of the pattern:

  • It only matches the two LinkedIn paths on a LinkedIn host. linkedin.com.example.org does not match.
  • The captured destination must start with http:// or https://, plain or URL-encoded. The rule can never produce a javascript:, data: or relative url, and an empty url is ignored.
  • url may appear anywhere in the query; the capture stops at & or #.
  • The host prefix is the character class (?:[a-z0-9.-]*\.)? instead of the usual (?:[a-z0-9-]+\.)*?. Java's regex engine (URL Check, an Android app, ships this catalog) recurses once per repetition of a group, and the usual prefix overflowed a 512 KB thread stack at 5,000 host labels in a test. The class form handled inputs up to 160 KB in at most 10 ms, in Java and in JavaScriptCore.

Affected fields

  1. redirections of the provider LinkedIn

Change in data.min.json (provider LinkedIn)

"redirections": [
    "^https?:\\/\\/(?:[a-z0-9.-]*\\.)?linkedin\\.com\\/(?:redir\\/redirect|safety\\/go)\\/?\\?(?:url=|[^#]*?&url=)(https?(?::|%3[Aa])(?:\\/|%2[Ff]){2}[^&#]+)"
]

Example URLs

URL Result
https://www.linkedin.com/safety/go?url=https%3A%2F%2Fow.ly%2F1y7950PGZbq%3Ftrk%3Dfeed_main-feed-card-text (from #284) https://ow.ly/1y7950PGZbq?trk=feed_main-feed-card-text
https://www.linkedin.com/redir/redirect?url=https%3A%2F%2Fexample%2Ecom%2Fcert%2F9hJUZz&urlhash=D0OT https://example.com/cert/9hJUZz
https://www.linkedin.com/safety/go?url=https%3A%2F%2Fexample.com%2F&trk=flagship-messaging-web https://example.com/
https://www.linkedin.com/redir/redirect?url=www%2Eefset%2Eorg%2Fcert%2F9hJUZz&urlhash=D0OT (from GitHub issue 252) unchanged, the destination has no scheme
https://www.linkedin.com.evil.example/redir/redirect?url=https%3A%2F%2Fexample.com%2F unchanged, not a LinkedIn host
https://www.linkedin.com/redir/redirect?url=javascript%3Aalert(1)&urlhash=x unchanged
https://www.linkedin.com/redir/redirect?urlhash=D0OT unchanged, no destination

trk stays in the first result: after the redirect it belongs to the ow.ly url, and trk is too common a name for a global rule.

Testing

Tested offline in URL Check 3.5 (Android 15 emulator), which applies this catalog with Java regexes: the current catalog plus this change gave the expected result in all 8 LinkedIn test cases (3 unwrapped, 5 unchanged; the table shows 7 of them, the 8th is a second destination without scheme), and in 50 of 50 cases together with the two companion changes (globalRules, instagram/vk). Without the change all 8 stay unchanged apart from trk removal. The pattern gives the same results in JavaScriptCore, with and without the i flag. Inputs up to 160 KB (long hosts, many parameters, long tokens) took at most 10 ms per pattern in Java and 8 ms in JavaScriptCore, with no stack overflow at a 512 KB thread stack.

Companion MRs: !89 (instagram and vk.com redirections), !90 (globalRules). The three change different fields and merge without conflict in any order.

AI-Assisted-By: Claude Opus 5.5 (xhigh)

Edited by Milan

Merge request reports

Loading
Loading