Files
codeql/javascript/ql/src/NodeJS/InvalidExport.ql
2022-03-16 22:56:52 +01:00

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."