-
Notifications
You must be signed in to change notification settings - Fork 1.7k
JS: Decompression Bombs #13554
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
JS: Decompression Bombs #13554
Conversation
QHelp previews: javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qhelperrors/warnings:
|
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/Bombs_zlib-Pako-AdmZip.ql
Fixed
Show fixed
Hide fixed
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/Bombs_node-tar.ql
Fixed
Show fixed
Hide fixed
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/Bombs_zlib-Pako-AdmZip.ql
Fixed
Show fixed
Hide fixed
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/sequelizeModelTypes.qll
Fixed
Show fixed
Hide fixed
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/CommandLineSource.qll
Fixed
Show fixed
Hide fixed
QHelp previews: javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qhelperrors/warnings:
|
QHelp previews: javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qhelpUser-controlled file decompressionExtracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks. Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file. RecommendationWhen 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. ExampleJsZip: check uncompressedSize Object Field before extraction. const jszipp = require("jszip");
function zipBombSafe(zipFile) {
jszipp.loadAsync(zipFile.data).then(function (zip) {
if (zip.file("10GB")["_data"]["uncompressedSize"] > 1024 * 1024 * 8) {
console.log("error")
}
zip.file("10GB").async("uint8array").then(function (u8) {
console.log(u8);
});
});
} nodejs Zlib: use maxOutputLength option which it'll limit the buffer read size const zlib = require("zlib");
zlib.gunzip(
inputZipFile.data,
{ maxOutputLength: 1024 * 1024 * 5 },
(err, buffer) => {
doSomeThingWithData(buffer);
});
zlib.gunzipSync(inputZipFile.data, { maxOutputLength: 1024 * 1024 * 5 });
inputZipFile.pipe(zlib.createGunzip({ maxOutputLength: 1024 * 1024 * 5 })).pipe(outputFile); node-tar: use maxReadSize option which it'll limit the buffer read size const tar = require("tar");
tar.x({
file: tarFileName,
strip: 1,
C: 'some-dir',
maxReadSize: 16 * 1024 * 1024 // 16 MB
}) References
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @amammad 👋
Thanks for the many submissions. I haven't had a chance to review the impact, but it certainly seems very valuable to have these queries.
Before we get into language-specific reviews, there are a few recurring technical issues with the PRs:
- There seem to be some accidental file deletions/modifications of random unrelated files in the repo. Please undo those changes.
- Ensure the
.qhelp
file has the same name as the corresponding.ql
file. Otherwise it just doesn't work and the PR can't be merged. - Stick to one query per language.
- The JS PR contains one query per library. They will need to be merged into one query.
- The Ruby PR has two variants of the query. Please pick one of them to keep.
If you could address the above for all the PRs that would be help the review process a lot.
Lastly, once the above has been addressed, it would be great if you could mention when you think the PR is ready for review, at which point you should stop pushing new changes, unless in response to a review comment. It makes reviews very hard when new changes keep coming in.
javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.qhelp
Outdated
Show resolved
Hide resolved
javascript/ql/test/experimental/Security/CWE-094/UntrustedCheckout.qlref
Outdated
Show resolved
Hide resolved
Hi @asgerf |
Hi, I've completed the work on this query and I don't have any further updates/commits here. |
…le for Readable Streams, BusBoy RemoteFlowSources is covering more sources now!, modularize
javascript/ql/src/Security/CWE-400/DeepObjectResourceExhaustion.expected
Outdated
Show resolved
Hide resolved
javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qll
Fixed
Show fixed
Hide fixed
*/ | ||
|
||
import javascript | ||
import DataFlow::PathGraph |
Check warning
Code scanning / CodeQL
Redundant import
@@ -0,0 +1,432 @@ | |||
import javascript | |||
import experimental.semmle.javascript.FormParsers | |||
import experimental.semmle.javascript.ReadableStream |
Check warning
Code scanning / CodeQL
Redundant import
Hi @asgerf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this targets files exclusively within experimental, I'm going to merge without substantial review.
Thanks for your contribution, and apologies for the long wait.
Thank you a lot for approving this PR and developing and improving the CodeQL every day :) |
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.
I've added sanitizers as much as I could find safe ways of using methods of each library in their documentation.
I also added some additional taint steps which I think it is good to consider them as global steps too.
I tried my best to cover Command line flow sources as much as possible which can be used in other existing query too.
One interesting thing is that during finding CVEs for this submission I found out that there are some second level Remote flow sources like a situation that users upload their files and then get the file ID in one endpoint and their web app client will send another request containing this file ID to a second endpoint. the second endpoint mostly need a additional taint steps to work, one of these steps is Sequelize library Model. these additional steps are like second level Remote flow sources which is come after first level ones.