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

Enhance security: code fixes and dependency upgrades #134

Merged
merged 7 commits into from
Dec 6, 2023

Conversation

MiguelAxcar
Copy link
Contributor

@MiguelAxcar MiguelAxcar commented Dec 1, 2023

This PR intends to add security enhancements listed on Security Review Summary - T335004 - 2023-09-26 (internal client ticket #922)

Changes added

  • Sanitization of post.title.rendered to avoid XSS attacks
  • Upgrade NPM dependencies
  • Resolve vulnerabilities updating dependencies through npm audit fix

Vulnerable packages

  • ajv (4.11.8) report (issue fixed on 6.12.3)
  • decode-uri-component (0.2.0) report (issue fixed on 0.2.1 - updated by dependabot to 0.2.2 on Bump decode-uri-component from 0.2.0 to 0.2.2 #127)
  • glob-parent (3.1.0) report (issue fixed on 5.1.2)
  • jsdom (11.12.0) report (issue fixed on 16.5.0)
  • json5 (1.0.1) report (upgraded to 1.0.2)
  • json5 (2.2.1) report (issue fixed on 2.2.2) (upgraded to 2.2.3)
  • loader-utils (1.4.0) report (issue fixed on 1.4.2) (upgraded to 1.4.2)
  • loader-utils (1.4.0) report (issue fixed on 1.4.2) (upgraded to 1.4.2)
  • loader-utils (1.4.0) report (issue fixed on 1.4.2) (upgraded to 1.4.2)
  • loader-utils (2.0.2) report (issue fixed on 2.0.3) (upgraded to 2.0.4)
  • loader-utils (2.0.2) report (issue fixed on 2.0.3) (upgraded to 2.0.4)
  • loader-utils (2.0.2) report (issue fixed on 2.0.3) (upgraded to 2.0.4)
  • node-forge (0.10.0) report (issue fixed on 1.0.0)
  • node-forge (0.10.0) report (issue fixed on 1.0.0)
  • node-forge (0.10.0) report (issue fixed on 1.0.0)
  • node-forge (0.10.0) report (issue fixed on 1.3.0)
  • node-forge (0.10.0) report (issue fixed on 1.3.0)
  • node-forge (0.10.0) report (issue fixed on 1.3.0)
  • node-notifier (5.4.5) report (issue fixed on 8.0.1)
  • nth-check (1.0.2) report (issue fixed on 2.0.1)
  • request (2.88.2) report (issue fixed on 2.88.2)
  • semver (5.7.1) report (upgraded to 5.7.2)
  • semver (6.3.0) report (upgraded to 6.3.1)
  • semver (7.3.8) report (issue fixed on 7.5.2) (upgraded to 7.5.4)
  • shelljs (0.7.8) report (issue fixed on 0.8.5)
  • shelljs (0.7.8) report (issue fixed on 0.8.5)
  • tough-cookie (2.5.0) report (issue fixed on 4.1.3 - removed by dependabot on Bump tough-cookie, jest and jest-cli #135)
  • word-wrap (1.2.3) report (issue fixed on 1.2.4) (upgraded to 1.2.5)

SAST Audit findings

  • js/post-select/components/post-list-item.js
    • Line 30: Use of dangerouslySetInnerHTML with post.title.rendered - Potential XSS risk (Details)
  • js/post-select/components/selection-item.js
    • Line 27: Use of dangerouslySetInnerHTML with post.title.rendered - Potential XSS risk (Details)

Copy link
Contributor

@kadamwhite kadamwhite left a comment

Choose a reason for hiding this comment

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

+1 on the updates, but I'd recommend importing sanitize specifically, because it sometimes makes it easier for security sniffers to detect that sanitization is in use.

However — where is DOMPurify coming from? It's not a dependency of this plugin and not listed in package.json. I suspect it's being provided by another plugin, and we're getting lucky that the global is present -- but we should include it in our build, for safety. It won't increase bundle size much and it'll make this plugin independent from others.

@@ -14,7 +15,7 @@ const PostListItem = ( { post, author, thumbnail, postTypeObject, isSelected, on
<label htmlFor={ `select-post-${post.id}` }>
{ thumbnail
? <img
alt={ post.title.rendered }
alt={ DOMPurify.sanitize( post.title.rendered ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, better to import { sanitize } from DOMPurify; and then call these as alt={ sanitize( post.title.rendered ) }

(Although, I'm confused why we need to do this -- React should already be escaping the alt attribute. The main security issue with React is when you set __dangerouslySetInnerHtml. Are we certain we need to double-sanitize alt strings?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kadamwhite thanks for the review.

I applied the solution you suggested on both, but could not yet test it, as I'm setting up a local environment to use the plugin.

I got this solution of sanitizing the variable and using DOMPurify from the security audit:
https://semgrep.dev/r?q=typescript.react.security.audit.react-dangerouslysetinnerhtml.react-dangerouslysetinnerhtml

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have linting actions in place, and I noticed that eslint is complaining about sanitize:

sanitize not found in 'dompurify' eslint (import/named)

I'm looking into that. Thanks.

Copy link
Contributor

@kadamwhite kadamwhite left a comment

Choose a reason for hiding this comment

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

@MiguelAxcar I think that the issue you're seeing is related to my comment,

where is DOMPurify coming from? It's not a dependency of this plugin and not listed in package.json

We can't use this module in the bundled code unless we can guarantee it exists. I was suggesting we add dompurify as a package dependency, which should allow the named imports sniff to detect it, and also fix a build error:

Build errors that turned out not to be caused by a missing dependency
Child editor:
    Time: 7313ms
     3 assets
    
    WARNING in ./js/post-select/containers/term-select-form-field.js
    Module Warning (from ./node_modules/eslint-loader/dist/cjs.js):
    Cannot read property 'range' of null
    Occurred while linting /Users/kadam/hm/gh/hm-gutenberg-tools/js/post-select/containers/term-select-form-field.js:3
    
    ERROR in ./js/post-select/components/post-list-item.js
    Module Error (from ./node_modules/eslint-loader/dist/cjs.js):
    
    /Users/kadam/hm/gh/hm-gutenberg-tools/js/post-select/components/post-list-item.js
      2:10  error  sanitize not found in 'dompurify'  import/named
    
    ✖ 1 problem (1 error, 0 warnings)
    
    
    ERROR in ./js/post-select/components/selection-item.js
    Module Error (from ./node_modules/eslint-loader/dist/cjs.js):
    
    /Users/kadam/hm/gh/hm-gutenberg-tools/js/post-select/components/selection-item.js
      2:10  error  sanitize not found in 'dompurify'  import/named
    
    ✖ 1 problem (1 error, 0 warnings)

Please add dompurify to the project using npm.

Edit: The package has been there all along, and the syntax error was the result of my suggestion to destructure sanitize. Interestingly, neither import DOMPurify from 'dompurify' nor import { sanitize } from DOMPurify are the recommended way to consume the package as a ES module, but the * as DOMPurify method doesn't work locally, and using it as the default export does.

"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"dompurify": "^3.0.6",
Copy link
Contributor

@kadamwhite kadamwhite Dec 5, 2023

Choose a reason for hiding this comment

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

I'm sorry, @MiguelAxcar , I don't know how I missed that you had already installed this 🤦 🤔

I also now understand that the errors we're seeing are because I steered you wrong: DOMPurify wants to be imported like this,

import * as DOMPurify from 'dompurify';

so then we would call it as DOMPurify.sanitize() in the way you did before. But, that doesn't actually work for me locally, probably because of the older Node environment; so, we should actually go back to what you had in the first place, import DOMPurify from 'dompurify';. 😬

Best way to get things working is probably to revert 7d95e8c and then everything should work.

Apologies for the off-target guidance!

This reverts commit 7d95e8c.
@MiguelAxcar MiguelAxcar merged commit 9e2e541 into main Dec 6, 2023
@MiguelAxcar MiguelAxcar deleted the security-enhancements branch December 6, 2023 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants