Comments (1)
感谢贡献!根据建议,1.2 文件操作
部分已做预修改,后续将统一更新至仓库。如有其他建议,欢迎重开问题讨论,我们将有专人跟进。
变动如下:
1.2 文件操作
文件操作涉及上传、下载和删除。代码中涉及这些操作时,首先必须保证用户输入不能产生路径穿越的影响;另外,非必须不建议将上传文件保存在web目录下,否则必须对文件后缀名进行控制。
1.2.1【必须】禁止全路径可控
文件操作时,禁止全路径都由客户端传入,这样不用跨目录,也可以对系统所有文件进行操作。如下例子:
@RequestMapping("/path/delete")
public void delete(HttpServletRequest request, HttpServletResponse response) {
String filePath = request.getParameter("path");
File file = new File(filePath); // 文件全路径由客户端传入,禁止
file.delete();
}
1.2.2【必须】禁止路径穿越
常见的有两种方式来防止路径穿越:
- 判断拼接进路径中的用户输入是否包含 ".."
@RequestMapping("/path/download")
public void download(HttpServletRequest request, HttpServletResponse response) {
String fileName = request.getParameter("name");
String DIR = "/data/file/upload/"; //文件服务器映射目录,非web目录
/*
* 防护方法:判断用户输入文件名是否存在..,存在则可能导致跨目录
*/
if(fileName.contains("..")) {
return;
}
File file = new File(DIR + fileName);
try {
InputStream inputStream = new FileInputStream(file);
OutputStream out = response.getOutputStream();
byte[] b = new byte[100];
int len;
while ((len = inputStream.read(b)) > 0) {
out.write(b, 0, len);
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- 获取文件标准路径进行合法性判断
@RequestMapping("/path/upload")
public void safe_upload(@RequestParam(value="file") MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
String DIR = "/data/file/upload/"; //文件服务器映射目录,非web目录
String filePath = DIR + fileName;
File tmpFile = new File(filePath);
/*
* 防护方法:File对象获取绝对路径,进行startwith判断
*/
if(!tmpFile.getCanonicalPath().startsWith(DIR)) {
throw new IOException(); // 这里return也可以
}
try {
InputStream in = file.getInputStream();
FileUtils.copyInputStreamToFile(in, tmpFile);
} catch (IOException e) {
e.printStackTrace();
}
}
1.2.3【建议】文件类型限制
-
【建议】如果文件保存在文件服务器映射的目录(或者专门的文件管理目录),则不必对文件后缀名做控制,只要确保无法跨目录即可
-
如果文件保存在web容器的可执行目录,在确保无法跨目录的前提下,还必须对文件类型进行控制。禁止对.jsp、.jspx、.class、.java、.jar、.war、.xml、.js、.html、.shtml、.vbs等类型文件进行操作。最好结合业务采用白名单限制:
- 图片类型:.jpg、.jpeg、.png、.gif、.bmp
- 文档类型:.doc、.docx、.ppt、.pptx、.xls、.xlsx、.pdf
可以通过以下方式限制文件类型:
@RequestMapping("/path/delete")
public void safe_delete(HttpServletRequest request) {
/*
* 防护方法:判断用户输入的文件后缀名是否在白名单中,是的话执行下一步操作
*/
String webRootPath = request.getSession().getServletContext().getRealPath("/");
String fileName = request.getParameter("name");
if(fileName.contains("..")) {
return;
}
int pos = fileName.lastIndexOf(".");
String ext = fileName.substring(pos);
String whiteExt = ".jpg.jpeg.png.gif.bmp"; // 文件类型白名单,根据具体情况而定
if(whiteExt.contains(ext)) {
new File(webRootPath + fileName).delete();
}
}
1.2.4【建议】避免路径拼接
文件目录避免外部参数拼接。保存文件目录建议后台写死并对文件名进行校验(字符类型、长度)。建议文件保存时,将文件名替换为随机字符串。
可以采取以下方法生成随机文件名:
- java.util.UUID类,UUID.randomUUID().toString()
- 雪花算法
安全案例参考:
@RequestMapping("/path/upload")
public void safe_upload(@RequestParam(value="file") MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf("."));
String DIR = "/data/file/upload/"; //文件服务器映射目录,非web目录
String fileName = UUID.randomUUID().toString(); // 文件名为随机字符串
String filePath = DIR + fileName + ext;
File tmpFile = new File(filePath);
try {
InputStream in = file.getInputStream();
FileUtils.copyInputStreamToFile(in, tmpFile);
} catch (IOException e) {
e.printStackTrace();
}
}
from secguide.
Related Issues (20)
- 专家建议增加一份C#的 HOT 3
- #java# 规范 1.6 OS命令执行 修订建议
- 希望增加一份iOS的代码安全指南 HOT 1
- C,C++安全指南.md 修改建议
- #C,C++# rand() 类函数应正确初始化 修改建议
- 想问一下后续有考虑做PHP的安全开发指南的想法吗
- #Python# 规范 通用类 1.9.3条 描述不清晰 HOT 2
- #go 规范# 1.2.1 语病 HOT 1
- #go# 规范 1.1.9 条 “slice是引用类型,在作为函数入参时采用的是地址传递” 勘误 HOT 3
- c# 指南 HOT 1
- PHP安全指南 HOT 2
- C ++安全指南.md 修改建议
- NET安全指南??
- #C,C++# 指南4.3条修订建议
- Go安全编码1.3.1 通过黑名单校验命令注入不可靠
- "CONTRIBUTING.md"文件中“提交请求”链接失效
- Request - English version
- C/C++安全指南建议 HOT 2
- C/C++ guide log_m_essage HOT 1
- 没有PHP的安全指南是什么意思 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from secguide.