mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
relocate the query
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* https://github.com/google/brotli
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.commons.File
|
||||
|
||||
/**
|
||||
* A Pointer Variable is used in Flow source
|
||||
*/
|
||||
class PointerVar extends VariableAccess {
|
||||
PointerVar() { this.getType() instanceof PointerType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A Pointer Variable is used in Flow source
|
||||
*/
|
||||
class Uint8Var extends VariableAccess {
|
||||
Uint8Var() { this.getType() instanceof UInt8_t }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BrotliDecoderDecompress` function is used in Flow sink
|
||||
* Ref: https://www.brotli.org/decode.html#af68
|
||||
*/
|
||||
class BrotliDecoderDecompressFunction extends Function {
|
||||
BrotliDecoderDecompressFunction() { this.hasGlobalName(["BrotliDecoderDecompress"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BrotliDecoderDecompressStream` function is used in Flow sink
|
||||
* Ref: https://www.brotli.org/decode.html#a234
|
||||
*/
|
||||
class BrotliDecoderDecompressStreamFunction extends Function {
|
||||
BrotliDecoderDecompressStreamFunction() { this.hasGlobalName(["BrotliDecoderDecompressStream"]) }
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* https://www.sourceware.org/bzip2/manual/manual.html
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.commons.File
|
||||
|
||||
/**
|
||||
* A `bz_stream` Variable as a Flow source
|
||||
*/
|
||||
class BzStreamVar extends VariableAccess {
|
||||
BzStreamVar() { this.getType().hasName("bz_stream") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `BZFILE` Variable as a Flow source
|
||||
*/
|
||||
class BzFileVar extends VariableAccess {
|
||||
BzFileVar() { this.getType().hasName("BZFILE") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BZ2_bzDecompress` function as a Flow source
|
||||
*/
|
||||
class BZ2BzDecompressFunction extends Function {
|
||||
BZ2BzDecompressFunction() { this.hasGlobalName(["BZ2_bzDecompress"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BZ2_bzReadOpen` function
|
||||
*/
|
||||
class BZ2BzReadOpenFunction extends Function {
|
||||
BZ2BzReadOpenFunction() { this.hasGlobalName(["BZ2_bzReadOpen"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BZ2_bzRead` function is used in Flow sink
|
||||
*/
|
||||
class BZ2BzReadFunction extends Function {
|
||||
BZ2BzReadFunction() { this.hasGlobalName("BZ2_bzRead") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BZ2_bzBuffToBuffDecompress` function is used in Flow sink
|
||||
*/
|
||||
class BZ2BzBuffToBuffDecompressFunction extends Function {
|
||||
BZ2BzBuffToBuffDecompressFunction() { this.hasGlobalName("BZ2_bzBuffToBuffDecompress") }
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.</p>
|
||||
<p>Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.</p>
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
Reading uncompressed Gzip file within a loop and check for a threshold size in each cycle.
|
||||
</p>
|
||||
<sample src="example_good.cpp"/>
|
||||
|
||||
<p>
|
||||
An Unsafe Approach can be this example which we don't check for uncompressed size.
|
||||
</p>
|
||||
<sample src="example_bad.cpp" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>
|
||||
<a href="https://zlib.net/manual.html">Zlib Documentation</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://www.bamsoftware.com/hacks/zipbomb/">A great research to gain more impact by this kind of attacks</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,186 +0,0 @@
|
||||
/**
|
||||
* @name User-controlled file decompression
|
||||
* @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 7.8
|
||||
* @precision high
|
||||
* @id cpp/data-decompression
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-409
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.commons.File
|
||||
import Bzip2
|
||||
import Brotli
|
||||
import LibArchive
|
||||
import LibMiniz
|
||||
import ZSTD
|
||||
import MiniZip
|
||||
import XZ
|
||||
import ZlibGzopen
|
||||
import ZlibUncompress
|
||||
import ZlibInflator
|
||||
import Brotli
|
||||
|
||||
module DecompressionTaintConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction |
|
||||
fc.getArgument(2) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction |
|
||||
fc.getArgument(2) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof MzInflate |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction |
|
||||
fc.getArgument(2) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction |
|
||||
fc.getArgument(3) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction |
|
||||
fc.getArgument(2) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction |
|
||||
fc.getArgument(3) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction |
|
||||
fc.getArgument(3) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction |
|
||||
fc.getArgument(1) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction |
|
||||
sink.asExpr() = fc.getArgument(3)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction |
|
||||
sink.asExpr() = fc.getArgument(0)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction |
|
||||
fc.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc.getArgument(1)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc.getArgument(1)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction
|
||||
|
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc.getArgument(1)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction |
|
||||
node1.asExpr() = fc.getArgument(3) and
|
||||
node2.asExpr() = fc.getArgument(0)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node1.asExpr() = fc.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module DecompressionTaint = TaintTracking::Global<DecompressionTaintConfig>;
|
||||
|
||||
import DecompressionTaint::PathGraph
|
||||
|
||||
from DecompressionTaint::PathNode source, DecompressionTaint::PathNode sink
|
||||
where DecompressionTaint::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This Decompression output $@.", source.getNode(),
|
||||
"is not limited"
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* https://github.com/libarchive/libarchive/wiki
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* The `archive_read_new` function as a Flow source
|
||||
* create a `archive` instance
|
||||
*/
|
||||
class Archive_read_new extends Function {
|
||||
Archive_read_new() { this.hasGlobalName("archive_read_new") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `archive_read_data*` functions are used in Flow Sink
|
||||
* [Examples](https://github.com/libarchive/libarchive/wiki/Examples)
|
||||
*/
|
||||
class Archive_read_data_block extends Function {
|
||||
Archive_read_data_block() {
|
||||
this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"])
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* https://github.com/richgel999/miniz
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* A unsigned char Variable is used in Flow source
|
||||
*/
|
||||
class UnsignedCharVar extends VariableAccess {
|
||||
UnsignedCharVar() { this.getType().stripType().resolveTypedefs*() instanceof UnsignedCharType }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_streamp`, `z_stream` Variables are used in Flow source
|
||||
*/
|
||||
class MzStreampVar extends VariableAccess {
|
||||
MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A Char Variable is used in Flow source
|
||||
*/
|
||||
class CharVar extends VariableAccess {
|
||||
CharVar() { this.getType().stripType().resolveTypedefs*() instanceof CharType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `mz_zip_archive` Variable is used in Flow source
|
||||
*/
|
||||
class MzZipArchiveVar extends VariableAccess {
|
||||
MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_uncompress` functions are used in Flow Sink
|
||||
*/
|
||||
class MzUncompress extends Function {
|
||||
MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `zip handle` is used in Flow source
|
||||
*/
|
||||
class MzZip extends Function {
|
||||
MzZip() {
|
||||
this.hasGlobalName([
|
||||
"mz_zip_reader_open", "mz_zip_reader_open_file", "mz_zip_reader_open_file_in_memory",
|
||||
"mz_zip_reader_open_buffer", "mz_zip_reader_entry_open"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_inflate` functions are used in Flow Sink
|
||||
*/
|
||||
class MzInflate extends Function {
|
||||
MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_inflateInit` functions are used in Flow Sink
|
||||
*/
|
||||
class MzInflateInit extends Function {
|
||||
MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_reader_extract_*` functions are used in Flow Sink
|
||||
*/
|
||||
class MzZipReaderExtract extends Function {
|
||||
MzZipReaderExtract() {
|
||||
this.hasGlobalName([
|
||||
"mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap",
|
||||
"mz_zip_reader_extract_to_callback", "mz_zip_reader_extract_file_to_callback",
|
||||
"mz_zip_reader_extract_to_mem", "mz_zip_reader_extract_file_to_mem",
|
||||
"mz_zip_reader_extract_iter_read", "mz_zip_reader_extract_to_file",
|
||||
"mz_zip_reader_extract_file_to_file"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `tinfl_decompress_mem_*` functions are used in Flow Sink
|
||||
*/
|
||||
class TinflDecompressMem extends Function {
|
||||
TinflDecompressMem() {
|
||||
this.hasGlobalName([
|
||||
"tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem",
|
||||
"tinfl_decompress_mem_to_heap"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `tinfl_decompress_*` functions are used in Flow Sink
|
||||
*/
|
||||
class TinflDecompress extends Function {
|
||||
TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) }
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* https://github.com/zlib-ng/minizip-ng
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* The `mz_zip_reader_create` function as a Flow source
|
||||
* create a `mz_zip_reader` instance
|
||||
*/
|
||||
class Mz_zip_reader_create extends Function {
|
||||
Mz_zip_reader_create() { this.hasGlobalName("mz_zip_reader_create") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_create` function as a Flow source
|
||||
* create a `mz_zip` instance
|
||||
*/
|
||||
class Mz_zip_create extends Function {
|
||||
Mz_zip_create() { this.hasGlobalName("mz_zip_create") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_entry` function is used in Flow source
|
||||
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md)
|
||||
*/
|
||||
class Mz_zip_entry extends Function {
|
||||
Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in Flow source
|
||||
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md)
|
||||
*/
|
||||
class Mz_zip_reader_entry extends Function {
|
||||
Mz_zip_reader_entry() {
|
||||
this.hasGlobalName([
|
||||
"mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process",
|
||||
"mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `unzFile` Variable as a Flow source
|
||||
*/
|
||||
class UnzFileVar extends VariableAccess {
|
||||
UnzFileVar() { this.getType().hasName("unzFile") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `UnzOpen` function as a Flow source
|
||||
*/
|
||||
class UnzOpenFunction extends Function {
|
||||
UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `unzReadCurrentFile` function is used in Flow sink
|
||||
*/
|
||||
class UnzReadCurrentFileFunction extends Function {
|
||||
UnzReadCurrentFileFunction() { this.hasGlobalName(["unzReadCurrentFile"]) }
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* https://github.com/tukaani-project/xz
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* A `lzma_stream` Variable as a Flow source
|
||||
*/
|
||||
class LzmaStreamVar extends VariableAccess {
|
||||
LzmaStreamVar() { this.getType().hasName("lzma_stream") }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The `lzma_code` function is used in Flow sink
|
||||
*/
|
||||
class LzmaCodeFunction extends Function {
|
||||
LzmaCodeFunction() { this.hasGlobalName(["lzma_code"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `lzma_stream_buffer_decode` function is used in Flow sink
|
||||
*/
|
||||
class LzmaStreamBufferDecodeFunction extends Function {
|
||||
LzmaStreamBufferDecodeFunction() { this.hasGlobalName(["lzma_stream_buffer_decode"]) }
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* https://github.com/facebook/zstd/blob/dev/examples/streaming_decompression.c
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.commons.File
|
||||
|
||||
/**
|
||||
* A ZSTD_inBuffer Variable as a Flow source
|
||||
*/
|
||||
class ZSTDinBufferVar extends VariableAccess {
|
||||
ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A ZSTD_inBuffer_s Variable as a Flow source
|
||||
*/
|
||||
class ZSTDinBufferSVar extends VariableAccess {
|
||||
ZSTDinBufferSVar() { this.getType().hasName("ZSTD_inBuffer_s") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompress` function is used in Flow sink
|
||||
*/
|
||||
class ZSTDDecompressFunction extends Function {
|
||||
ZSTDDecompressFunction() { this.hasGlobalName(["ZSTD_decompress"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompressDCtx` function is used in Flow sink
|
||||
*/
|
||||
class ZSTDDecompressDCtxFunction extends Function {
|
||||
ZSTDDecompressDCtxFunction() { this.hasGlobalName(["ZSTD_decompressDCtx"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompressStream` function is used in Flow sink
|
||||
*/
|
||||
class ZSTDDecompressStreamFunction extends Function {
|
||||
ZSTDDecompressStreamFunction() { this.hasGlobalName(["ZSTD_decompressStream"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompress_usingDDict` function is used in Flow sink
|
||||
*/
|
||||
class ZSTDDecompressUsingDictFunction extends Function {
|
||||
ZSTDDecompressUsingDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompress_usingDDict` function is used in Flow sink
|
||||
*/
|
||||
class ZSTDDecompressUsingDDictFunction extends Function {
|
||||
ZSTDDecompressUsingDDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) }
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* A `gzFile` Variable as a Flow source
|
||||
*/
|
||||
class GzFileVar extends VariableAccess {
|
||||
GzFileVar() { this.getType().hasName("gzFile") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzopen` function as a Flow source
|
||||
*
|
||||
* `gzopen(const char *path, const char *mode)`
|
||||
*/
|
||||
class GzopenFunction extends Function {
|
||||
GzopenFunction() { this.hasGlobalName("gzopen") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzdopen` function as a Flow source
|
||||
*
|
||||
* `gzdopen(int fd, const char *mode)`
|
||||
*/
|
||||
class GzdopenFunction extends Function {
|
||||
GzdopenFunction() { this.hasGlobalName("gzdopen") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzfread` function is used in Flow sink
|
||||
*
|
||||
* `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)`
|
||||
*/
|
||||
class GzFreadFunction extends Function {
|
||||
GzFreadFunction() { this.hasGlobalName("gzfread") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzgets` function is used in Flow sink.
|
||||
*
|
||||
* `gzgets(gzFile file, char *buf, int len)`
|
||||
*/
|
||||
class GzGetsFunction extends Function {
|
||||
GzGetsFunction() { this.hasGlobalName("gzgets") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzread` function is used in Flow sink
|
||||
*
|
||||
* `gzread(gzFile file, voidp buf, unsigned len)`
|
||||
*/
|
||||
class GzReadFunction extends Function {
|
||||
GzReadFunction() { this.hasGlobalName("gzread") }
|
||||
}
|
||||
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction |
|
||||
fc.getArgument(0) = source.asExpr() and
|
||||
// arg 0 can be a path string whichwe must do following check
|
||||
not fc.getArgument(0).isConstant()
|
||||
)
|
||||
or
|
||||
// IDK whether it is good to use all file decriptors function returns as source or not
|
||||
// because we can do more sanitization from fd function sources
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction |
|
||||
fc.getArgument(0) = source.asExpr()
|
||||
)
|
||||
or
|
||||
source.asExpr() instanceof GzFileVar
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* A `z_stream` Variable as a Flow source
|
||||
*/
|
||||
class ZStreamVar extends VariableAccess {
|
||||
ZStreamVar() { this.getType().hasName("z_stream") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `inflate`/`inflateSync` functions are used in Flow sink
|
||||
*
|
||||
* `inflate(z_streamp strm, int flush)`
|
||||
*
|
||||
* `inflateSync(z_streamp strm)`
|
||||
*/
|
||||
class InflateFunction extends Function {
|
||||
InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) }
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* A Bytef Variable as a Flow source
|
||||
*/
|
||||
class BytefVar extends VariableAccess {
|
||||
BytefVar() { this.getType().hasName("Bytef") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `uncompress`/`uncompress2` function is used in Flow sink
|
||||
*/
|
||||
class UncompressFunction extends Function {
|
||||
UncompressFunction() { this.hasGlobalName(["uncompress", "uncompress2"]) }
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "zlib.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
int UnsafeInflate(int argc, char *argv[]) {
|
||||
// original string len = 36
|
||||
char a[50] = "Hello Hello Hello Hello Hello Hello!";
|
||||
// placeholder for the compressed (deflated) version of "a"
|
||||
char b[50];
|
||||
// placeholder for the Uncompressed (inflated) version of "b"
|
||||
char c[50];
|
||||
printf("Uncompressed size is: %lu\n", strlen(a));
|
||||
printf("Uncompressed string is: %s\n", a);
|
||||
printf("\n----------\n\n");
|
||||
|
||||
// STEP 1.
|
||||
// zlib struct
|
||||
z_stream defstream;
|
||||
defstream.zalloc = Z_NULL;
|
||||
defstream.zfree = Z_NULL;
|
||||
defstream.opaque = Z_NULL;
|
||||
// setup "a" as the input and "b" as the compressed output
|
||||
defstream.avail_in = (uInt) strlen(a) + 1; // size of input, string + terminator
|
||||
defstream.next_in = (Bytef *) a; // input char array
|
||||
defstream.avail_out = (uInt) sizeof(b); // size of output
|
||||
defstream.next_out = (Bytef *) b; // output char array
|
||||
|
||||
// the actual compression work.
|
||||
deflateInit(&defstream, Z_BEST_COMPRESSION);
|
||||
deflate(&defstream, Z_FINISH);
|
||||
deflateEnd(&defstream);
|
||||
|
||||
// This is one way of getting the size of the output
|
||||
printf("Compressed size is: %lu\n", strlen(b));
|
||||
printf("Compressed string is: %s\n", b);
|
||||
printf("\n----------\n\n");
|
||||
// STEP 2.
|
||||
// inflate b into c
|
||||
// zlib struct
|
||||
z_stream infstream;
|
||||
infstream.zalloc = Z_NULL;
|
||||
infstream.zfree = Z_NULL;
|
||||
infstream.opaque = Z_NULL;
|
||||
// setup "b" as the input and "c" as the compressed output
|
||||
// TOTHINK: Here we can add additional step from Right operand to z_stream variable access
|
||||
infstream.avail_in = (uInt) ((char *) defstream.next_out - b); // size of input
|
||||
infstream.next_in = (Bytef *) b; // input char array
|
||||
infstream.avail_out = (uInt) sizeof(c); // size of output
|
||||
infstream.next_out = (Bytef *) c; // output char array
|
||||
|
||||
// uLong total_out; /* total number of bytes output so far */
|
||||
// the actual DE-compression work.
|
||||
inflateInit(&infstream);
|
||||
std::cout << infstream.total_out << std::endl;
|
||||
inflate(&infstream, Z_NO_FLUSH);
|
||||
std::cout << infstream.total_out << std::endl;
|
||||
inflateEnd(&infstream);
|
||||
|
||||
printf("Uncompressed size is: %lu\n", strlen(c));
|
||||
printf("Uncompressed string is: %s\n", c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UnsafeGzread() {
|
||||
std::cout << "enter compressed file name!\n" << std::endl;
|
||||
char fileName[100];
|
||||
std::cin >> fileName;
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
if (inFileZ == nullptr) {
|
||||
printf("Error: Failed to gzopen %s\n", fileName);
|
||||
exit(0);
|
||||
}
|
||||
unsigned char unzipBuffer[8192];
|
||||
unsigned int unzippedBytes;
|
||||
std::vector<unsigned char> unzippedData;
|
||||
while (true) {
|
||||
unzippedBytes = gzread(inFileZ, unzipBuffer, 8192);
|
||||
if (unzippedBytes > 0) {
|
||||
unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto &&i: unzippedData)
|
||||
std::cout << i;
|
||||
gzclose(inFileZ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UnsafeGzfread() {
|
||||
std::cout << "enter compressed file name!\n" << std::endl;
|
||||
char fileName[100];
|
||||
std::cin >> fileName;
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
if (inFileZ == nullptr) {
|
||||
printf("Error: Failed to gzopen %s\n", fileName);
|
||||
exit(0);
|
||||
}
|
||||
while (true) {
|
||||
char buffer[1000];
|
||||
if (!gzfread(buffer, 999, 1, inFileZ)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
gzclose(inFileZ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UnsafeGzgets() {
|
||||
std::cout << "enter compressed file name!\n" << std::endl;
|
||||
char fileName[100];
|
||||
std::cin >> fileName;
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
if (inFileZ == nullptr) {
|
||||
printf("Error: Failed to gzopen %s\n", fileName);
|
||||
exit(0);
|
||||
}
|
||||
char *buffer = new char[4000000000];
|
||||
char *result = gzgets(inFileZ, buffer, 1000000000);
|
||||
while (true) {
|
||||
result = gzgets(inFileZ, buffer, 1000000000);
|
||||
if (result == nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "zlib.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
int SafeGzread() {
|
||||
std::cout << "enter compressed file name!\n" << std::endl;
|
||||
char fileName[100];
|
||||
std::cin >> fileName;
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
if (inFileZ == nullptr) {
|
||||
printf("Error: Failed to gzopen %s\n", fileName);
|
||||
exit(0);
|
||||
}
|
||||
unsigned char unzipBuffer[8192];
|
||||
unsigned int unzippedBytes;
|
||||
uint totalRead = 0;
|
||||
std::vector<unsigned char> unzippedData;
|
||||
while (true) {
|
||||
unzippedBytes = gzread(inFileZ, unzipBuffer, 8192);
|
||||
totalRead += unzippedBytes;
|
||||
if (unzippedBytes > 0) {
|
||||
unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
|
||||
if (totalRead > 1024 * 1024 * 4) {
|
||||
std::cout << "Bombs!" << totalRead;
|
||||
exit(1);
|
||||
} else {
|
||||
std::cout << "not Bomb yet!!" << totalRead << std::endl;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&i: unzippedData)
|
||||
std::cout << i;
|
||||
gzclose(inFileZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SafeGzread2() {
|
||||
std::cout << "enter compressed file name!\n" << std::endl;
|
||||
char fileName[100];
|
||||
std::cin >> fileName;
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
if (inFileZ == nullptr) {
|
||||
printf("Error: Failed to gzopen %s\n", fileName);
|
||||
exit(0);
|
||||
}
|
||||
const int BUFFER_SIZE = 8192;
|
||||
unsigned char unzipBuffer[BUFFER_SIZE];
|
||||
unsigned int unzippedBytes;
|
||||
uint totalRead = 0;
|
||||
std::vector<unsigned char> unzippedData;
|
||||
while (true) {
|
||||
unzippedBytes = gzread(inFileZ, unzipBuffer, BUFFER_SIZE);
|
||||
totalRead += BUFFER_SIZE;
|
||||
if (unzippedBytes > 0) {
|
||||
unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
|
||||
if (totalRead > 1024 * 1024 * 4) {
|
||||
std::cout << "Bombs!" << totalRead;
|
||||
exit(1);
|
||||
} else {
|
||||
std::cout << "not Bomb yet!!" << totalRead << std::endl;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&i: unzippedData)
|
||||
std::cout << i;
|
||||
gzclose(inFileZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user