Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Decompression Bombs #13560

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open

C++: Decompression Bombs #13560

wants to merge 20 commits into from

Conversation

am0o0
Copy link
Contributor

@am0o0 am0o0 commented Jun 25, 2023

This is part of All for one, one for all query submission, I'm going to submit an issue in github/securitylab for this pull request too.
this query will be upgraded more in this week whether in this pull request or in another pull request, currently I'm adding minizip, xz, bzip2, zstd, LZ4 related libraries.
I'm trying my best to add proper sanitizers too if there is any protection for each function as some functions are unsafe by default and can not be controlled during decompression.

@github-actions github-actions bot removed the C# label Jun 25, 2023
@am0o0
Copy link
Contributor Author

am0o0 commented Jun 25, 2023

Anyone not watching the repo in general, note this is part of a family of submissions:

#13553
#13554
#13555
#13556
#13557
#13558
#13560

@am0o0 am0o0 changed the title CPP: Decompression Bombs C++: Decompression Bombs Jun 25, 2023
@jketema jketema removed the request for review from a team June 25, 2023 12:47
@github-actions
Copy link
Contributor

QHelp previews:

cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp

errors/warnings:

A fatal error occurred: Failed to read path ./cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.ql
(eventual cause: NoSuchFileException "./cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.ql")

* The `gzopen` function as a Flow source
*/
private class GzopenFunction extends Function {
GzopenFunction() { hasGlobalName("gzopen") }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
* The `gzdopen` function as a Flow source
*/
private class GzdopenFunction extends Function {
GzdopenFunction() { hasGlobalName("gzdopen") }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
* The `gzfread` function is used in Flow sink
*/
private class GzfreadFunction extends Function {
GzfreadFunction() { hasGlobalName("gzfread") }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
* The `gzread` function is used in Flow sink
*/
private class GzreadFunction extends Function {
GzreadFunction() { hasGlobalName("gzread") }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
* The `inflate`/`inflateSync` function is used in Flow sink
*/
private class DeflateFunction extends Function {
DeflateFunction() { hasGlobalName(["inflate", "inflateSync"]) }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
* The `uncompress`/`uncompress2` function is used in Flow sink
*/
private class UncompressFunction extends Function {
UncompressFunction() { hasGlobalName(["uncompress", "uncompress2"]) }

Check warning

Code scanning / CodeQL

Using implicit `this` Warning

Use of implicit this.
@am0o0
Copy link
Contributor Author

am0o0 commented Jul 3, 2023

Hi, I've completed the work on this query and I don't have any further updates/commits here.

@ghsecuritylab ghsecuritylab marked this pull request as draft July 31, 2023 16:02
@am0o0
Copy link
Contributor Author

am0o0 commented Aug 10, 2023

Hi, currently for most of the libraries there are no sanitizers because I didn't know how can I set a limit on output buffer length for many of them, I think there is no way to control the output resource for some methods of these libs, the other problem is that being able to write proper sanitizer too which I succeeded to write one for gzread method. it seems that there must be sanitizers otherwise every usage of these decompression methods can be mark as vulnerable, however I think many of them are not checking the decompressed output size.
also as there are some void* as source in taint tracking config, I must find the longest path that the inner nodes of this path has not appeared in other paths as source. I got help from one of your colleges but I didn't implement this yet.

@Kwstubbs
Copy link
Contributor

@am0o0 how is this going? would you like me to open this PR to get the CodeQL team to look at it?

@am0o0
Copy link
Contributor Author

am0o0 commented May 24, 2024

@Kwstubbs yes, I can also open this PR if you can't.

@Kwstubbs
Copy link
Contributor

@am0o0 sounds good please do

@am0o0 am0o0 marked this pull request as ready for review May 24, 2024 06:42
@Kwstubbs
Copy link
Contributor

pinging @codeql-c-analysis query is ready for review.

Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments. I will need to make a second pass over this.

The query should be relocated to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409

The PR currently seems to be missing tests, which should be added to cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409. See the directories around there for examples of how to write tests.

Comment on lines 183 to 186
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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why will the examples from you example_good.cpp file not be flagged up by this query?

totalRead += BUFFER_SIZE;
if (unzippedBytes > 0) {
unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
if (totalRead > 1024 * 1024 * 4) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be interesting to add these examples as a test (in cpp/ql/test/experimental/query-tests/Security/CWE/...). I'm not clear how we intend to detect that a read limit such as this one is in place.

@am0o0
Copy link
Contributor Author

am0o0 commented Jun 25, 2024

@jketema this directory doesn't exist:

The query should be relocated to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409

@jketema
Copy link
Contributor

jketema commented Jun 25, 2024

@jketema this directory doesn't exist:

The query should be relocated to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409

Feel free to create it as part of this PR.

@am0o0
Copy link
Contributor Author

am0o0 commented Jun 26, 2024

Hi, as I don't have enough experience with C++ package/module systems, It takes some time to implement tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants