JS: Make getInstance() propagate to subclasses

This commit is contained in:
Asger F 2024-04-05 15:01:26 +02:00
Родитель a8dac17aec
Коммит cd84fa4bee
4 изменённых файлов: 39 добавлений и 0 удалений

Просмотреть файл

@ -891,6 +891,17 @@ module API {
(propDesc = Promises::errorProp() or propDesc = "") (propDesc = Promises::errorProp() or propDesc = "")
} }
pragma[nomagic]
private DataFlow::ClassNode getALocalSubclass(DataFlow::SourceNode node) {
result.getASuperClassNode().getALocalSource() = node
}
bindingset[node]
pragma[inline_late]
private DataFlow::ClassNode getALocalSubclassFwd(DataFlow::SourceNode node) {
result = getALocalSubclass(node)
}
/** /**
* Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled
* `lbl` in the API graph. * `lbl` in the API graph.
@ -927,6 +938,15 @@ module API {
or or
lbl = Label::forwardingFunction() and lbl = Label::forwardingFunction() and
DataFlow::functionForwardingStep(pred.getALocalUse(), ref) DataFlow::functionForwardingStep(pred.getALocalUse(), ref)
or
exists(DataFlow::ClassNode cls |
lbl = Label::instance() and
cls = getALocalSubclassFwd(pred).getADirectSubClass*()
|
ref = cls.getAReceiverNode()
or
ref = cls.getAClassReference().getAnInstantiation()
)
) )
or or
exists(DataFlow::Node def, DataFlow::FunctionNode fn | exists(DataFlow::Node def, DataFlow::FunctionNode fn |

Просмотреть файл

@ -74,6 +74,10 @@ taintFlow
| test.js:249:28:249:35 | source() | test.js:249:28:249:35 | source() | | test.js:249:28:249:35 | source() | test.js:249:28:249:35 | source() |
| test.js:252:15:252:22 | source() | test.js:252:15:252:22 | source() | | test.js:252:15:252:22 | source() | test.js:252:15:252:22 | source() |
| test.js:254:32:254:39 | source() | test.js:254:32:254:39 | source() | | test.js:254:32:254:39 | source() | test.js:254:32:254:39 | source() |
| test.js:262:10:262:31 | this.ba ... ource() | test.js:262:10:262:31 | this.ba ... ource() |
| test.js:265:6:265:39 | new MyS ... ource() | test.js:265:6:265:39 | new MyS ... ource() |
| test.js:269:10:269:31 | this.ba ... ource() | test.js:269:10:269:31 | this.ba ... ource() |
| test.js:272:6:272:40 | new MyS ... ource() | test.js:272:6:272:40 | new MyS ... ource() |
isSink isSink
| test.js:54:18:54:25 | source() | test-sink | | test.js:54:18:54:25 | source() | test-sink |
| test.js:55:22:55:29 | source() | test-sink | | test.js:55:22:55:29 | source() | test-sink |

Просмотреть файл

@ -256,3 +256,17 @@ function fuzzy() {
fuzzyCall(source()); // OK - does not come from 'testlib' fuzzyCall(source()); // OK - does not come from 'testlib'
require('blah').fuzzyCall(source()); // OK - does not come from 'testlib' require('blah').fuzzyCall(source()); // OK - does not come from 'testlib'
} }
class MySubclass extends testlib.BaseClass {
foo() {
sink(this.baseclassSource()); // NOT OK
}
}
sink(new MySubclass().baseclassSource()); // NOT OK
class MySubclass2 extends MySubclass {
foo2() {
sink(this.baseclassSource()); // NOT OK
}
}
sink(new MySubclass2().baseclassSource()); // NOT OK

Просмотреть файл

@ -80,6 +80,7 @@ class Sources extends ModelInput::SourceModelCsv {
"testlib;Member[ParamDecoratorSource].DecoratedParameter;test-source", "testlib;Member[ParamDecoratorSource].DecoratedParameter;test-source",
"testlib;Member[MethodDecorator].DecoratedMember.Parameter[0];test-source", "testlib;Member[MethodDecorator].DecoratedMember.Parameter[0];test-source",
"testlib;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.Parameter[0];test-source", "testlib;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.Parameter[0];test-source",
"testlib;Member[BaseClass].Instance.Member[baseclassSource].ReturnValue;test-source",
] ]
} }
} }