Skip to content

Commit ceea475

Browse files
committed
add new s3 and spring IO path injection sinks
1 parent 5fa1b57 commit ceea475

File tree

7 files changed

+405
-0
lines changed

7 files changed

+405
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/java-all
4+
extensible: experimentalSinkModel
5+
data:
6+
- ["software.amazon.awssdk.transfer.s3.model","ResumableFileUpload",true,"serializeToFile","(Path)","","Argument[0]","path-injection","manual"]
7+
- ["software.amazon.awssdk.transfer.s3.model","DownloadFileRequest$Builder",true,"destination","(Path)","","Argument[0]","path-injection","manual"]
8+
- ["software.amazon.awssdk.transfer.s3.model","UploadFileRequest$Builder",true,"source","(Path)","","Argument[0]","path-injection","manual"]
9+
- ["software.amazon.awssdk.transfer.s3.model","DownloadDirectoryRequest$Builder",true,"destination","(Path)","","Argument[0]","path-injection","manual"]
10+
- ["software.amazon.awssdk.transfer.s3.model","ResumableFileDownload",true,"fromFile","(Path)","","Argument[0]","path-injection","manual"]
11+
- ["software.amazon.awssdk.transfer.s3.model","ResumableFileDownload",true,"serializeToFile","(Path)","","Argument[0]","path-injection","manual"]
12+
- ["software.amazon.awssdk.transfer.s3.model","ResumableFileUpload",true,"fromFile","(Path)","","Argument[0]","path-injection","manual"]
13+
- ["software.amazon.awssdk.transfer.s3.model","UploadDirectoryRequest$Builder",true,"source","(Path)","","Argument[0]","code-injection","manual"]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/java-all
4+
extensible: experimentalSinkModel
5+
data:
6+
- ["org.springframework.core.io","FileSystemResource",true,"FileSystemResource","(FileSystem,String)","","Argument[1]","path-injection","manual"]
7+
- ["org.springframework.core.io","FileSystemResource",true,"FileSystemResource","(File)","","Argument[0]","path-injection","manual"]
8+
- ["org.springframework.core.io","FileSystemResource",true,"FileSystemResource","(Path)","","Argument[0]","path-injection","manual"]
9+
- ["org.springframework.core.io","FileSystemResource",true,"FileSystemResource","(String)","","Argument[0]","path-injection","manual"]
10+
- ["org.springframework.core.io","FileUrlResource",true,"FileUrlResource","(String)","","Argument[0]","path-injection","manual"]
11+
- ["org.springframework.core.io","FileUrlResource",true,"FileUrlResource","(URL)","","Argument[0]","path-injection","manual"]
12+
- ["org.springframework.core.io","PathResource",true,"PathResource","(Path)","","Argument[0]","path-injection","manual"]
13+
- ["org.springframework.core.io","PathResource",true,"PathResource","(String)","","Argument[0]","path-injection","manual"]
14+
- ["org.springframework.core.io","PathResource",true,"PathResource","(URI)","","Argument[0]","path-injection","manual"]
15+
- ["org.springframework.core.io","UrlResource",true,"UrlResource","(String,String,String)","","Argument[1]","path-injection","manual"]
16+
- ["org.springframework.core.io","UrlResource",true,"UrlResource","(String,String)","","Argument[1]","path-injection","manual"]
17+
- ["org.springframework.core.io","UrlResource",true,"UrlResource","(String)","","Argument[0]","path-injection","manual"]
18+
- ["org.springframework.core.io","UrlResource",true,"UrlResource","(URI)","","Argument[0]","path-injection","manual"]
19+
- ["org.springframework.core.io","UrlResource",true,"UrlResource","(URL)","","Argument[0]","path-injection","manual"]
20+
- ["org.springframework.util","FileSystemUtils",true,"copyRecursively","(Path,Path)","","Argument[0]","path-injection","manual"]
21+
- ["org.springframework.util","FileSystemUtils",true,"copyRecursively","(Path,Path)","","Argument[1]","path-injection","manual"]
22+
- ["org.springframework.util","FileSystemUtils",true,"deleteRecursively","(File)","","Argument[0]","path-injection","manual"]
23+
- ["org.springframework.util","FileSystemUtils",true,"deleteRecursively","(Path)","","Argument[0]","path-injection","manual"]
24+
- ["org.springframework.util","ResourceUtils",true,"getFile","(String)","","Argument[0]","path-injection","manual"]
25+
- ["org.springframework.util","FileCopyUtils",true,"copyToByteArray","(File)","","Argument[0]","path-injection","manual"]
26+
- ["org.springframework.util","FileCopyUtils",true,"copyToString","(Reader)","","Argument[0]","path-injection","manual"]
27+
- ["org.springframework.util","FileSystemUtils",true,"copyRecursively","(File,File)","","Argument[0]","path-injection","manual"]
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>org.PathInjection</groupId>
5+
<artifactId>PathInjection</artifactId>
6+
<packaging>war</packaging>
7+
<version>1.0-SNAPSHOT</version>
8+
<name>PathInjection Maven Webapp</name>
9+
<url>https://maven.apache.org</url>
10+
11+
<properties>
12+
<aws.sdk.version>2.19.1</aws.sdk.version>
13+
</properties>
14+
15+
<dependencyManagement>
16+
<dependencies>
17+
<dependency>
18+
<groupId>software.amazon.awssdk</groupId>
19+
<artifactId>bom</artifactId>
20+
<version>${aws.sdk.version}</version>
21+
<type>pom</type>
22+
<scope>import</scope>
23+
</dependency>
24+
</dependencies>
25+
</dependencyManagement>
26+
<dependencies>
27+
<dependency>
28+
<groupId>javax.servlet</groupId>
29+
<artifactId>javax.servlet-api</artifactId>
30+
<version>4.0.1</version>
31+
<scope>provided</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.springframework</groupId>
35+
<artifactId>spring-framework-bom</artifactId>
36+
<version>6.1.4</version>
37+
<scope>import</scope>
38+
<type>pom</type>
39+
</dependency>
40+
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
41+
<dependency>
42+
<groupId>org.springframework</groupId>
43+
<artifactId>spring-core</artifactId>
44+
<version>6.1.4</version>
45+
</dependency>
46+
<dependency>
47+
<groupId>software.amazon.awssdk</groupId>
48+
<artifactId>s3-transfer-manager</artifactId>
49+
</dependency>
50+
<dependency>
51+
<groupId>software.amazon.awssdk.crt</groupId>
52+
<artifactId>aws-crt</artifactId>
53+
<version>0.20.3</version>
54+
</dependency>
55+
<dependency>
56+
<groupId>commons-io</groupId>
57+
<artifactId>commons-io</artifactId>
58+
<version>2.12.0</version>
59+
</dependency>
60+
<!-- https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j -->
61+
<dependency>
62+
<groupId>net.lingala.zip4j</groupId>
63+
<artifactId>zip4j</artifactId>
64+
<version>2.11.5</version>
65+
</dependency>
66+
<!-- https://mvnrepository.com/artifact/com.github.luben/zstd-jni -->
67+
<dependency>
68+
<groupId>com.github.luben</groupId>
69+
<artifactId>zstd-jni</artifactId>
70+
<version>1.5.5-1</version>
71+
</dependency>
72+
<!-- https://mvnrepository.com/artifact/org.tukaani/xz -->
73+
<dependency>
74+
<groupId>org.tukaani</groupId>
75+
<artifactId>xz</artifactId>
76+
<version>1.9</version>
77+
</dependency>
78+
<!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
79+
<dependency>
80+
<groupId>org.lz4</groupId>
81+
<artifactId>lz4-java</artifactId>
82+
<version>1.8.0</version>
83+
</dependency>
84+
<!-- https://mvnrepository.com/artifact/org.xerial.snappy/snappy-java -->
85+
<dependency>
86+
<groupId>org.xerial.snappy</groupId>
87+
<artifactId>snappy-java</artifactId>
88+
<version>1.1.10.5</version>
89+
</dependency>
90+
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
91+
<dependency>
92+
<groupId>org.apache.commons</groupId>
93+
<artifactId>commons-compress</artifactId>
94+
<version>1.26.0</version>
95+
</dependency>
96+
</dependencies>
97+
<build>
98+
<finalName>PathInjection</finalName>
99+
<plugins>
100+
<plugin>
101+
<groupId>org.apache.maven.plugins</groupId>
102+
<artifactId>maven-compiler-plugin</artifactId>
103+
<configuration>
104+
<source>11</source>
105+
<target>11</target>
106+
</configuration>
107+
</plugin>
108+
</plugins>
109+
</build>
110+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.PathInjection;
2+
3+
import java.io.*;
4+
import java.nio.channels.AsynchronousFileChannel;
5+
import java.nio.file.*;
6+
import java.nio.file.attribute.FileAttribute;
7+
import java.util.Set;
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.Executors;
10+
11+
class fileAttr implements FileAttribute<String> {
12+
public String name() {
13+
return "file";
14+
}
15+
16+
public String value() {
17+
return "value";
18+
}
19+
}
20+
21+
public class CommonsIOPathInjection {
22+
public void PathInjection(Path src, File srcF) throws IOException {
23+
AsynchronousFileChannel.open(src); // $ PathInjection
24+
AsynchronousFileChannel.open(src, LinkOption.NOFOLLOW_LINKS); // $ PathInjection
25+
AsynchronousFileChannel.open(
26+
src, LinkOption.NOFOLLOW_LINKS, LinkOption.NOFOLLOW_LINKS); // $ PathInjection
27+
ExecutorService executor = Executors.newFixedThreadPool(10);
28+
AsynchronousFileChannel.open(
29+
src, Set.of(LinkOption.NOFOLLOW_LINKS), executor); // $ PathInjection
30+
AsynchronousFileChannel.open(
31+
src, // $ PathInjection
32+
Set.of(LinkOption.NOFOLLOW_LINKS),
33+
executor,
34+
new fileAttr());
35+
36+
FileSystems.getFileSystem(srcF.toURI()); // $ PathInjection
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.PathInjection;
2+
3+
import java.io.*;
4+
import java.io.IOException;
5+
import java.net.URISyntaxException;
6+
import java.nio.file.Path;
7+
import javax.servlet.annotation.MultipartConfig;
8+
import javax.servlet.annotation.WebServlet;
9+
import javax.servlet.http.HttpServlet;
10+
import javax.servlet.http.HttpServletRequest;
11+
import javax.servlet.http.HttpServletResponse;
12+
13+
import net.lingala.zip4j.ZipFile;
14+
15+
@WebServlet(
16+
name = "helloServlet",
17+
urlPatterns = {"/hello"})
18+
@MultipartConfig()
19+
public class HelloServlet extends HttpServlet {
20+
21+
public void init() {}
22+
23+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
24+
String path = request.getParameter("path");
25+
Path src = Path.of(path);
26+
File srcF = new File(path);
27+
new CommonsIOPathInjection().PathInjection(src, srcF);
28+
new SpringIoPathInjection().PathInjection(path);
29+
S3PathInjection s3PathInjection = new S3PathInjection();
30+
s3PathInjection.downloadFileResumable(src.toUri());
31+
s3PathInjection.downloadFile(path);
32+
s3PathInjection.downloadObjectsToDirectory(src.toUri());
33+
s3PathInjection.uploadFileResumable(src.toUri());
34+
s3PathInjection.uploadDirectory(src.toUri());
35+
s3PathInjection.uploadFile(src.toUri());
36+
37+
ZipFile zipfile = new ZipFile(path);
38+
zipfile.extractAll(path);
39+
new java.util.zip.ZipFile(path);
40+
41+
PrintWriter out = response.getWriter();
42+
response.setContentType("text/html");
43+
out.println("<html><body>end</body></html>");
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.PathInjection;
2+
3+
import software.amazon.awssdk.transfer.s3.S3TransferManager;
4+
import software.amazon.awssdk.transfer.s3.model.*;
5+
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
6+
7+
import java.net.MalformedURLException;
8+
import java.net.URI;
9+
import java.net.URISyntaxException;
10+
import java.nio.file.Paths;
11+
12+
public class S3PathInjection {
13+
S3TransferManager transferManager = S3TransferManager.create();
14+
String bucketName = "bucketTest";
15+
String key = "keyTest";
16+
17+
public String uploadFile(URI filePathURI) {
18+
UploadFileRequest uploadFileRequest =
19+
UploadFileRequest.builder()
20+
.putObjectRequest(b -> b.bucket(this.bucketName).key(this.key))
21+
.addTransferListener(LoggingTransferListener.create())
22+
.source(Paths.get(filePathURI)) // $ PathInjection
23+
.build();
24+
25+
FileUpload fileUpload = this.transferManager.uploadFile(uploadFileRequest);
26+
27+
CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
28+
return uploadResult.response().eTag();
29+
}
30+
31+
public String uploadFileResumable(URI filePathURI) {
32+
UploadFileRequest uploadFileRequest =
33+
UploadFileRequest.builder()
34+
.putObjectRequest(b -> b.bucket(this.bucketName).key(this.key))
35+
.addTransferListener(LoggingTransferListener.create())
36+
.source(Paths.get(filePathURI)) // $ PathInjection
37+
.build();
38+
39+
// Initiate the transfer
40+
FileUpload upload = this.transferManager.uploadFile(uploadFileRequest);
41+
// Pause the upload
42+
ResumableFileUpload resumableFileUpload = upload.pause();
43+
// Optionally, persist the resumableFileUpload
44+
resumableFileUpload.serializeToFile(Paths.get(filePathURI)); // $ PathInjection
45+
// Retrieve the resumableFileUpload from the file
46+
ResumableFileUpload persistedResumableFileUpload =
47+
ResumableFileUpload.fromFile(Paths.get(filePathURI)); // $ PathInjection
48+
// Resume the upload
49+
FileUpload resumedUpload = this.transferManager.resumeUploadFile(persistedResumableFileUpload);
50+
// Wait for the transfer to complete
51+
resumedUpload.completionFuture().join();
52+
FileUpload fileUpload = this.transferManager.uploadFile(uploadFileRequest);
53+
CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
54+
return uploadResult.response().eTag();
55+
}
56+
57+
public String downloadFileResumable(URI downloadedFileWithPath) {
58+
DownloadFileRequest downloadFileRequest =
59+
DownloadFileRequest.builder()
60+
.getObjectRequest(b -> b.bucket(this.bucketName).key(this.key))
61+
.addTransferListener(LoggingTransferListener.create())
62+
.destination(Paths.get(downloadedFileWithPath)) // $ PathInjection
63+
.build();
64+
65+
// Initiate the transfer
66+
FileDownload download = this.transferManager.downloadFile(downloadFileRequest);
67+
// Pause the download
68+
ResumableFileDownload resumableFileDownload = download.pause();
69+
// Optionally, persist the resumableFileDownload
70+
resumableFileDownload.serializeToFile(Paths.get(downloadedFileWithPath)); // $ PathInjection
71+
// Retrieve the resumableFileDownload from the file
72+
ResumableFileDownload persistedResumableFileDownload =
73+
ResumableFileDownload.fromFile(Paths.get(downloadedFileWithPath)); // $ PathInjection
74+
// Resume the download
75+
FileDownload resumedDownload =
76+
this.transferManager.resumeDownloadFile(persistedResumableFileDownload);
77+
// Wait for the transfer to complete
78+
resumedDownload.completionFuture().join();
79+
FileDownload filedownload = this.transferManager.downloadFile(downloadFileRequest);
80+
CompletedFileDownload downloadResult = filedownload.completionFuture().join();
81+
return downloadResult.response().eTag();
82+
}
83+
84+
public Integer uploadDirectory(URI sourceDirectory) {
85+
DirectoryUpload directoryUpload =
86+
this.transferManager.uploadDirectory(
87+
UploadDirectoryRequest.builder()
88+
.source(Paths.get(sourceDirectory)) // $ PathInjection
89+
.bucket(this.bucketName)
90+
.build());
91+
92+
CompletedDirectoryUpload completedDirectoryUpload = directoryUpload.completionFuture().join();
93+
return completedDirectoryUpload.failedTransfers().size();
94+
}
95+
96+
public Long downloadFile(String downloadedFileWithPath) {
97+
DownloadFileRequest downloadFileRequest =
98+
DownloadFileRequest.builder()
99+
.getObjectRequest(b -> b.bucket(this.bucketName).key(this.key))
100+
.addTransferListener(LoggingTransferListener.create())
101+
.destination(Paths.get(downloadedFileWithPath)) // $ PathInjection
102+
.build();
103+
104+
FileDownload downloadFile = this.transferManager.downloadFile(downloadFileRequest);
105+
106+
CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
107+
return downloadResult.response().contentLength();
108+
}
109+
110+
public Integer downloadObjectsToDirectory(URI destinationPathURI) {
111+
DirectoryDownload directoryDownload =
112+
this.transferManager.downloadDirectory(
113+
DownloadDirectoryRequest.builder()
114+
.destination(Paths.get(destinationPathURI)) // $ PathInjection
115+
.bucket(this.bucketName)
116+
.build());
117+
CompletedDirectoryDownload completedDirectoryDownload =
118+
directoryDownload.completionFuture().join();
119+
120+
return completedDirectoryDownload.failedTransfers().size();
121+
}
122+
}

0 commit comments

Comments
 (0)