mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
49 lines
1.6 KiB
Plaintext
49 lines
1.6 KiB
Plaintext
/**
|
|
* @name Assignment to exports variable
|
|
* @description Assigning to the special 'exports' variable only overwrites its value and does not export
|
|
* anything. Such an assignment is hence most likely unintentional.
|
|
* @kind problem
|
|
* @problem.severity warning
|
|
* @id js/node/assignment-to-exports-variable
|
|
* @tags maintainability
|
|
* frameworks/node.js
|
|
* external/cwe/cwe-563
|
|
* @precision very-high
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Holds if `assign` assigns the value of `nd` to `exportsVar`, which is an `exports` variable
|
|
*/
|
|
predicate exportsAssign(Assignment assign, Variable exportsVar, DataFlow::Node nd) {
|
|
exists(NodeModule m |
|
|
exportsVar = m.getScope().getVariable("exports") and
|
|
assign.getLhs() = exportsVar.getAnAccess() and
|
|
nd = assign.getRhs().flow()
|
|
)
|
|
or
|
|
exportsAssign(assign, exportsVar, nd.getASuccessor())
|
|
}
|
|
|
|
/**
|
|
* Holds if `pw` assigns the value of `nd` to `module.exports`.
|
|
*/
|
|
predicate moduleExportsAssign(DataFlow::PropWrite pw, DataFlow::Node nd) {
|
|
pw.getBase().asExpr() instanceof ModuleAccess and
|
|
pw.getPropertyName() = "exports" and
|
|
nd = pw.getRhs()
|
|
or
|
|
moduleExportsAssign(pw, nd.getASuccessor())
|
|
}
|
|
|
|
from Assignment assgn, Variable exportsVar, DataFlow::Node exportsVal
|
|
where
|
|
exportsAssign(assgn, exportsVar, exportsVal) and
|
|
not exists(exportsVal.getAPredecessor()) and
|
|
// this is OK if `exportsVal` flows into `module.exports`
|
|
not moduleExportsAssign(_, exportsVal) and
|
|
// export assignments do work in closure modules
|
|
not assgn.getTopLevel() instanceof Closure::ClosureModule
|
|
select assgn, "Assigning to 'exports' does not export anything."
|