PHP无法正确读取文件

时间:2020-11-09 15:51:39

标签: php authentication

这是我的代码:

<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
  if ($next == true and $pass === fgets($file)){
      echo "true";
      $next = false;
  } else {
      echo "false" . "<br>";
      $next = false;
  }
  if (fgets($file) == $user) {
      $next = true;
  }
}
fclose($file);
?>

这是info.txt

ch1ck3n
kodero1029

请注意,这只是一个伪造的密码

例如,我们转到包含以下代码的网站https://ch1ck3n.com/login/auth/auth.php?user=ch1ck3n&pass=kodero1029

,并打印错误的TWICE。 我正在使用php和一个简单的txt文档制作一个登录系统。 php代码逐行读取txt文件行,如果一行与用户名匹配,则表示密码在下一行。但是如果您看到了,请访问该网站,它将打印两次假。 $next变量表示下一行是密码。

2 个答案:

答案 0 :(得分:0)

怎么了?

您的问题是因为:

  if (fgets($file) == $user) {
      $next = true;
  }

为什么这是错误的?

这是$ next为true的唯一方法,但是您有$user = $_GET["user"] //ch1ck3n,但是如果您View the Manual则说明:

fgets
返回一个最大长度为字符串的字符串-从handle指向的文件中读取1个字节。如果文件指针中没有更多数据可读取,则返回FALSE。

另请参见:

读取长度为1个字节或换行符( 包含在返回值中 )后,读取结束

(我的口吻)

因此,您从fgets返回的值是一个包含行尾的字符串,您正在将其与文本行ch1ck3n进行比较,而不包含行尾。因此$next永远不会为真,因此对于文件的每一行,if / else语句将返回false选项。

解决方案:

字符串中带状线的结尾:

  if (trim(fgets($file)) === $user) {
      $next = true;
  }

对于您使用fgets的所有情况,都需要执行相同的操作。

安全说明:

正如评论中提到的那样,您解决此问题的方法是:安全绝对是错误的处理方式。您应该使用POST请求或数据库引用或SESSION cookie将凭据数据与脚本安全关联。

请勿在URL中发送敏感信息,因为无论是否带有https:Link

这都是不安全的

Comment by Felippe Duarte

答案 1 :(得分:-1)

循环的每次迭代都读取两行。由于您只有两行(也许是三行?),这意味着您可以完成一次迭代。这样做:

<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
   $line = rtrim(fgets($file)); //Newline is included in the fgets result
  if ($next == true && $pass === $line){
      echo "true";
      $next = false;
  } else {
      echo "false" . "<br>";
      $next = false;
  }
  if ($line === $user) {
      $next = true;
  }
}
fclose($file);

两次出现错误的原因是(可能)是因为文件末尾可能有一个空行。