Skip to content

Commit 2ab1026

Browse files
committed
V3: better sinks, replace sinks arguments to sinks method accesses
1 parent 83cffea commit 2ab1026

1 file changed

Lines changed: 35 additions & 74 deletions

File tree

java/ql/src/experimental/Security/CWE/CWE-522-DecompressionBombs/DecompressionBomb.ql

Lines changed: 35 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,8 @@ module XserialSnappy {
4949
// Method calls
5050
call.(MethodAccess).getReceiverType() = any(TypeInputStream t) and
5151
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
52-
(
53-
call.getArgument(0) = n2.asExpr() and
54-
call.getQualifier() = n1.asExpr()
55-
or
56-
call.getArgument(0) = n1.asExpr() and
57-
call = n2.asExpr()
58-
)
52+
call.getQualifier() = n1.asExpr() and
53+
call = n2.asExpr()
5954
)
6055
}
6156

@@ -69,9 +64,9 @@ module XserialSnappy {
6964
}
7065

7166
/**
72-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
67+
* A method Access as a sink which responsible for reading bytes
7368
*/
74-
Expr getAWriteArgument() { result = this.getArgument(0) }
69+
MethodAccess getAByteRead() { result = this }
7570

7671
// look at Zip4j comments for this method
7772
predicate isControlledRead() { none() }
@@ -165,13 +160,8 @@ module ApacheCommons {
165160
// Method calls
166161
call.(MethodAccess).getReceiverType() = any(TypeCompressors t) and
167162
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
168-
(
169-
call.getArgument(0) = n2.asExpr() and
170-
call.getQualifier() = n1.asExpr()
171-
or
172-
call.getArgument(0) = n1.asExpr() and
173-
call = n2.asExpr()
174-
)
163+
call.getQualifier() = n1.asExpr() and
164+
call = n2.asExpr()
175165
)
176166
}
177167

@@ -185,9 +175,9 @@ module ApacheCommons {
185175
}
186176

187177
/**
188-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
178+
* A method Access as a sink which responsible for reading bytes
189179
*/
190-
Expr getAWriteArgument() { result = this.getArgument(0) }
180+
MethodAccess getAByteRead() { result = this }
191181

192182
// look at Zip4j comments for this method
193183
predicate isControlledRead() { none() }
@@ -234,13 +224,8 @@ module ApacheCommons {
234224
// Method calls
235225
call.(MethodAccess).getReceiverType() = any(TypeArchivers t) and
236226
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
237-
(
238-
call.getArgument(0) = n2.asExpr() and
239-
call.getQualifier() = n1.asExpr()
240-
or
241-
call.getArgument(0) = n1.asExpr() and
242-
call = n2.asExpr()
243-
)
227+
call.getQualifier() = n1.asExpr() and
228+
call = n2.asExpr()
244229
)
245230
}
246231

@@ -254,9 +239,9 @@ module ApacheCommons {
254239
}
255240

256241
/**
257-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
242+
* A method Access as a sink which responsible for reading bytes
258243
*/
259-
Expr getAWriteArgument() { result = this.getArgument(0) }
244+
MethodAccess getAByteRead() { result = this }
260245

261246
// look at Zip4j comments for this method
262247
predicate isControlledRead() { none() }
@@ -312,13 +297,8 @@ module ApacheCommons {
312297
call.(MethodAccess).getReceiverType() = any(TypeCompressorInputStream t)
313298
) and
314299
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
315-
(
316-
call.getArgument(0) = n2.asExpr() and
317-
call.getQualifier() = n1.asExpr()
318-
or
319-
call.getArgument(0) = n1.asExpr() and
320-
call = n2.asExpr()
321-
)
300+
call.getQualifier() = n1.asExpr() and
301+
call = n2.asExpr()
322302
)
323303
}
324304

@@ -336,9 +316,9 @@ module ApacheCommons {
336316
}
337317

338318
/**
339-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
319+
* A method Access as a sink which responsible for reading bytes
340320
*/
341-
Expr getAWriteArgument() { result = this.getArgument(0) }
321+
MethodAccess getAByteRead() { result = this }
342322

343323
// look at Zip4j comments for this method
344324
predicate isControlledRead() { none() }
@@ -369,9 +349,9 @@ module Zip4j {
369349
}
370350

371351
/**
372-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
352+
* A method Access as a sink which responsible for reading bytes
373353
*/
374-
Expr getAWriteArgument() { result = this.getArgument(0) }
354+
MethodAccess getAByteRead() { result = this }
375355

