-
-
Notifications
You must be signed in to change notification settings - Fork 60
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
🔒 fix: CVE-2023-26115 #33
🔒 fix: CVE-2023-26115 #33
Conversation
@@ -36,7 +42,7 @@ module.exports = function(str, options) { | |||
}).join(newline); | |||
|
|||
if (options.trim === true) { | |||
result = result.replace(/[ \t]*$/gm, ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess /\s+$/gm
works faster
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, let me check on that.
But ideally, I would like to not use regex for the operation that can be easily handled by native trimEnd
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe or native better regex can be faster. need to bench to check that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @aashutoshrathi, sorry for the long delay, and thanks for the PR. I'll try to get this merged in ASAP.
I guess
/\s+$/gm
works faster
Yes, let's use this pattern without the m
flag. Using +
will also be a bit safer since it won't allow that pattern to match an empty string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/[ \t]+$/g
is slightly better than /\s+$/g
it would seem. Unfortunately both regexes are suspectable to redos, as opposed to trimEnd()
;
$ time node -e 'payloadstr=""; for ( i=0; i < 100000; i++ ) payloadstr+="\t"; payloadstr+="a"; payloadstr.replace(/[ \t]+$/gm,"");'
real 0m21.084s
$ time node -e 'payloadstr=""; for ( i=0; i < 100000; i++ ) payloadstr+="\t"; payloadstr+="a"; payloadstr.replace(/\s+$/g,"");'
real 0m8.587s
$ time node -e 'payloadstr=""; for ( i=0; i < 100000; i++ ) payloadstr+="\t"; payloadstr+="a"; payloadstr.replace(/[ \t]+$/g,"");'
real 0m6.169s
$ time node -e 'payloadstr=""; for ( i=0; i < 100000; i++ ) payloadstr+="\t"; payloadstr+="a"; payloadstr.trimEnd();'
real 0m0.082s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonschlinkert Any update when this PR will be merged ?
index.js
Outdated
* Released under the MIT License. | ||
*/ | ||
|
||
function trimTabAndSpaces(str) { | ||
const lines = str.split('\n'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may be using method chaining eliminates the need to create an intermediate variable ??
return str.split('\n').map(line => line.trimEnd()).join('\n');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup! can be done. I once just need verification the approach or whether it is important or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utilizing native String.prototype.trimEnd()
would require the node-engine to be at least on version 10.0.0.
Ref: String.prototype.trimEnd() - JavaScript | MDN
This should probably considered a breaking-change which requires new major version release.
Hence I would recommend to utilize custom implementation for this patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh! I can write trimEnd
myself if that's the case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the reason mentioned by @mscheid-sf, for now let's merge in the regex I suggested in my other comment. After that I'd be happy to take another PR that replaces the regex with .trimEnd()
(Using .trimEnd
would indeed qualify as a breaking change according to semver, and also it's generally a good practice to minimize potential for regressions when releasing patches).
Do you have an update when this PR will be merged? Thanks! |
Any update? |
I suggest going with |
@jonschlinkert is this repo active? |
Any update on this @jonschlinkert ? We're blocked by this issue not being fixed. |
Any update on this @jonschlinkert ? Is this repo active? |
in meantime someone brave enough can publish a version of the package that can be a replacement in
|
I think we can try, what do you think @sergeyt ? |
Sure, why not |
Okay here's a temporary package: https://www.npmjs.com/package/@aashutoshrathi/word-wrap "resolutions": {
"word-wrap": "npm:@aashutoshrathi/word-wrap@1.2.4"
}, |
and if you don't use yarn and using npm itself use 'overrides' |
Please use the newer version the older one causes some issues "resolutions": {
"word-wrap": "npm:@aashutoshrathi/word-wrap@1.2.5"
}, |
If we use npm not yarn, how would we use overrides to change a package with another ? i do not find it clear from the official docs: https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides |
for example, using something like this in your "overrides": {
"word-wrap" : "npm:@aashutoshrathi/word-wrap@1.2.5"
}, |
I will try with this one, I have a question. Becouse that dependency is involved into eslint and jest dependecies, I have to specify from the example parent dependency. 'jest/jest-config.../word-wrap' or just specify as you say ? |
You can use the same, without specifying the path. |
Please have this merged to the main branch |
Thanks @aashutoshrathi , But still, this needs to be merged..Can anyone from us reach out to @jonschlinkert through LinkedIn/Twitter please :-P |
@aashutoshrathi , The same is still reappearing for the following path, |
Hey! if you use resolution override in the main |
Hey @aashutoshrathi, In case do another |
Hi all, why is this fix not merged yet? |
@xx745, I don't think @jonschlinkert has any desire to continue managing this repo. I've reached out to him several times on twitter, where he's active, but no response. I would love to be wrong though! I would be great for him to come in and merge this or for there to be a way for somebody else to be an admin here, then he doesn't have to keep up with it. |
@aashutoshrathi, since this PR has been merged and this Issue was resolved with PR #41, I'm backing to the original project now. Thank you for bringing a solution until this problem was actually solved here, I believe your fork has helped many people and keep helping (the numbers themselves prove this) 🚀 |
No problemo anytime for OSS folks! 🖖🏻 |
@doowb and @nicholas-quirk-mass-gov, just asking for clarity. @nicholas-quirk-mass-gov, are you saying that PR #41 (1.2.4) didn't fix the vulnerability? |
Yes! This PR won't fix it. until we leave Regex completely. |
@bgswilde, understanding the storyline 🧙🏻 This PR changes only the regex rule: - result = result.replace(/[ \t]*$/gm, '');
+ result = result.replace(/\s+$/g, ''); The @aashutoshrathi/word-wrap fork uses the native The PR #41 recreates the Both @aashutoshrathi/word-wrap fork and PR #41 fix that vulnerability, this PR (#33) don't. For a better understand, please see the #41 changes. |
# [1.16.0](v1.15.0...v1.16.0) (2023-12-04) ### Upgrade * Bump word-wrap from 1.2.3 to 1.2.5 (#516) ([9c9251b](9c9251b)), closes [#516](#516) [jonschlinkert/word-wrap#24](jonschlinkert/word-wrap#24) [jonschlinkert/word-wrap#41](jonschlinkert/word-wrap#41) [jonschlinkert/word-wrap#33](jonschlinkert/word-wrap#33) [jonschlinkert/word-wrap#42](jonschlinkert/word-wrap#42) [jonschlinkert/word-wrap#24](jonschlinkert/word-wrap#24) [jonschlinkert/word-wrap#41](jonschlinkert/word-wrap#41) [jonschlinkert/word-wrap#33](jonschlinkert/word-wrap#33) [#42](#42) [#41](#41)
Fixes #32
Issue with existing approach
CVE-2023-26115
TLDR;
ReDoS
, the issue is due to Regex matching algo.Approach used here
Removed the use of
String.prototype.replace(Regex)
, instead wrote function to trim tabs and space from the end of line.Benchmarks
Code snippet used
Performance Benchmarks