PHP - fpassthru()不显示图像

时间:2017-07-21 15:36:04

标签: php pdo

我写了一个脚本来测试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> 

1 个答案:

答案 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 );
}