摘要:
允许用户输入控制文件系统操作所用的路径会导致攻击者能够访问或修改其他受保护的系统资源。
缺陷描述:
当满足以下两个条件时,就会产生路径遍历错误:
- 攻击者可以指定某一文件系统操作中所使用的路径。
- 攻击者可以通过指定特定资源来获取某种权限,而这种权限在一般情况下是不可能获得的。
例如,在某一程序中,攻击者可以获得特定的权限,以重写指定的文件或是在其控制的配置环境下运行程序。
示例1: 下面的代码使用来自于 HTTP
请求的输入来创建一个文件名。程序员没有考虑到攻击者可能使用像 “…/…/tomcat/conf/server.xml” 一样的文件名,从而导致应用程序删除它自己的配置文件。
String rName = request.getParameter("reportName"); File rFile = new File("/usr/local/apfr/reports" + rName); ... rFile.delete();
- 1
- 2
- 3
- 4
示例2: 下面的代码使用来自于配置文件的输入来决定打开哪个文件,并返回给用户。如果程序在一定的权限下运行,且恶意用户能够篡改配置文件,那么他们可以通过程序读取系统中以 .txt 扩展名结尾的所有文件。
fis = new FileInputStream(cfg.getPorperty("sub") + ".txt"); amt = fis.read(arr); out.println(arr);
- 1
- 2
- 3
有些人认为在移动世界中,典型的漏洞(如:path manipulation)是无意义的 – 为什么用户要攻击自己?但是,谨记移动平台的本质是从各种来源下载并在相同设备上运行的应用程序。恶意软件在银行应用程序附近运行的可能性很高,他们会强制扩展应用程序的攻击面(包括跨进程通信)。
示例3: 以下代码 “ 示例1 ” 改编未适用于 Android 平台。
... String rName = this.getIntent().getExtras().getString("reportName"); File rFile = getBaseContext().getFileStreamPath(rName); ... rFile.delete(); ...
- 1
- 2
- 3
- 4
- 5
- 6
防止路径遍历的最佳方法是采用一些间接手段:例如创建一份和合法资源名的列表,并且规定用户只能选择其中的文件名。通过这种方法,用户就不能直接由自己来指定资源的名称了。
但在某些情况下,这种方法并不可行,因为这样一份合法资源名的列表过于庞大、难于跟踪。因此,程序员通常在这种情况下采用黑名单的办法。在输入之前,黑名单会有选择地拒绝或避免潜在的危险字符。但是,任何这样一份名单都不可能是完整的,而且随着时间的推移而果实。更好的方法是创建一份白名单,允许其中的字符出现在资源名称中,且只接受完全由这些被认可的字符组成的输入。
示例4 白名单例子:
public boolean validateFile(File file) throws IOException {
//This represents the format d:\myapp\temp\ where the file name
//can consist of alpha-numeric, space/tab, period and dash characters and
//cannot exceed 20 characters in length
String goodPattern = "d:(\\\\|/)myapp(\\\\|/)temp(\\\\|/)(\\w|\\s|\\.|-){1,20}"";
Pattern p = Pattern.compile(goodPattern, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(file.getCanonicalPath());
if(!m.matches()) {
return false;
}
return true;
}
使用 2.6
版本的 commons-io
工具包自带的工具:
修改前:
File file = new File(path);
修改后:
import org.apache.commons.io.FileUtils;
File file = FileUtils.getFile(path);
整理完毕,完结撒花~