Created
April 15, 2022 01:55
-
-
Save jkschneider/a9282574cd94ab52cf7109be5135f560 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.openrewrite.java.dataflow; | |
import org.openrewrite.java.JavaIsoVisitor; | |
import org.openrewrite.java.MethodMatcher; | |
import org.openrewrite.java.tree.Expression; | |
import org.openrewrite.java.tree.J; | |
import java.util.function.Predicate; | |
import static org.apache.commons.lang.StringUtils.startsWith; | |
/** | |
* from Constructor fileReader, Call call, Expr src | |
* where | |
* fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and | |
* call.getCallee() = fileReader and | |
* DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0))) | |
* select src | |
*/ | |
public class FileReaderConstructedWithArgument<P> extends JavaIsoVisitor<P> { | |
private static final MethodMatcher NEW_FILE_READER = new MethodMatcher("java.io.FileReader <constructor>(..)"); | |
// Example of fixing at the sink | |
@Override | |
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, P p) { | |
if (NEW_FILE_READER.matches(method)) { | |
// test whether the input to this FileReader contained "http" | |
if (dataflow().anyLocalFlow((J.Literal src) -> startsWith(src.getValueSource(), "http://"), | |
method.getArguments().get(0))) { | |
// modify the method invocation, maybe to further sanitize the input | |
} | |
} | |
return super.visitMethodInvocation(method, p); | |
} | |
// Example of fixing at the source | |
@Override | |
public J.Literal visitLiteral(J.Literal literal, P p) { | |
// test whether this literal winds up getting used to construct a FileReader | |
if (startsWith(literal.getValueSource(), "http://") && | |
dataflow().anyLocalFlow(literal, NEW_FILE_READER::matches)) { | |
// modify the input itself to sanitize it | |
} | |
return super.visitLiteral(literal, p); | |
} | |
// API ----------------------------------------------- | |
public Dataflow dataflow() { | |
return new Dataflow(); | |
} | |
class Dataflow { | |
public boolean anyLocalFlow(Predicate<? extends Expression> sourceMatches, Expression sink) { | |
return false; | |
} | |
public boolean anyLocalFlow(Expression source, Predicate<? extends Expression> sinkMatches) { | |
return false; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.openrewrite.java.dataflow; | |
import org.openrewrite.java.JavaIsoVisitor; | |
import org.openrewrite.java.MethodMatcher; | |
import org.openrewrite.java.tree.Expression; | |
import org.openrewrite.java.tree.J; | |
import java.util.function.Predicate; | |
/** | |
* from Constructor fileReader, Call call, Expr src | |
* where | |
* fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and | |
* call.getCallee() = fileReader and | |
* DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0))) | |
* select src | |
*/ | |
public class FileTempDirThing<P> extends JavaIsoVisitor<P> { | |
private static final MethodMatcher FILE_MKDIRS = new MethodMatcher("java.io.File mkdirs()"); | |
private static final MethodMatcher FILE_DELETE = new MethodMatcher("java.io.File delete()"); | |
/** | |
f1 = new File(); | |
f2 = f1.identity(); | |
try { | |
File f = Files.createTempFile(null, null).toFile(); | |
// a = "http:" | |
// b = a + "hi" | |
// through the f, not through the delete | |
// f | |
// f.delete() | |
f = new File(); | |
f.delete(); | |
// from the assignment (source) to the subject of delete (sink) | |
// from the subject of delete (source) to the the subject of mkdirs (sink) | |
boolean m = f.mkdirs(); | |
if (!m) { | |
throw new RuntimeException("e"); | |
} | |
} catch(Throwable t) { | |
} | |
*/ | |
// Example of fixing at the sink | |
@Override | |
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, P p) { | |
J.MethodInvocation m = super.visitMethodInvocation(method, p); | |
if (FILE_MKDIRS.matches(m) && dataflow().anyLocalFlow(FILE_DELETE::matches, m)) { | |
} | |
return m; | |
} | |
// API ----------------------------------------------- | |
public Dataflow dataflow() { | |
return new Dataflow(); | |
} | |
class Dataflow { | |
public boolean anyLocalFlow(Predicate<? extends Expression> sourceMatches, Expression sink) { | |
return false; | |
} | |
public boolean anyLocalFlow(Expression source, Predicate<? extends Expression> sinkMatches) { | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment