Skip to content

Commit 38ac10b

Browse files
committed
Unrestricted File Upload with Java
1 parent 5e812e0 commit 38ac10b

File tree

26 files changed

+1230
-4
lines changed

26 files changed

+1230
-4
lines changed

.github/workflows/java-ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
env:
1212
working-directory-fileupload: "./Path Manipulation/while File Upload/java/fileupload.pathmanipulation"
1313
working-directory-fileread: "./Path Manipulation/while File Read/java/fileread.pathmanipulation"
14+
working-directory-unrestricted-fileupload: "./Unrestriced File Upload/java"
1415

1516
steps:
1617
- name: Checkout code
@@ -30,10 +31,18 @@ jobs:
3031
working-directory: ${{ env.working-directory-fileread }}
3132
run: mvn clean -B package --file pom.xml
3233

34+
- name: Build with Maven for Unrestricted File Upload
35+
working-directory: ${{ working-directory-unrestricted-fileupload }}
36+
run: mvn clean -B package --file pom.xml
37+
3338
- name: Run tests for Path Manipulation while File Upload
3439
working-directory: ${{ env.working-directory-fileupload }}
3540
run: mvn test
3641

42+
- name: Run tests for Unrestricted File Upload
43+
working-directory: ${{ working-directory-unrestricted-fileupload }}
44+
run: mvn test
45+
3746
- name: Run tests for Path Manipulation while File Read
3847
working-directory: ${{ env.working-directory-fileread }}
3948
run: mvn test
@@ -44,4 +53,8 @@ jobs:
4453

4554
- name: Clean up for Path Manipulation while File Read
4655
working-directory: ${{ env.working-directory-fileread }}
56+
run: mvn clean
57+
58+
- name: Clean up for Unrestricted File Upload
59+
working-directory: ${{ working-directory-unrestricted-fileupload }}
4760
run: mvn clean

Path Manipulation/while File Read/java/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This maven project is to help to mitigate the path manipulation issues. You can
66

77
[HomeController](./fileread.pathmanipulation/src/main/java/securecodingexamples/fileread/pathmanipulation/HomeController.java) file serves the [index.html](./fileread.pathmanipulation/src/main/resources/templates/index.html) to serve as the Fronted for the File Upload.
88

9-
[UploadController.java](./fileread.pathmanipulation/src/main/java/securecodingexamples/fileread/pathmanipulation/DownloadController.java) file contains the logic for the file Upload and the Filename validation, Extension Validation during the File Upload.
9+
[DownloadController.java](./fileread.pathmanipulation/src/main/java/securecodingexamples/fileread/pathmanipulation/DownloadController.java) file contains the logic for the file Upload and the Filename validation, Extension Validation during the File Upload.
1010

1111
[resources/templates](./fileread.pathmanipulation/src/main/resources/templates/) Directory contains the index.html.
1212

@@ -25,7 +25,7 @@ cd 'Path Manipulation/while File Read/java/fileread.pathmanipulation'
2525

2626
**Windows:**
2727
```sh
28-
mvnw.cmd clean spring-boot:run
28+
./mvnw.cmd clean spring-boot:run
2929
```
3030
3. Open in Browser:
3131
```

Path Manipulation/while File Upload/java/fileupload.pathmanipulation/src/main/java/securecodingexamples/fileupload/pathmanipulation/UploadController.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) {
4242
}
4343

4444
String filename = file.getOriginalFilename();
45-
if (filename == null || !isValidName(filename)) {
45+
if (filename == null || filename.isEmpty() || !isValidName(filename)) {
4646
logger.warning("Invalid Filename");
4747
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Filename");
4848
}
4949

50-
if (filename == null || !isValidExtension(filename)) {
50+
if (filename == null || filename.isEmpty() || !isValidExtension(filename)) {
5151
logger.warning("Invalid File Extension");
5252
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Extension");
5353
}
@@ -67,6 +67,9 @@ public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) {
6767
} catch (IOException e) {
6868
logger.severe("File upload error: " + e.getMessage());
6969
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed");
70+
} catch (Exception e){
71+
logger.severe("File upload error: " + e.getMessage());
72+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed");
7073
}
7174
}
7275

Unrestriced File Upload/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Unrestricted File Upload
2+
3+
__Unrestricted File Upload__, as the name suggests, the file uploads are possible with minimal restrictions or no restrictions at all. When the developers don't put the File Upload Restrictions on the server-side code, the __attackers__ are able to upload __Malicious File__ with __Dangerous Types__, which can in turn result more severe issues.
4+
5+
## Mitigation
6+
7+
Unrestricted File Upload issues can be mitigated by putting Restrictions on everything possible for the file like __filename, file extensions, Content Type, Magic Numbers__.
8+
9+
The Unrestricted File Upload logic checks for the following:
10+
- The Filename Validation, to only contain Alphanumeric values with the help of regex.
11+
- The extension validation, to only allow files with certain extension.
12+
- Content Type validation, to only allow the files matching the content type for the allowed extensions with the help of magic numbers.
13+
- File size validation, to only allows files within the 5MB file size.
14+
- Same Filename validation, to only allow the unique files to be uploaded and not rewrite the existing file.
15+
16+
You can check the file signatures tables by visiting this [link](https://www.garykessler.net/library/file_sigs.html).
17+
18+
## Directory Structure for Path Manipulation
19+
```
20+
Unrestriced File Upload
21+
├───java
22+
│ ├───.mvn
23+
│ │ └───wrapper
24+
│ └───src
25+
│ ├───main
26+
│ │ ├───java
27+
│ │ │ └───securecodingexamples
28+
│ │ │ └───unrestricted
29+
│ │ │ └───fileupload
30+
│ │ └───resources
31+
│ │ └───static
32+
│ └───test
33+
│ └───java
34+
│ └───securecodingexamples
35+
│ └───fileupload
36+
│ └───pathmanipulation
37+
└───python
38+
└───securecodingexamples
39+
└───unrestricted
40+
└───fileupload
41+
└───src
42+
├───templates
43+
└───tests
44+
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
wrapperVersion=3.3.2
18+
distributionType=only-script
19+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Unrestricted File Upload
2+
3+
This maven project is to help to mitigate the Unrestricted File Upload issues. You can use the logic in the [UploadController.java](./src/main/java/securecodingexamples/unrestricted/fileupload/UploadController.java) in your local [Maven](https://maven.apache.org/), [Gradle](https://gradle.org/) or other Java Applications.
4+
5+
## Code Structure
6+
7+
[HomeController](./src/main/java/securecodingexamples/unrestricted/fileupload/HomeController.java) file serves the [index.html](./src/main/resources/static/index.html) to serve as the Fronted for the File Upload.
8+
9+
[UploadController.java](./src/main/java/securecodingexamples/unrestricted/fileupload/UploadController.java) file contains the logic for the file Upload and the Filename validation, Extension Validation during the File Upload.
10+
11+
[resources/static](./src/main/resources/static) Directory contains the index.html.
12+
13+
## Installation
14+
1. Clone the repository:
15+
```sh
16+
git clone https://github.com/sahildari/secure-coding-examples
17+
cd 'Unrestriced File Upload/java'
18+
```
19+
2. Install the package:
20+
21+
**MacOS/Linux:**
22+
```sh
23+
./mvnw clean spring-boot:run
24+
```
25+
26+
**Windows:**
27+
```sh
28+
mvnw.cmd clean spring-boot:run
29+
```
30+
3. Open in Browser:
31+
```
32+
http://127.0.0.1:8080
33+
```

0 commit comments

Comments
 (0)