From d3b5d717c170b3afb5596effd845f8ca34327978 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Wed, 30 Oct 2019 10:03:58 +0100 Subject: [PATCH] [New] `jsx-no-target-blank`: add `allowReferrer` option --- docs/rules/jsx-no-target-blank.md | 3 ++- lib/rules/jsx-no-target-blank.js | 14 +++++++++++--- tests/lib/rules/jsx-no-target-blank.js | 4 ++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/rules/jsx-no-target-blank.md b/docs/rules/jsx-no-target-blank.md index 41211eb1c0..0abc0719ea 100644 --- a/docs/rules/jsx-no-target-blank.md +++ b/docs/rules/jsx-no-target-blank.md @@ -14,10 +14,11 @@ This rule aims to prevent user generated links from creating security vulnerabil ## Rule Options ```json ... -"react/jsx-no-target-blank": [, { "enforceDynamicLinks": }] +"react/jsx-no-target-blank": [, { "allowReferrer": , "enforceDynamicLinks": }] ... ``` +* allow-referrer: optional boolean. If `true` does not require `noreferrer`. Defaults to `false`. * enabled: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0. * enforce: optional string, 'always' or 'never' diff --git a/lib/rules/jsx-no-target-blank.js b/lib/rules/jsx-no-target-blank.js index af825f56d2..51df0ece1a 100644 --- a/lib/rules/jsx-no-target-blank.js +++ b/lib/rules/jsx-no-target-blank.js @@ -40,11 +40,11 @@ function hasDynamicLink(element, linkAttribute) { attr.value.type === 'JSXExpressionContainer'); } -function hasSecureRel(element) { +function hasSecureRel(element, allowReferrer) { return element.attributes.find((attr) => { if (attr.type === 'JSXAttribute' && attr.name.name === 'rel') { const tags = attr.value && attr.value.type === 'Literal' && attr.value.value.toLowerCase().split(' '); - return tags && (tags.indexOf('noopener') >= 0 && tags.indexOf('noreferrer') >= 0); + return tags && (tags.indexOf('noopener') >= 0 && (allowReferrer || tags.indexOf('noreferrer') >= 0)); } return false; }); @@ -61,6 +61,9 @@ module.exports = { schema: [{ type: 'object', properties: { + allowReferrer: { + type: 'boolean' + }, enforceDynamicLinks: { enum: ['always', 'never'] } @@ -71,12 +74,17 @@ module.exports = { create(context) { const configuration = context.options[0] || {}; + const allowReferrer = configuration.allowReferrer || false; const enforceDynamicLinks = configuration.enforceDynamicLinks || 'always'; const components = linkComponentsUtil.getLinkComponents(context); return { JSXAttribute(node) { - if (!components.has(node.parent.name.name) || !isTargetBlank(node) || hasSecureRel(node.parent)) { + if ( + !components.has(node.parent.name.name) || + !isTargetBlank(node) || + hasSecureRel(node.parent, allowReferrer) + ) { return; } diff --git a/tests/lib/rules/jsx-no-target-blank.js b/tests/lib/rules/jsx-no-target-blank.js index b0d97df283..aefd526cfc 100644 --- a/tests/lib/rules/jsx-no-target-blank.js +++ b/tests/lib/rules/jsx-no-target-blank.js @@ -68,6 +68,10 @@ ruleTester.run('jsx-no-target-blank', rule, { code: '', options: [{enforceDynamicLinks: 'never'}], settings: {linkComponents: {name: 'Link', linkAttribute: 'to'}} + }, + { + code: '', + options: [{allowReferrer: true}] } ], invalid: [{