我写了一个脚本来测试fpassthru()。这个想法是有一个提交图像的表单。提交后,脚本将为服务器上临时位置的映像创建文件句柄。然后文件句柄传递给fpassthru()并显示在网页上。但是,当我运行此脚本时,图像不会显示,而是显示在页面中心的一个小空白方块。这是代码:
<html>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'])?>" enctype="mu
ltipart/form-data">
<input type="file" name="image">
<input type="submit" value="submit">
</form>
<?php
if($_SERVER["REQUEST_METHOD"]=="POST"){
$finfo = finfo_open();
$type = finfo_file($finfo, $_FILES["image"]["tmp_name"], FILEINFO_MIME_TYPE);
if(strpos($type, "image")!==False)
{
$file=fopen($_FILES["image"]["tmp_name"], "rb") or die("Unable to open file<br>");
header("Content-Type: $type");
fpassthru($file);
}
}
?>
</body>
</html>
答案 0 :(得分:0)
首先,你不能在同一个请求中发送HTML和图像(好吧,有一个解决方法,比如base64编码图像,这是可能的,但很少有好主意,这样的解决方法使用显着更多带宽和cpu和ram,无论是对于您的服务器还是浏览器等,都要发送上传HTML表单或图像,而不是两者都在同一个请求中,如下所示:
<?php
if($_SERVER["REQUEST_METHOD"]=="POST"){
$finfo = finfo_open();
$type = finfo_file($finfo, $_FILES["image"]["tmp_name"], FILEINFO_MIME_TYPE);
if(strpos($type, "image")!==False)
{
$file=fopen($_FILES["image"]["tmp_name"], "rb") or die("Unable to open file<br>");
header("Content-Type: $type");
fpassthru($file);
die();
}
}
?><html>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'])?>" enctype="mu
ltipart/form-data">
<input type="file" name="image">
<input type="submit" value="submit">
</form>
</body>
</html>
第二,不要这样做:action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'])?>"
- 你不仅暴露自己的XSS漏洞,你试图通过htmlspecialchars()来防止这里的失败但是没有(例如,尝试输入带有page.php?%27+onmouseover%3D%27alert%28%27vulnerable%27%29%3B%27+
)的网址,但完全没必要。当你想发布到当前页面时,只需完全省略&#34; action&#34;属性完全。当你想要防止XSS注入时,请确保给htmlspecialchars提供适当的标志,ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE | ENT_DISALLOWED
- 带有这些标志的htmlspecialchars实际上可以保护你免受xss注入。就此而言,我多年来一直使用这个功能来防止xss注入:
/**
* convert any string to valid HTML, as losslessly as possible, assuming UTF-8
*
* @param string $str
* @return string
*/
function hhb_tohtml(string $str): string {
return htmlentities ( $str, ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE | ENT_DISALLOWED, 'UTF-8', true );
}