From aa670dfa94d76c03a67477fb637cec4d02deed44 Mon Sep 17 00:00:00 2001 From: Spring Raindrop Date: Wed, 29 Sep 2021 15:03:45 +0000 Subject: [PATCH] [Fix] `jsx-no-target-blank`: improve error messages Show different error messages depending on whether referrer is allowed; clarify about `noreferrer` only being necessary in older browsers. Closes #3044. --- lib/rules/jsx-no-target-blank.js | 9 ++++++--- tests/lib/rules/jsx-no-target-blank.js | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/rules/jsx-no-target-blank.js b/lib/rules/jsx-no-target-blank.js index d73c8e4f9d..f0b5ae6966 100644 --- a/lib/rules/jsx-no-target-blank.js +++ b/lib/rules/jsx-no-target-blank.js @@ -97,7 +97,8 @@ function hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttribu } const messages = { - noTargetBlank: 'Using target="_blank" without rel="noreferrer" is a security risk: see https://html.spec.whatwg.org/multipage/links.html#link-type-noopener' + noTargetBlankWithoutNoreferrer: 'Using target="_blank" without rel="noreferrer" is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations', + noTargetBlankWithoutNoopener: 'Using target="_blank" without rel="noopener" is a security risk: see https://mathiasbynens.github.io/rel-noopener/#recommendations' }; module.exports = { @@ -173,7 +174,8 @@ module.exports = { const hasDangerousLink = hasExternalLink(node, linkAttribute, warnOnSpreadAttributes, spreadAttributeIndex) || (enforceDynamicLinks === 'always' && hasDynamicLink(node, linkAttribute)); if (hasDangerousLink && !hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttributeIndex)) { - report(context, messages.noTargetBlank, 'noTargetBlank', { + const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer'; + report(context, messages[messageId], messageId, { node, fix(fixer) { // eslint 5 uses `node.attributes`; eslint 6+ uses `node.parent.attributes` @@ -244,7 +246,8 @@ module.exports = { hasExternalLink(node, formAttribute) || (enforceDynamicLinks === 'always' && hasDynamicLink(node, formAttribute)) ) { - report(context, messages.noTargetBlank, 'noTargetBlank', { + const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer'; + report(context, messages[messageId], messageId, { node }); } diff --git a/tests/lib/rules/jsx-no-target-blank.js b/tests/lib/rules/jsx-no-target-blank.js index ce2402325f..38302d6a7d 100644 --- a/tests/lib/rules/jsx-no-target-blank.js +++ b/tests/lib/rules/jsx-no-target-blank.js @@ -25,7 +25,7 @@ const parserOptions = { // ------------------------------------------------------------------------------ const ruleTester = new RuleTester({parserOptions}); -const defaultErrors = [{messageId: 'noTargetBlank'}]; +const defaultErrors = [{messageId: 'noTargetBlankWithoutNoreferrer'}]; ruleTester.run('jsx-no-target-blank', rule, { valid: [ @@ -249,7 +249,7 @@ ruleTester.run('jsx-no-target-blank', rule, { code: '', output: '', options: [{allowReferrer: true}], - errors: defaultErrors + errors: [{messageId: 'noTargetBlankWithoutNoopener'}] }, { code: '',