Php 写入文件的输入会被恶意篡改吗?

Php 写入文件的输入会被恶意篡改吗?,php,file,security,validation,Php,File,Security,Validation,Uber是一个简单的例子来说明这一点: $message = $_POST['message']; $fp = fopen("log.txt", "a"); fwrite($fp, $message); fclose($fp); 我是否应该清理$\u POST['message']变量的用户输入 我理解准备好的语句(用于数据库清理)和htmlentities(如果我在某个时候将POST消息输出回屏幕),但在这种情况下,输入只是放在一个日志文件中,由一个小PHP脚本读取(通过fopen())

Uber是一个简单的例子来说明这一点:

$message = $_POST['message'];

$fp = fopen("log.txt", "a");
fwrite($fp, $message);

fclose($fp);
我是否应该清理
$\u POST['message']
变量的用户输入

我理解准备好的语句(用于数据库清理)和
htmlentities
(如果我在某个时候将
POST
消息输出回屏幕),但在这种情况下,输入只是放在一个日志文件中,由一个小PHP脚本读取(
通过fopen()


答案是否取决于阅读方式?例如,如果我确实通过fopen()打开日志文件,它应该是
htmlentities
,如果我计划下载日志文件并用Excel读取它(出于过滤目的),则无需执行任何操作?

您应该清理用户输入,但如何清理完全取决于输入的用途。“消毒”指的是确保输入对于特定用途是安全的或健全的。在确定用例之前,术语不能更具体

您不必担心像fopen()这样的PHP读/写函数。关注实际解析或分析输入的步骤。一些可能的例子:

  • 如果文件将显示在基本日志读取器中,则可能需要确保每个输入都被限制为特定长度,并且不包含换行符或您选择的字段分隔符,并且每行的开头都是有效的时间戳
  • 如果文件将显示在web浏览器中,您可能需要确保输入不包括脚本或指向其他资源的链接(如IMG标记)
  • Excel文件在行长度、时间戳和分隔符方面也会有类似的问题。只要Excel将文件解析为文本,您就不必担心包含可执行代码的人。(此外,现代Excel版本在运行宏之前会对包含的宏发出警告。)
    • 一般规则是:

      如果可以以任何方式修改您的输入,那么您应该。如果没有,那么您应该在输出时对其进行清理,以确保它在使用它的上下文中是安全的

      e、 g.如果您知道每条
      消息
      应少于100个字符,无论其使用方式如何,则读取POST数据的脚本可以验证并拒绝其POST数据包含100个字符或以上输入的任何请求

      验证是一种“全有或全无”的方法,它拒绝任何不符合特定规则的内容,而不管输出上下文如何,而清除则是根据上下文“确保安全”的过程。我认为区分这一点很重要

      在您的情况下,您提供的示例代码不会输出(由另一个脚本处理的过程除外)。与其说是输出操作,不如说是存储操作,因为
      消息
      可以像文件系统一样轻松地写入数据库。在这种情况下,需要锁定的主要攻击面似乎是文件权限,并确保除了您打算在正确上下文下执行此操作的脚本之外,没有任何内容可以读取或写入文件。例如,我意识到您的示例被简化了,但是在这种特定情况下,您应该确保将文件写入web根目录上方的位置,或者写入具有适当文件夹权限设置的位置。否则,您可能会无意中为web上的任何人授予读取权限,如果他们也可以写入,那么如果他们可以诱使浏览器将文件读取为HTML,则可能会利用某种攻击。旧版本的Internet Explorer不依赖服务器头值
      text/plain
      (另请参见)。虽然这些漏洞可能有点离题,但我只是全面地提到它们,并作为确保文件本身被适当锁定的示例

      回到您的问题:在您的情况下,您的验证应该通过处理
      log.txt
      的脚本进行。这将验证该文件。请注意,此处验证的是文件,而不是原始的
      消息
      。该文件应使用其自身的规则进行验证,以确保数据符合预期。如果脚本直接输出任何内容,则应在此处进行清理,以匹配输出的上下文。因此,对您的申请进行验证和消毒的过程总结如下:

    • 创建日志:Web浏览器---发布--->
      获取消息.php
      -->验证
      消息
      是否有效---fwrite()-->
      log.txt

    • 进程日志:
      log.txt
      --fopen()-->
      Process.php
      -->验证文件是否有效-->是否有任何输出?然后在此阶段进行消毒


    • 以上假设在脚本进行处理之前进行了正确的授权(即当前用户在应用程序中有权记录
      消息或处理日志)。

      您的代码基本上是无辜的。唯一“明显”的攻击是反复向服务器上传数据,最终耗尽磁盘空间

      “消毒”是一种情境性的东西。这并不是像食物上撒盐一样,你可以在代码上撒一些东西来让代码变得更好。也许您会清理$_POST数据以防止SQL注入攻击,但随后会在HTML上下文中使用这些数据—现在您很容易受到XSS攻击。也许这是一个图像上传,您需要进行基本的MIME类型确定,以确保它是一个图像。这一切都很好,但后来有人上传了儿童色情片,这将通过“这是一个图像”测试,现在你有一个更大的问题

      由于您正在接受用户数据并将其写入文件,因此无法使用此代码(除了磁盘空间问题)滥用您的系统。不能将某些数据嵌入到文件中
      include('log.txt');
      
      line 1
      line 2
      
      line 1 
      line 2
      line 3
      remainder of line 3
      very remainder of line 3
      
      line 3\nremainder of line 3\nvery remainder of line 3