Java: Taint flows backwards for array element
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
### Version
```
CodeQL extension version: 1.12.0
CodeQL CLI version: 2.15.5
Platform: win32 x64
```
Dependencies:
- `codeql/java-all: 0.8.5`
### Description
It looks like taint tracking erroneously reports that taint flows "backwards" from an array element assignment.
For example:
```java
void arrayAssign() {
String[] s = {"a"};
s[0] = source(sink(s[0]));
}
```
Here it erroneously reports that there is taint flow from `source` to `sink`, even though `sink` is actually executed _before_ `source`, so there should not be any flow between them.
Here is also real world code where this occurs: [apache/logging-log4j2](https://github.com/apache/logging-log4j2/blob/e7b107fe44fd18ca759b83f0cbdb37bc889233f4/log4j-1.2-api/src/test/java/org/apache/log4j/layout/Log4j1SyslogLayoutTest.java#L63-L64)
(my query considered the output of `String.format` as source, and an argument to `String.format` as sink)
### Steps to reproduce
Java code:
```java
class FlowTest {
T source(T o) {
return o;
}
T sink(T o) {
return o;
}
void varAssign() {
String s = "a";
s = source(sink(s));
}
void arrayAssign() {
String[] s = {"a"};
// Erroneously reports flow from `source` to `sink`
s[0] = source(sink(s[0]));
}
}
```
CodeQL query:
```codeql
/**
* @kind problem
*/
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
class Source extends DataFlow::Node {
Source() {
exists(Method m |
m = this.asExpr().(MethodCall).getMethod().getSourceDeclaration() and
m.hasName("source") and
m.fromSource()
)
}
}
class Sink extends DataFlow::Node {
Sink() {
exists(MethodCall call, Method m |
call.getAnArgument() = this.asExpr() and
m = call.getMethod().getSourceDeclaration() and
m.hasName("sink") and
m.fromSource()
)
}
}
from Source source, Sink sink, string type
where
type = "dataflow" and DataFlow::localFlow(source, sink)
or
type = "taint" and TaintTracking::localTaint(source, sink)
select sink, type + " from $@", source, "source"
```
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Reproduisez le problème avec le code Java FlowTest et la requête CodeQL fournis, en comparant DataFlow::localFlow à TaintTracking::localTaint. Commencez par suivre les points d’entrée des bibliothèques importées semmle.code.java.dataflow.DataFlow et TaintTracking, puis vérifiez la gestion des affectations de tableaux. Le travail est terminé lorsque le taint ne s’écoule plus de la source vers le sink précédent, tandis que l’exemple d’affectation de variable reste correct.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- java
- Domaine
- security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100