mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
C#: ZipSlip - Update help, compile and test samples.
This commit is contained in:
@@ -5,15 +5,16 @@
|
|||||||
<overview>
|
<overview>
|
||||||
<p>Extracting files from a malicious zip archive without validating that the destination file path
|
<p>Extracting files from a malicious zip archive without validating that the destination file path
|
||||||
is within the destination directory can cause files outside the destination directory to be
|
is within the destination directory can cause files outside the destination directory to be
|
||||||
overwritten, due to the possible presence of directory traversal elements ("..") in archive
|
overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in
|
||||||
paths.</p>
|
archive paths.</p>
|
||||||
|
|
||||||
<p>Zip archives contain archive entries representing each file in the archive. These entries
|
<p>Zip archives contain archive entries representing each file in the archive. These entries
|
||||||
include a file path for the entry, but these file paths are not restricted and may contain
|
include a file path for the entry, but these file paths are not restricted and may contain
|
||||||
unexpected special elements such as the directory traversal element (".."). If these file paths are
|
unexpected special elements such as the directory traversal element (<code>..</code>). If these
|
||||||
use to determine an output file to write the contents of the archive item to, then the file may be
|
file paths are used to determine an output file to write the contents of the archive item to, then
|
||||||
written to an unexpected location. This can result in sensitive information being revealed or
|
the file may be written to an unexpected location. This can result in sensitive information being
|
||||||
deleted, or an attacker being able to influence behavior by modifying unexpected files.</p>
|
revealed or deleted, or an attacker being able to influence behavior by modifying unexpected
|
||||||
|
files.</p>
|
||||||
|
|
||||||
<p>For example, if a zip file contains a file entry <code>..\sneaky-file</code>, and the zip file
|
<p>For example, if a zip file contains a file entry <code>..\sneaky-file</code>, and the zip file
|
||||||
is extracted to the directory <code>c:\output</code>, then naively combining the paths would result
|
is extracted to the directory <code>c:\output</code>, then naively combining the paths would result
|
||||||
@@ -50,7 +51,7 @@ the result is within the destination directory. If provided with a zip file cont
|
|||||||
path like <code>..\sneaky-file</code>, then this file would be written outside of the destination
|
path like <code>..\sneaky-file</code>, then this file would be written outside of the destination
|
||||||
directory.</p>
|
directory.</p>
|
||||||
|
|
||||||
<sample src="ZipSlipBroken.cs" />
|
<sample src="ZipSlipBad.cs" />
|
||||||
|
|
||||||
<p>In order to fix this vulnerability, we need to make three changes. Firstly, we need to resolve any
|
<p>In order to fix this vulnerability, we need to make three changes. Firstly, we need to resolve any
|
||||||
directory traversal or other special characters in the path by using <code>Path.GetFullPath</code>.
|
directory traversal or other special characters in the path by using <code>Path.GetFullPath</code>.
|
||||||
@@ -59,7 +60,7 @@ Secondly, we need to identify the destination output directory, again using
|
|||||||
the resolved output starts with the resolved destination directory, and throw and exception if this
|
the resolved output starts with the resolved destination directory, and throw and exception if this
|
||||||
is not the case.</p>
|
is not the case.</p>
|
||||||
|
|
||||||
<sample src="ZipSlipFixed.cs" />
|
<sample src="ZipSlipGood.cs" />
|
||||||
|
|
||||||
</example>
|
</example>
|
||||||
<references>
|
<references>
|
||||||
|
|||||||
12
csharp/ql/src/Security Features/CWE-022/ZipSlipBad.cs
Normal file
12
csharp/ql/src/Security Features/CWE-022/ZipSlipBad.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
class Bad
|
||||||
|
{
|
||||||
|
public static void WriteToDirectory(ZipArchiveEntry entry,
|
||||||
|
string destDirectory)
|
||||||
|
{
|
||||||
|
string destFileName = Path.Combine(destDirectory, entry.FullName);
|
||||||
|
entry.ExtractToFile(destFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
public static void WriteToDirectory(IArchiveEntry entry,
|
|
||||||
string destDirectory,
|
|
||||||
ExtractionOptions options){
|
|
||||||
string file = Path.GetFileName(entry.Key);
|
|
||||||
string destFileName = Path.Combine(destDirectory, file);
|
|
||||||
entry.WriteToFile(destFileName, options);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
public static void WriteToDirectory(IArchiveEntry entry,
|
|
||||||
string destDirectory,
|
|
||||||
ExtractionOptions options){
|
|
||||||
string file = Path.GetFileName(entry.Key);
|
|
||||||
string destFileName = Path.GetFullPath(Path.Combine(destDirecory, entry.Key));
|
|
||||||
string fullDestDirPath = Path.GetFullPath(destDirectory + Path.DirectorySeparatorChar);
|
|
||||||
if (!destFileName.StartsWith(fullDestDirPath)) {
|
|
||||||
throw new ExtractionException("Entry is outside of the target dir: " + destFileName);
|
|
||||||
}
|
|
||||||
entry.WriteToFile(destFileName, options);
|
|
||||||
}
|
|
||||||
17
csharp/ql/src/Security Features/CWE-022/ZipSlipGood.cs
Normal file
17
csharp/ql/src/Security Features/CWE-022/ZipSlipGood.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
class Good
|
||||||
|
{
|
||||||
|
public static void WriteToDirectory(ZipArchiveEntry entry,
|
||||||
|
string destDirectory)
|
||||||
|
{
|
||||||
|
string destFileName = Path.GetFullPath(Path.Combine(destDirectory, entry.FullName));
|
||||||
|
string fullDestDirPath = Path.GetFullPath(destDirectory + Path.DirectorySeparatorChar);
|
||||||
|
if (!destFileName.StartsWith(fullDestDirPath)) {
|
||||||
|
throw new System.InvalidOperationException("Entry is outside of the target dir: " +
|
||||||
|
destFileName);
|
||||||
|
}
|
||||||
|
entry.ExtractToFile(destFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,3 +4,4 @@
|
|||||||
| ZipSlip.cs:68:71:68:82 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
| ZipSlip.cs:68:71:68:82 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
||||||
| ZipSlip.cs:75:57:75:68 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
| ZipSlip.cs:75:57:75:68 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
||||||
| ZipSlip.cs:83:58:83:69 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
| ZipSlip.cs:83:58:83:69 | access to local variable destFilePath | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlip.cs:54:72:54:85 | access to property FullName | item path |
|
||||||
|
| ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | Unsanitized zip archive $@ which may contain '..' used in a file system operation. | ZipSlipBad.cs:9:59:9:72 | access to property FullName | item path |
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
class Bad
|
||||||
|
{
|
||||||
|
public static void WriteToDirectory(ZipArchiveEntry entry,
|
||||||
|
string destDirectory)
|
||||||
|
{
|
||||||
|
string destFileName = Path.Combine(destDirectory, entry.FullName);
|
||||||
|
entry.ExtractToFile(destFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
class Good
|
||||||
|
{
|
||||||
|
public static void WriteToDirectory(ZipArchiveEntry entry,
|
||||||
|
string destDirectory)
|
||||||
|
{
|
||||||
|
string destFileName = Path.GetFullPath(Path.Combine(destDirectory, entry.FullName));
|
||||||
|
string fullDestDirPath = Path.GetFullPath(destDirectory + Path.DirectorySeparatorChar);
|
||||||
|
if (!destFileName.StartsWith(fullDestDirPath)) {
|
||||||
|
throw new System.InvalidOperationException("Entry is outside of the target dir: " +
|
||||||
|
destFileName);
|
||||||
|
}
|
||||||
|
entry.ExtractToFile(destFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user