【代码审计】文件读取下载JavaWeb工程

0x00 版权声明

JAVA基础系列是笔者学习@炼石星球的笔记,大部分文字描述取自星球内发布的教程文件,仅作学习。

0x02 FileRead&Download

首先创建SpringInitializr项目,JAVA版本选择8,其他默认,选择名称,选择Spring Web依赖,等待项目加载完成。

在pom.xml引入Commons-Io依赖:

1
2
3
4
5
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>

在src.main.java.com.example.webreadfile下新建ReadFileController.class文件,键入代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package com.example.webreadfile;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Scanner;

@Controller
@ResponseBody
public class ReadFileController {

@RequestMapping("/readUsingFiles")
public String readUsingFiles(String fileName, HttpServletResponse response) throws IOException {
//使用Java 7中的Files类处理小文件,获取完整的文件数据
Path path = Paths.get(fileName);
//将文件读取到字节数组
byte[] bytes = Files.readAllBytes(path);
System.out.println("使用File类读取文件.........");
@SuppressWarnings("unused")
List<String> allLines = Files.readAllLines(path, StandardCharsets.UTF_8);
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
System.out.println(new String(bytes));
return new String(bytes);
}
@RequestMapping("/readUsingFileReader")
public void readUsingFileReader(String fileName, HttpServletResponse response) throws IOException {
//使用FileReader读取,没有编码支持,效率不高
File file = new File(fileName);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line;
System.out.println("使用FileReader读取文本文件......");
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
PrintWriter out = response.getWriter();
while ((line = br.readLine()) != null) {
//逐行读取
System.out.println(line);
out.print(line);
}
br.close();
fr.close();
}
@RequestMapping("/ReadBufferedReader")
public void readBufferedReader(String fileName, HttpServletResponse response) throws IOException{
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
String line;
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
PrintWriter out = response.getWriter();
System.out.println("使用BufferedReader读取文本文件......");
while((line = br.readLine()) != null){
//逐行读取
System.out.println(line);
out.print(line);
}
br.close();
}
@RequestMapping("/readScanner")
public void readScanner(String fileName, HttpServletResponse response) throws IOException{
Path path = Paths.get(fileName);
Scanner scanner = new Scanner(path);
System.out.println("使用Scanner读取文本文件.....");
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
PrintWriter out = response.getWriter();
//逐行读取
while(scanner.hasNextLine()){
//逐行处理
String line = scanner.nextLine();
System.out.println(line);
out.print(line);
}
scanner.close();
}
@RequestMapping("/readUsingRandomAccessFile")
public void readUsingRandomAccessFile(String fileName, HttpServletResponse response) throws IOException{
RandomAccessFile file = new RandomAccessFile(fileName, "r");
String str;
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
PrintWriter out = response.getWriter();
while ((str = file.readLine()) != null) {
System.out.println("使用RandomAccessFile来实现断点续传读取/下载 文件......");
System.out.println(str);
out.print(str);
}
file.close();
}
@RequestMapping("/readUsingCommonsIo")
public String readUsingCommonsIo(String fileName,HttpServletResponse response) throws IOException{
File file = new File(fileName);
//将注释去掉,重新运行启动项目,在浏览器键入要读取的文件地址,观察下效果有什么不一样。
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
System.out.println("使用Commons-io读取文件......");
System.out.println(FileUtils.readFileToString(file, StandardCharsets.UTF_8));
return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}
}

运行项目,浏览器访问:

1
<http://127.0.0.1:8080/readUsingCommonsIo?fileName=C:/Users/admins/Desktop/test.txt>

https://zebpic-1301715962.cos.ap-nanjing.myqcloud.com/blog/202210111410345.png

也可以访问不同的读取接口访问:

1
2
3
http://127.0.0.1:8080/readUsingFiles?fileName=C:/Users/admins/Desktop/test.txt

http://127.0.0.1:8080/readUsingRandomAccessFile?fileName=C:/Users/admins/Desktop/test.txt