这更像是一个安全问题,我不确定这种方法是否足够安全可靠地下载文件并呈现给网络用户?
我们将客户发票文件存储在服务器位置(公共无法访问的位置(,然后我们通过文件中的PHP代码(在公共位置有文件(读取它们,如下所示,
当然,我们会在访问用户之前使用会话对用户进行身份验证,但是如果最终用户知道文件在哪里,他可以操纵其读取联合国授权发票的请求。
我只是想知道,如果这种方式
1. 向最终用户呈现文件是否足够安全?
2.最终用户根本不知道文件存储在服务器中的什么位置?
3. 关于如何处理类似情况,还有其他建议吗?
$i = $invoice->get();
$filename = sprintf(INV_PDF_FILENAME,$i['customerid'],date('Ymd',$i['dateIssued']));
$x = sprintf('/tmp/invoices/%s',$filename);
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Pragma: cache');
header('Cache-Control: private');
readfile($x);
- 是的,假设没有其他漏洞(即用户能够更改进入
$filename
的参数以执行目录遍历攻击(。 - 除非存在任何其他漏洞,否则提供的代码不会将其本地文件路径泄露给最终用户。
- 确保上传的文件存储在文档根目录之外。验证
realpath($x)
是否以您希望它们所在的目录开头。
例如:
$x = sprintf('/tmp/invoices/%s',$filename);
$realpath = realpath($x);
if (strpos($realpath, '/tmp/invoices/') !== 0) {
// Note: The strict comparison to 0 matters.
// It means that the real file path must begin with "/tmp/invoices/"
// or else this redirect/exit gets called.
header("Location: /error");
exit;
}