做渗透测试的时候,ueditor附件上传一个包含javascript代码的pdf文件,直接保存成功。
通过浏览器访问这个保存好的文件,会执行javascript代码。被评定为高危漏洞。
项目使用的ueditor1.4.*,发现ueditor只做了文件大小和后缀的验证,没有做内容是否包含javascript代码的验证。
思路是在ueditor处理文件上传成临时文件验证的地方(移动之前),加上验证,不通过就直接返回,跳过文件移动。
修改ueditor包含的Uploader.class.php文件可以实现
1、添加ERROR_XSS错误提示,只加末尾那一行
php
private $stateMap = array( //上传状态映射表,国际化用户需考虑此处数据的国际化
"SUCCESS", //上传成功标记,在UEditor中内不可改变,否则flash判断会出错
"文件大小超出 upload_max_filesize 限制",
"文件大小超出 MAX_FILE_SIZE 限制",
"文件未被完整上传",
"没有文件被上传",
"上传文件为空",
"ERROR_TMP_FILE" => "临时文件错误",
"ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
"ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
"ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
"ERROR_CREATE_DIR" => "目录创建失败",
"ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
"ERROR_FILE_MOVE" => "文件保存时出错",
"ERROR_FILE_NOT_FOUND" => "找不到上传文件",
"ERROR_WRITE_CONTENT" => "写入文件内容错误",
"ERROR_UNKNOWN" => "未知错误",
"ERROR_DEAD_LINK" => "链接不可用",
"ERROR_HTTP_LINK" => "链接不是http链接",
"ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确",
"ERROR_XSS" => "文件内容包含代码",
);
2、添加一个验证方法,建议加在 private function checkSize()方法后面:
php
/**
* 文件内容检测
* @return bool
*/
private function checkXSS($tmp_file)
{
$text = file_get_contents($tmp_file);
$text = str_replace(array("\r\n","\r","\n"), " ", $text);
preg_match('/javascript/i', $text, $matches);
if($matches){
return false;
}
return true;
}
3、upFile方法开头调用这个checkXSS方法验证
php
private function upFile()
{
$file = $this->file = $_FILES[$this->fileField];
if (!$file) {
$this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
return;
}
if ($this->file['error']) {
$this->stateInfo = $this->getStateInfo($file['error']);
return;
} else if (!file_exists($file['tmp_name'])) {
$this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
return;
} else if (!is_uploaded_file($file['tmp_name'])) {
$this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
return;
} else if (!$this->checkXSS($file['tmp_name'])) { //检查是否包含javascript代码
$this->stateInfo = $this->getStateInfo("ERROR_XSS");
return;
}
// 加了上面末尾三行