网站可能提供文件查看或下载的功能,如果对用户查看或下载的文件不做限制,就能够查看或下载任意的文件,可以是源文件,敏感文件等等。
任意文件下载漏洞发生的根本原因是系统自带的查看或下载功能,用户可控制下载路径,且当服务器不做任何限制的时候,就可以完成对任意文件的读取/下载。
当判断代码中是否存在任意文件下载漏洞时,可从以下3点进行判断:
1、是否存在文件读取接口?Java中如read函数等。
2、待读取的文件名参数是否为用户可控?是否直接拼接http请求数据?或者调用存储在数据库中的数据?
3、用户输入的文件名是否经过了校验?是否预先设置好文件白名单?对输入的特殊字符是否存在敏感字符过滤?
Java
private final String PROFILE = "F:\\file\\";
@RequestMapping("/download1")
public void download1(String filename, HttpServletResponse response) {
try {
String fileaPath = PROFILE + filename;
File file = new File(fileaPath);
> 这里是引用
String fullfilename = file.getName();
String ext = fullfilename.substring(fullfilename.lastIndexOf(".") + 1).toLowerCase();
FileInputStream fileInputStream = new FileInputStream(file);
InputStream fis = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
response.reset();
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fullfilename, "UTF-8"));
response.addHeader("Content-Length", "" + file.length());
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
outputStream.write(buffer);
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
上述代码中,对前端传的filename参数直接进行路径拼接,且未对filename中特殊字符进行过滤,存在任意文件下载漏洞。
打开源码文件,检索到file接口,明确里面的参数p没有过滤
而file接口却对p参数做了处理,跟进getFile,直接下载没有过滤,所以判断file/sm接口存在任意文件下载
1、输入验证和过滤:确保对用户提供的输入进行有效验证和过滤,防止输入中包含恶意路径或文件名。
2、文件权限设置:禁止应用程序下载目录以外的文件,或者对某些文件设置只读权限。
3、白名单校验:限制文件下载的路径和文件类型,严格控制下载的文件范围。
4、文件名重写:对用户提供的文件名进行重写,防止用户通过修改文件名绕过限制。
5、使用安全框架:使用已经经过安全验证的框架进行文件下载操作,避免自行编写下载代码可能引入漏洞。