Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rel="noopener noreferrer" wherever target="_blank" is used #7680

Merged
merged 13 commits into from
Sep 1, 2016

Conversation

bluefuton
Copy link
Contributor

@bluefuton bluefuton commented Aug 25, 2016

To address the target="_blank" issue outlined here:

https://dev.to/ben/the-targetblank-vulnerability-by-example

...this PR adds rel="noopener noreferrer" to every external link using target="_blank" in the Calypso codebase.

We've also added an eslint rule (Automattic/eslint-config-wpcalypso#2) to flag any links using target="_blank" without the corresponding rel attribute.

cc @aduth

Test live: https://calypso.live/?branch=fix/target-blank-vuln

@bluefuton bluefuton added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. Security labels Aug 25, 2016
@bluefuton bluefuton self-assigned this Aug 25, 2016
@@ -29,7 +29,7 @@ const ReaderAuthorLink = ( { author, post, siteUrl, children } ) => {
}

return (
<ExternalLink className="reader-author-link" href={ linkUrl } target="_blank" onClick={ recordAuthorClick }>
<ExternalLink className="reader-author-link" href={ linkUrl } target="_blank" rel="noopener noreferrer" onClick={ recordAuthorClick }>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of <ExternalLink /> is such that rel will be overridden and remove the noopener noreferrer:

https://github.com/Automattic/wp-calypso/blob/dcf8306/client/components/external-link/index.jsx#L41

To that end, if the purpose of external link is for linking externally, should we just add these values to the component itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought, but I'm not sure our new lint rule (Automattic/eslint-config-wpcalypso#2) is smart enough to figure that out :) Might mean peppering the code with eslint exception comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I suspected, the eslint rule is a bit of a blunt instrument. If we specify target="_blank" on an ExternalLink, the rule complains even though we are setting rel in the underlying component.

I've worked around the handful of cases with

eslint-disable react/jsx-no-target-blank

for the moment. Another way around this would be to introduce a new prop on ExternalLink (openInNewWindow or similar) that applies target inside the component.

@aduth aduth added [Status] Needs Author Reply and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Aug 25, 2016
@bluefuton
Copy link
Contributor Author

bluefuton commented Aug 26, 2016

Todo:

  • apply rel in EmptyContent (components/empty-content) when target is specified
  • apply rel in PurchaseDetail when target is specified
  • specify rel in ExternalLink when target is specified
  • clean up EmptyContent and ExternalLink with a now-redundant rel
  • run linter and check warnings/exceptions

@bluefuton bluefuton force-pushed the fix/target-blank-vuln branch 2 times, most recently from bad0bf4 to 3a740b3 Compare August 30, 2016 11:11
@bluefuton bluefuton added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] Needs Author Reply labels Aug 30, 2016
@bluefuton bluefuton force-pushed the fix/target-blank-vuln branch from 519772f to 08aedfd Compare August 30, 2016 20:06
@bluefuton
Copy link
Contributor Author

Rebased and ready for 👀

borderless: PropTypes.bool
borderless: PropTypes.bool,
target: PropTypes.string,
rel: PropTypes.string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be argued that these be included in the else block in render to push into omitProps for the button case, since they're not valid attributes for a button. This assumes someone renders as a button with rel and target but not href, which is unlikely, be "possible".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Added in b88562b.

@bluefuton bluefuton added [Status] Needs Author Reply and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Aug 31, 2016
@bluefuton bluefuton force-pushed the fix/target-blank-vuln branch from 8848da9 to 1f9fca3 Compare August 31, 2016 10:20
@bluefuton bluefuton added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] Needs Author Reply labels Aug 31, 2016
@bluefuton bluefuton force-pushed the fix/target-blank-vuln branch from b51c6e2 to 05522ce Compare September 1, 2016 11:34
@bluefuton
Copy link
Contributor Author

Does this look good to go @aduth? Keeping on top of the conflicts is getting tricky as it touches so many files.

I'll remove the eslint-disable-line statements later if your change to the rule gets merged (jsx-eslint/eslint-plugin-react#793).

@@ -41,6 +42,10 @@ export default React.createClass( {
rel: 'external'
} );

if ( props.target ) {
props.rel = props.rel.concat( ' noopener noreferrer' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL String#concat. Then again, this could have just been props.rel += ' noopener noreferrer';

No need to change anything.

@aduth
Copy link
Contributor

aduth commented Sep 1, 2016

LGTM 👍

You may want to rebase once more locally and run npm run lint just to make sure that no need target props have crept in since the last rebase.

@aduth aduth added [Status] Ready to Merge and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Sep 1, 2016
@bluefuton bluefuton force-pushed the fix/target-blank-vuln branch from 05522ce to c7c5163 Compare September 1, 2016 13:42
@bluefuton
Copy link
Contributor Author

Thanks @aduth! I've just given it a final rebase and lint. 🚢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants