Merge pull request #19049 from Napalys/js/underscore-string

JS: Modeling of `underscore.string` package
This commit is contained in:
Napalys Klicius
2025-03-20 19:11:24 +01:00
committed by GitHub
5 changed files with 196 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added support for the `underscore.string` package.

View File

@@ -0,0 +1,35 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["'underscore.string'.Wrapper", "'underscore.string'", "ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,strip,lstrip,rstrip,camelcase].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[insert,replaceAll,join,splice,prune,pad,lpad,rpad,repeat,surround,quote,q,rjust,ljust].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[toUpperCase,toLowerCase,replace,slice,substring,substr,concat].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[tap].ReturnValue"]
- addsTo:
pack: codeql/javascript-all
extensible: summaryModel
data:
- ["'underscore.string'", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,strip,lstrip,rstrip,camelcase]", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[chop,chars,words,lines]", "Argument[0]", "ReturnValue.ArrayElement", "taint"]
- ["'underscore.string'", "Member[toSentence,toSentenceSerial]", "Argument[0].ArrayElement", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[insert,replaceAll,splice,prune,pad,lpad,rpad,repeat,rjust,ljust]", "Argument[0,2]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[splice]", "Argument[0,3]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[join]", "Argument[0..]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[surround,quote,q]", "Argument[0,1]", "ReturnValue", "taint"]
- ["'underscore.string'", "", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,value,strip,lstrip,rstrip,camelcase]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[insert,replaceAll,join,splice,prune,pad,lpad,rpad,repeat,surround,quote,q,rjust,ljust]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[insert,replaceAll,prune,pad,lpad,rpad,repeat,rjust,ljust]", "Argument[1]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[surround,quote,q]", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[splice]", "Argument[2]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[join,concat]", "Argument[0..]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[toUpperCase,toLowerCase,replace,slice,substring,substr,split]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[0].ReturnValue", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[this]", "Argument[0].Parameter[1]", "taint"]
- ["'underscore.string'", "Member[map]", "Argument[0]", "Argument[1].Parameter[0]", "taint"]
- ["'underscore.string'", "Member[map]", "Argument[1].ReturnValue", "ReturnValue", "taint"]

View File

@@ -143,3 +143,4 @@ import semmle.javascript.linters.ESLint
import semmle.javascript.linters.JSLint
import semmle.javascript.linters.Linting
import semmle.javascript.security.dataflow.RemoteFlowSources
import semmle.javascript.frameworks.UnderscoreDotString

View File

@@ -0,0 +1,26 @@
/**
* Provides classes for modeling data flow behavior of the Underscore.string library (https://www.npmjs.com/package/underscore.string).
*/
private import javascript
private import semmle.javascript.dataflow.internal.AdditionalFlowInternal
/**
* Models data flow for the Underscore.string library.
*/
private class UnderscoreDotString extends AdditionalFlowInternal {
/**
* Some of the methods in `underscore.string` have the same name as methods from `Array.prototype`.
* This prevents methods like `splice` from propagating into Argument[this].ArrayElement.
*/
override predicate clearsContent(DataFlow::Node node, DataFlow::ContentSet contents) {
exists(DataFlow::CallNode call |
call =
ModelOutput::getATypeNode(["'underscore.string'.Wrapper", "'underscore.string'"])
.getAMember()
.getACall() and
node = call.getReceiver().getPostUpdateNode() and
contents = DataFlow::ContentSet::arrayElement()
)
}
}