2 files changed
@@ -11,6 +11,9 @@ import java | |||
| 11 | 11 | import semmle.code.java.controlflow.Guards | |
| 12 | 12 | import semmle.code.java.dataflow.FlowSources | |
| 13 | 13 | import semmle.code.java.security.TempFileLib | |
| 14 | + import semmle.code.java.dataflow.DataFlow3 | ||
| 15 | + import semmle.code.java.dataflow.TaintTracking | ||
| 16 | + import semmle.code.java.dataflow.TaintTracking2 | ||
| 14 | 17 | import DataFlow::PathGraph | |
| 15 | 18 | ||
| 16 | 19 | /** | |
@@ -31,33 +34,41 @@ predicate isDeleteFileExpr(Expr expr) { | |||
| 31 | 34 | expr = any(MethodFileDelete m).getAReference().getQualifier() | |
| 32 | 35 | } | |
| 33 | 36 | ||
| 34 | - private class TempDirHijackingToDeleteConfig extends TaintTracking::Configuration { | ||
| 35 | - TempDirHijackingToDeleteConfig() { this = "TempDirHijackingToDeleteConfig" } | ||
| 36 | - | ||
| 37 | - override predicate isSource(DataFlow::Node source) { | ||
| 38 | - source.asExpr() = | ||
| 37 | + private class DirHijackingTaintSource extends DataFlow::Node { | ||
| 38 | + DirHijackingTaintSource() { | ||
| 39 | + this.asExpr() = | ||
| 39 | 40 | any(MethodAccess ma | | |
| 40 | 41 | ma.getMethod() instanceof MethodFileCreateTempFile and ma.getNumArgument() = 2 | |
| 41 | 42 | ) | |
| 42 | 43 | or | |
| 43 | 44 | // TODO: Replace with getSystemProperty("java.io.tmpdir") | |
| 44 | - source.asExpr() = | ||
| 45 | + this.asExpr() = | ||
| 45 | 46 | any(MethodAccessSystemGetProperty maSgp | | |
| 46 | 47 | maSgp.hasCompileTimeConstantGetPropertyName("java.io.tmpdir") | |
| 47 | 48 | ) | |
| 48 | 49 | } | |
| 50 | + } | ||
| 51 | + | ||
| 52 | + private predicate isAdditionalTaintStepCommon(DataFlow::Node node1, DataFlow::Node node2) { | ||
| 53 | + node2.asExpr() = | ||
| 54 | + any(MethodAccess ma | | ||
| 55 | + ma.getMethod() instanceof MethodFileCreateTempFile and ma.getArgument(2) = node1.asExpr() | ||
| 56 | + ) | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + private class TempDirHijackingToDeleteConfig extends TaintTracking2::Configuration { | ||
| 60 | + TempDirHijackingToDeleteConfig() { this = "TempDirHijackingToDeleteConfig" } | ||
| 61 | + | ||
| 62 | + override predicate isSource(DataFlow::Node source) { source instanceof DirHijackingTaintSource } | ||
| 49 | 63 | ||
| 50 | 64 | override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { | |
| 51 | - node2.asExpr() = | ||
| 52 | - any(MethodAccess ma | | ||
| 53 | - ma.getMethod() instanceof MethodFileCreateTempFile and ma.getArgument(2) = node1.asExpr() | ||
| 54 | - ) | ||
| 65 | + isAdditionalTaintStepCommon(node1, node2) | ||
| 55 | 66 | } | |
| 56 | 67 | ||
| 57 | 68 | override predicate isSink(DataFlow::Node sink) { isDeleteFileExpr(sink.asExpr()) } | |
| 58 | 69 | } | |
| 59 | 70 | ||
| 60 | - private class TempDirHijackingFromDeleteConfig extends DataFlow2::Configuration { | ||
| 71 | + private class TempDirHijackingFromDeleteConfig extends DataFlow3::Configuration { | ||
| 61 | 72 | TempDirHijackingFromDeleteConfig() { this = "TempDirHijackingFromDeleteConfig" } | |
| 62 | 73 | ||
| 63 | 74 | override predicate isSource(DataFlow::Node source) { isDeleteFileExpr(source.asExpr()) } | |
@@ -127,15 +138,31 @@ private predicate safeUse(Expr e) { | |||
| 127 | 138 | ) | |
| 128 | 139 | } | |
| 129 | 140 | ||
| 141 | + private class TempDirHijackingFullPath extends TaintTracking::Configuration { | ||
| 142 | + TempDirHijackingFullPath() { this = "TempDirHijackingFullPath" } | ||
| 143 | + | ||
| 144 | + override predicate isSource(DataFlow::Node source) { source instanceof DirHijackingTaintSource } | ||
| 145 | + | ||
| 146 | + override predicate isSink(DataFlow::Node sink) { | ||
| 147 | + isNonThrowingDirectoryCreationExpression(sink.asExpr(), _) | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { | ||
| 151 | + isAdditionalTaintStepCommon(node1, node2) | ||
| 152 | + or | ||
| 153 | + node1.asExpr() = node2.asExpr() and isDeleteFileExpr(node1.asExpr()) | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + | ||
| 130 | 157 | from | |
| 131 | - DataFlow::PathNode source, DataFlow::PathNode deleteCheckpoint, DataFlow2::Node deleteCheckpoint2, | ||
| 132 | - DataFlow2::Node sink, MethodAccess creationCall, Expr unsafe | ||
| 158 | + DataFlow::PathNode pathSource, DataFlow::PathNode pathSink, DataFlow::Node deleteCheckpoint, | ||
| 159 | + MethodAccess creationCall, Expr unsafe | ||
| 133 | 160 | where | |
| 134 | - any(TempDirHijackingToDeleteConfig c).hasFlowPath(source, deleteCheckpoint) and | ||
| 135 | - any(TempDirHijackingFromDeleteConfig c).hasFlow(deleteCheckpoint2, sink) and | ||
| 136 | - deleteCheckpoint.getNode().asExpr() = deleteCheckpoint2.asExpr() and | ||
| 137 | - isUnsafeUseUnconstrainedByIfCheck(sink, unsafe) and | ||
| 138 | - isNonThrowingDirectoryCreationExpression(sink.asExpr(), creationCall) | ||
| 139 | - select deleteCheckpoint.getNode(), source, deleteCheckpoint, | ||
| 140 | - "Local temporary directory hijacking race condition $@, file $@ may have been hijacked", | ||
| 141 | - creationCall, "here", unsafe, "here" | ||
| 161 | + any(TempDirHijackingFullPath c).hasFlowPath(pathSource, pathSink) and | ||
| 162 | + any(TempDirHijackingToDeleteConfig c).hasFlow(pathSource.getNode(), deleteCheckpoint) and | ||
| 163 | + any(TempDirHijackingFromDeleteConfig c).hasFlow(deleteCheckpoint, pathSink.getNode()) and | ||
| 164 | + isUnsafeUseUnconstrainedByIfCheck(pathSink.getNode(), unsafe) and | ||
| 165 | + isNonThrowingDirectoryCreationExpression(pathSink.getNode().asExpr(), creationCall) | ||
| 166 | + select pathSink, pathSource, pathSink, | ||
| 167 | + "Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user.", | ||
| 168 | + deleteCheckpoint.asExpr(), "delete here", unsafe, "here" | ||
@@ -1,54 +1,57 @@ | |||
| 1 | 1 | edges | |
| 2 | - | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:12:13:12:16 | temp | | ||
| 3 | - | Test.java:22:21:22:60 | createTempFile(...) : File | Test.java:23:9:23:12 | temp | | ||
| 4 | - | Test.java:35:21:35:60 | createTempFile(...) : File | Test.java:36:9:36:12 | temp | | ||
| 5 | - | Test.java:45:21:45:60 | createTempFile(...) : File | Test.java:46:9:46:12 | temp | | ||
| 6 | - | Test.java:56:21:56:60 | createTempFile(...) : File | Test.java:57:9:57:12 | temp | | ||
| 7 | - | Test.java:66:21:66:60 | createTempFile(...) : File | Test.java:67:20:67:23 | temp | | ||
| 8 | - | Test.java:77:21:77:60 | createTempFile(...) : File | Test.java:78:20:78:23 | temp | | ||
| 9 | - | Test.java:88:21:88:60 | createTempFile(...) : File | Test.java:89:13:89:16 | temp | | ||
| 10 | - | Test.java:97:21:97:60 | createTempFile(...) : File | Test.java:98:14:98:17 | temp | | ||
| 11 | - | Test.java:109:21:109:60 | createTempFile(...) : File | Test.java:110:30:110:33 | temp | | ||
| 12 | - | Test.java:118:21:118:60 | createTempFile(...) : File | Test.java:119:14:119:17 | temp | | ||
| 13 | - | Test.java:129:62:129:107 | new File(...) : File | Test.java:130:9:130:12 | temp | | ||
| 2 | + | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:13:13:13:16 | temp | | ||
| 3 | + | Test.java:22:21:22:60 | createTempFile(...) : File | Test.java:24:9:24:12 | temp | | ||
| 4 | + | Test.java:29:21:29:60 | createTempFile(...) : File | Test.java:30:9:30:12 | temp | | ||
| 5 | + | Test.java:35:21:35:60 | createTempFile(...) : File | Test.java:37:13:37:16 | temp | | ||
| 6 | + | Test.java:45:21:45:60 | createTempFile(...) : File | Test.java:47:29:47:32 | temp | | ||
| 7 | + | Test.java:56:21:56:60 | createTempFile(...) : File | Test.java:58:15:58:18 | temp | | ||
| 8 | + | Test.java:66:21:66:60 | createTempFile(...) : File | Test.java:68:20:68:23 | temp | | ||
| 9 | + | Test.java:77:21:77:60 | createTempFile(...) : File | Test.java:79:20:79:23 | temp | | ||
| 10 | + | Test.java:88:21:88:60 | createTempFile(...) : File | Test.java:89:30:89:33 | temp | | ||
| 11 | + | Test.java:97:21:97:60 | createTempFile(...) : File | Test.java:98:32:98:35 | temp | | ||
| 12 | + | Test.java:109:21:109:60 | createTempFile(...) : File | Test.java:110:48:110:51 | temp | | ||
| 13 | + | Test.java:118:21:118:60 | createTempFile(...) : File | Test.java:122:14:122:17 | temp | | ||
| 14 | + | Test.java:129:62:129:107 | new File(...) : File | Test.java:131:9:131:12 | temp | | ||
| 14 | 15 | | Test.java:129:71:129:106 | getProperty(...) : String | Test.java:129:62:129:107 | new File(...) : File | | |
| 15 | 16 | | Test.java:146:13:146:58 | new File(...) : File | Test.java:146:13:146:76 | getAbsoluteFile(...) : File | | |
| 16 | - | Test.java:146:13:146:76 | getAbsoluteFile(...) : File | Test.java:148:9:148:12 | temp | | ||
| 17 | + | Test.java:146:13:146:76 | getAbsoluteFile(...) : File | Test.java:149:9:149:12 | temp | | ||
| 17 | 18 | | Test.java:146:22:146:57 | getProperty(...) : String | Test.java:146:13:146:58 | new File(...) : File | | |
| 18 | 19 | nodes | |
| 19 | 20 | | Test.java:11:20:11:59 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 20 | - | Test.java:12:13:12:16 | temp | semmle.label | temp | | ||
| 21 | + | Test.java:13:13:13:16 | temp | semmle.label | temp | | ||
| 21 | 22 | | Test.java:22:21:22:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 22 | - | Test.java:23:9:23:12 | temp | semmle.label | temp | | ||
| 23 | + | Test.java:24:9:24:12 | temp | semmle.label | temp | | ||
| 24 | + | Test.java:29:21:29:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | ||
| 25 | + | Test.java:30:9:30:12 | temp | semmle.label | temp | | ||
| 23 | 26 | | Test.java:35:21:35:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 24 | - | Test.java:36:9:36:12 | temp | semmle.label | temp | | ||
| 27 | + | Test.java:37:13:37:16 | temp | semmle.label | temp | | ||
| 25 | 28 | | Test.java:45:21:45:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 26 | - | Test.java:46:9:46:12 | temp | semmle.label | temp | | ||
| 29 | + | Test.java:47:29:47:32 | temp | semmle.label | temp | | ||
| 27 | 30 | | Test.java:56:21:56:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 28 | - | Test.java:57:9:57:12 | temp | semmle.label | temp | | ||
| 31 | + | Test.java:58:15:58:18 | temp | semmle.label | temp | | ||
| 29 | 32 | | Test.java:66:21:66:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 30 | - | Test.java:67:20:67:23 | temp | semmle.label | temp | | ||
| 33 | + | Test.java:68:20:68:23 | temp | semmle.label | temp | | ||
| 31 | 34 | | Test.java:77:21:77:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 32 | - | Test.java:78:20:78:23 | temp | semmle.label | temp | | ||
| 35 | + | Test.java:79:20:79:23 | temp | semmle.label | temp | | ||
| 33 | 36 | | Test.java:88:21:88:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 34 | - | Test.java:89:13:89:16 | temp | semmle.label | temp | | ||
| 37 | + | Test.java:89:30:89:33 | temp | semmle.label | temp | | ||
| 35 | 38 | | Test.java:97:21:97:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 36 | - | Test.java:98:14:98:17 | temp | semmle.label | temp | | ||
| 39 | + | Test.java:98:32:98:35 | temp | semmle.label | temp | | ||
| 37 | 40 | | Test.java:109:21:109:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 38 | - | Test.java:110:30:110:33 | temp | semmle.label | temp | | ||
| 41 | + | Test.java:110:48:110:51 | temp | semmle.label | temp | | ||
| 39 | 42 | | Test.java:118:21:118:60 | createTempFile(...) : File | semmle.label | createTempFile(...) : File | | |
| 40 | - | Test.java:119:14:119:17 | temp | semmle.label | temp | | ||
| 43 | + | Test.java:122:14:122:17 | temp | semmle.label | temp | | ||
| 41 | 44 | | Test.java:129:62:129:107 | new File(...) : File | semmle.label | new File(...) : File | | |
| 42 | 45 | | Test.java:129:71:129:106 | getProperty(...) : String | semmle.label | getProperty(...) : String | | |
| 43 | - | Test.java:130:9:130:12 | temp | semmle.label | temp | | ||
| 46 | + | Test.java:131:9:131:12 | temp | semmle.label | temp | | ||
| 44 | 47 | | Test.java:146:13:146:58 | new File(...) : File | semmle.label | new File(...) : File | | |
| 45 | 48 | | Test.java:146:13:146:76 | getAbsoluteFile(...) : File | semmle.label | getAbsoluteFile(...) : File | | |
| 46 | 49 | | Test.java:146:22:146:57 | getProperty(...) : String | semmle.label | getProperty(...) : String | | |
| 47 | - | Test.java:148:9:148:12 | temp | semmle.label | temp | | ||
| 50 | + | Test.java:149:9:149:12 | temp | semmle.label | temp | | ||
| 48 | 51 | subpaths | |
| 49 | 52 | #select | |
| 50 | - | Test.java:12:13:12:16 | temp | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:12:13:12:16 | temp | Local temporary directory hijacking race condition $@, file $@ may have been hijacked | Test.java:13:13:13:24 | mkdir(...) | here | Test.java:18:9:18:33 | ...=... | here | | ||
| 51 | - | Test.java:12:13:12:16 | temp | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:12:13:12:16 | temp | Local temporary directory hijacking race condition $@, file $@ may have been hijacked | Test.java:13:13:13:24 | mkdir(...) | here | Test.java:18:30:18:33 | temp | here | | ||
| 52 | - | Test.java:23:9:23:12 | temp | Test.java:22:21:22:60 | createTempFile(...) : File | Test.java:23:9:23:12 | temp | Local temporary directory hijacking race condition $@, file $@ may have been hijacked | Test.java:24:9:24:20 | mkdir(...) | here | Test.java:25:16:25:19 | temp | here | | ||
| 53 | - | Test.java:130:9:130:12 | temp | Test.java:129:71:129:106 | getProperty(...) : String | Test.java:130:9:130:12 | temp | Local temporary directory hijacking race condition $@, file $@ may have been hijacked | Test.java:131:9:131:20 | mkdir(...) | here | Test.java:132:16:132:19 | temp | here | | ||
| 54 | - | Test.java:148:9:148:12 | temp | Test.java:146:22:146:57 | getProperty(...) : String | Test.java:148:9:148:12 | temp | Local temporary directory hijacking race condition $@, file $@ may have been hijacked | Test.java:149:9:149:20 | mkdir(...) | here | Test.java:150:16:150:19 | temp | here | | ||
| 53 | + | Test.java:13:13:13:16 | temp | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:13:13:13:16 | temp | Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user. | Test.java:12:13:12:16 | temp | delete here | Test.java:18:9:18:33 | ...=... | here | | ||
| 54 | + | Test.java:13:13:13:16 | temp | Test.java:11:20:11:59 | createTempFile(...) : File | Test.java:13:13:13:16 | temp | Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user. | Test.java:12:13:12:16 | temp | delete here | Test.java:18:30:18:33 | temp | here | | ||
| 55 | + | Test.java:24:9:24:12 | temp | Test.java:22:21:22:60 | createTempFile(...) : File | Test.java:24:9:24:12 | temp | Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user. | Test.java:23:9:23:12 | temp | delete here | Test.java:25:16:25:19 | temp | here | | ||
| 56 | + | Test.java:131:9:131:12 | temp | Test.java:129:71:129:106 | getProperty(...) : String | Test.java:131:9:131:12 | temp | Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user. | Test.java:130:9:130:12 | temp | delete here | Test.java:132:16:132:19 | temp | here | | ||
| 57 | + | Test.java:149:9:149:12 | temp | Test.java:146:22:146:57 | getProperty(...) : String | Test.java:149:9:149:12 | temp | Local temporary directory hijacking race condition between $@ and this directory creation call. As such, the directory usage $@ may have been hijacked by another local user. | Test.java:148:9:148:12 | temp | delete here | Test.java:150:16:150:19 | temp | here | | ||
0 commit comments