这是我的代码:
<?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
变量表示下一行是密码。
答案 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
这都是不安全的
答案 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);
两次出现错误的原因是(可能)是因为文件末尾可能有一个空行。