External links use noopener noreferrer
Issue No: 50
Category: Crawl Behaviour
Issue type: Suggestion
Priority: STANDARD
Description
This audit verifies that external links opening in a new tab include rel="noopener noreferrer". The check reduces tabnabbing risk and prevents unintended referrer leakage.
How do we capture it
- Fetch each in-scope page URL using an HTTP GET request and read the raw HTML response body.
- Parse anchor tags (
<a>) from raw HTML text and extract these attributes when present:href,target, andrel. - Resolve
hrefvalues to absolute URLs using RFC 3986 URL resolution rules. - Classify links as external when normalized link host is different from the crawled page host and outside allowed internal domain scope.
- Restrict evaluation to links with
target="_blank"because the noopener requirement is relevant for new-tab/window behavior. - Tokenize the
relattribute by ASCII whitespace, lowercase each token, and build a set of rel directives. - Mark a link as non-compliant when either token is missing:
- Missing
noopener. - Missing
noreferrer.
- Missing
- Record per-link diagnostics including source page URL, destination URL, and missing tokens.
- Aggregate page-level counts for total evaluated external
_blanklinks, compliant links, and non-compliant links. - Handle edge cases deterministically:
- Empty or malformed
hrefvalues are recorded with parse status and excluded from compliance denominator. - Non-HTTP(S) schemes (
mailto:,tel:,javascript:) are excluded from this check.
- Empty or malformed
- Constraint: this crawler does not execute JavaScript and does not render DOM state, so anchors inserted only at runtime are out of scope and must not be approximated via heuristics.
What to store
| Field | Type | Comment |
|---|---|---|
page_url TEXT | TEXT | Source page URL where external links are evaluated. |
external_blank_link_count INTEGER | INTEGER | Number of external links on the page with target="_blank" that were eligible for evaluation. |
non_compliant_link_count INTEGER | INTEGER | Count of eligible links missing noopener or noreferrer. |
has_noopener_noreferrer_violation BOOLEAN | BOOLEAN | True when at least one eligible link is non-compliant. |
violations JSONB | JSONB | Array of per-link diagnostics including destination URL and missing rel tokens. |
ignored_link_count INTEGER | INTEGER | Count of extracted links excluded due to malformed URLs or unsupported schemes. |
checked_at TIMESTAMPTZ | TIMESTAMPTZ | Timestamp when this audit evaluation was completed. |
Condition for trigger
A trigger is raised when any external link that opens in a new tab does not include both required rel tokens.
-
Trigger Rule 1: Missing noopener or noreferrer
- Target Field:
has_noopener_noreferrer_violation - Evaluation Logic:
has_noopener_noreferrer_violation = TRUE - Severity: SUGGESTION
- Diagnostic Message: "One or more external links using target=_blank are missing rel=noopener noreferrer. Add both tokens to improve security and privacy."
- Target Field:
-
Trigger Rule 2: Non-compliant Link Count Above Zero
- Target Field:
non_compliant_link_count - Evaluation Logic:
non_compliant_link_count > 0 - Severity: SUGGESTION
- Diagnostic Message: "External new-tab links were found without full noopener noreferrer protection. Update rel attributes on those links."
- Target Field:
Sources
- WHATWG HTML Standard - Link types
noopenerandnoreferrer: https://html.spec.whatwg.org/multipage/links.html#linkTypes - MDN -
rel="noopener": https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/noopener - MDN -
rel="noreferrer": https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/noreferrer - OWASP - Reverse Tabnabbing: https://owasp.org/www-community/attacks/Reverse_Tabnabbing
Long description
When an external page is opened with target="_blank", missing noopener can allow the destination page to access window.opener and manipulate the origin tab in some environments. Missing noreferrer may also send referrer metadata where privacy policies require suppression. Enforcing both tokens provides a conservative, cross-browser-safe baseline.
Common failure scenarios checked by the crawler:
- Links with
target="_blank"and norelattribute. - Links with partial rel values such as only
noopeneror onlynoreferrer. - Template fragments that add
_blankbroadly but omit security rel tokens. - Mixed-case rel tokens that are not normalized during manual checks.
- Third-party content blocks containing external links without compliant rel directives.
Because this is captured from static HTML attributes in server responses, it is fully compatible with script-based crawling and does not require browser rendering.
How to Fix
For every external link that opens in a new tab or window, set rel to include both noopener and noreferrer. Apply the rule consistently in shared templates/components, then re-crawl to confirm zero non-compliant links remain.