{"record":{"id":"7b20ee3df58c6c82","repo":"oxc-project/oxc","slug":"using-target-blank-without-rel-noreferrer-wh","errorCode":null,"errorMessage":"Using target=`_blank` without rel=`noreferrer` (which implies rel=`noopener`) is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations","messagePattern":"Using target=`_blank` without rel=`noreferrer` \\(which implies rel=`noopener`\\) is a security risk in older browsers: see https://mathiasbynens\\.github\\.io/rel-noopener/#recommendations","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs","lineNumber":25,"sourceCode":"        StringLiteral, match_expression,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse oxc_str::CompactStr;\nuse schemars::JsonSchema;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    AstNode,\n    context::{ContextHost, LintContext},\n    rule::{DefaultRuleConfig, Rule},\n    utils::is_same_expression,\n};\n\nfn target_blank_without_noreferrer(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Using target=`_blank` without rel=`noreferrer` (which implies rel=`noopener`) is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations\")\n        .with_help(\"add rel=`noreferrer` to the element\")\n        .with_label(span)\n}\n\nfn target_blank_without_noopener(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Using target=`_blank` without rel=`noreferrer` or rel=`noopener` (the former implies the latter and is preferred due to wider support) is a security risk: see https://mathiasbynens.github.io/rel-noopener/#recommendations\")\n        .with_help(\"add rel=`noreferrer` or rel=`noopener` to the element\")\n        .with_label(span)\n}\n\nfn explicit_props_in_spread_attributes(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"all spread attributes are treated as if they contain an unsafe combination of props, unless specifically overridden by props after the last spread attribute prop.\")\n        .with_help(\"add rel=`noreferrer` to the element\")\n        .with_label(span)\n}\n\n#[derive(Debug, Clone, JsonSchema, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs#L7-L43","documentation":"Diagnostic from oxlint's react/jsx-no-target-blank rule, emitted when `allowReferrers` is false (the default). An `<a target=\"_blank\">` with a non-relative href and no rel=\"noreferrer\" lets the opened page access `window.opener` in older browsers (reverse tabnabbing) and leaks the referrer URL. The rule demands rel=\"noreferrer\", which implies rel=\"noopener\".","triggerScenarios":"A link element (`<a>` or a component registered via linkComponents settings) carrying `target=\"_blank\"` whose href/action is external or dynamic (`enforceDynamicLinks` defaults to \"always\", so `href={dynamicLink}` counts) and whose rel attribute does not include noreferrer. Relative hrefs (`/path`, `host-relative`) are treated as safe; the diagnostic spans the target attribute.","commonSituations":"Marketing/external links opening in new tabs; user-generated hrefs; forgetting rel after adding target=\"_blank\"; custom Link components not registered in `settings.react.linkComponents` so the check is skipped (config gap, opposite problem).","solutions":["Add `rel=\"noreferrer\"` to the element (`rel=\"noopener noreferrer\"` also passes).","If you must preserve the referrer, set the rule option `\"allowReferrers\": true` — then rel=\"noopener\" alone satisfies the rule.","Register custom link components (`settings.react.linkComponents`) so they are checked too.","If the href is always same-site/relative you may set `\"enforceDynamicLinks\": \"never\"`."],"exampleFix":"// before\n<a href={userUrl} target=\"_blank\">Profile</a>\n\n// after\n<a href={userUrl} target=\"_blank\" rel=\"noreferrer\">Profile</a>","handlingStrategy":"validation","validationCode":"oxlint --react-plugin src/ # jsx-no-target-blank is on in the react plugin\n\n# audit existing links in one pass\nrg -n --no-ignore 'target=[\"'\"']_blank' src/","typeGuard":"// helper that makes the safe form the easy form\ntype SafeLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & { external?: boolean };\nconst SafeLink = ({ external, ...rest }: SafeLinkProps) =>\n  <a {...rest} rel={external ? 'noreferrer' : rest.rel} />;","tryCatchPattern":null,"preventionTips":["Add rel=\"noreferrer\" in the same commit that adds target=\"_blank\".","Register custom Link components in settings.react.linkComponents so they get checked.","Consider a shared <ExternalLink> wrapper that always sets target+rel correctly."],"tags":["react","security","tabnabbing","noopener","oxlint","lint"],"backgroundTag":"target-blank-tabnabbing","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}