376356
// while ((readLen = zipInputStream.read(readBuffer)) != -1) {
377357
// totallRead += readLen;
@@ -405,13 +385,8 @@ module Zip4j {
405385
// Method calls
406386
call.(MethodAccess).getReceiverType() = any(TypeZipInputStream t) and
407387
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
408-
(
409-
call.getArgument(0) = n2.asExpr() and
410-
call.getQualifier() = n1.asExpr()
411-
or
412-
call.getArgument(0) = n1.asExpr() and
413-
call = n2.asExpr()
414-
)
388+
call.getQualifier() = n1.asExpr() and
389+
call = n2.asExpr()
415390
)
416391
}
417392
}
@@ -460,9 +435,9 @@ module Zip {
460435
}
461436

462437
/**
463-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
438+
* A method Access as a sink which responsible for reading bytes
464439
*/
465-
Expr getAWriteArgument() { result = this.getArgument(0) }
440+
MethodAccess getAByteRead() { result = this }
466441

467442
// look at Zip4j comments for this method
468443
predicate isControlledRead() { none() }
@@ -484,13 +459,8 @@ module Zip {
484459
// Method calls
485460
call.(MethodAccess).getReceiverType() = any(TypeInputStream t) and
486461
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
487-
(
488-
call.getArgument(0) = n2.asExpr() and
489-
call.getQualifier() = n1.asExpr()
490-
or
491-
call.getArgument(0) = n1.asExpr() and
492-
call = n2.asExpr()
493-
)
462+
call.getQualifier() = n1.asExpr() and
463+
call = n2.asExpr()
494464
)
495465
}
496466

@@ -544,9 +514,9 @@ module Zip {
544514
}
545515

546516
/**
547-
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
517+
* A method Access as a sink which responsible for reading bytes
548518
*/
549-
Expr getAWriteArgument() { result = this.getArgument(0) }
519+
MethodAccess getAByteRead() { result = this }
550520

551521
// look at Zip4j comments for this method
552522
predicate isControlledRead() { none() }
@@ -609,17 +579,8 @@ module InputStream {
609579
// Method calls
610580
call.(MethodAccess).getReceiverType() = any(InputStream::TypeInputStream t) and
611581
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
612-
(
613-
// call.getArgument(0) = n2.asExpr() and
614-
// call.getQualifier() = n1.asExpr()
615-
// or
616-
// call.getArgument(0) = n1.asExpr() and
617-
// call = n2.asExpr()
618-
// or
619-
// TODO: only implement following
620-
call.getQualifier() = n1.asExpr() and
621-
call = n2.asExpr()
622-
)
582+
call.getQualifier() = n1.asExpr() and
583+
call = n2.asExpr()
623584
)
624585
}
625586
}
@@ -647,28 +608,28 @@ module DecompressionBombsConfig implements DataFlow::StateConfigSig {
647608
state = ["Zip4j", "inflator", "Zip", "ApacheCommons", "XserialSnappy", "ZipFile"]
648609
)
649610
or
650-
sink.asExpr() = any(Zip4j::ReadInputStreamCall r).getAWriteArgument() and
611+
sink.asExpr() = any(Zip4j::ReadInputStreamCall r).getAByteRead() and
651612
state = "Zip4j"
652613
or
653-
sink.asExpr() = any(Zip::InflateCall r).getAWriteArgument() and
614+
sink.asExpr() = any(Zip::InflateCall r).getAByteRead() and
654615
state = "inflator"
655616
or
656617
sink.asExpr() instanceof InputStream::Read and
657618
state = "ZipFile"
658619
or
659-
sink.asExpr() = any(Zip::ReadInputStreamCall r).getAWriteArgument() and
620+
sink.asExpr() = any(Zip::ReadInputStreamCall r).getAByteRead() and
660621
state = "Zip"
661622
or
662-
sink.asExpr() = any(ApacheCommons::Factory::ReadInputStreamCall r).getAWriteArgument() and
623+
sink.asExpr() = any(ApacheCommons::Factory::ReadInputStreamCall r).getAByteRead() and
663624
state = "ApacheCommons"
664625
or
665-
sink.asExpr() = any(ApacheCommons::Compressors::ReadInputStreamCall r).getAWriteArgument() and
626+
sink.asExpr() = any(ApacheCommons::Compressors::ReadInputStreamCall r).getAByteRead() and
666627
state = "ApacheCommons"
667628
or
668-
sink.asExpr() = any(ApacheCommons::Archivers::ReadInputStreamCall r).getAWriteArgument() and
629+
sink.asExpr() = any(ApacheCommons::Archivers::ReadInputStreamCall r).getAByteRead() and
669630
state = "ApacheCommons"
670631
or
671-
sink.asExpr() = any(XserialSnappy::ReadInputStreamCall r).getAWriteArgument() and
632+
sink.asExpr() = any(XserialSnappy::ReadInputStreamCall r).getAByteRead() and
672633
state = "XserialSnappy"
673634
)
674635
}

0 commit comments

Comments
 (0)