gpt4 book ai didi

php - 在此AJAX/PHP MySQL搜索字段上添加速率限制

转载 作者:行者123 更新时间:2023-11-29 07:32:46 25 4
gpt4 key购买 nike

我正在制作一个网页,允许用户从搜索字段中搜索MySQL数据库,下面是代码:

<script>
function finduser(str) {
if (str == "") {
document.getElementById("txtstatus").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtstatus").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","search.php?q="+str,true);
xmlhttp.send();
}
}
</script>

和search.php
 <!DOCTYPE html>
<html>
<head>

</head>
<body>

<?php
$q = htmlspecialchars($_GET['q']);

$con = mysqli_connect('localhost','user','pass','db');
if (!$con) {
die('Could not connect: ' . mysqli_error($con));
}

mysqli_select_db($con,"db");
$sql="SELECT * FROM people WHERE CONCAT( firstname, ' ', lastname) LIKE '".$q."' OR phone LIKE '".$q."' OR email LIKE '".$q."'";
$result = mysqli_query($con,$sql);

$num_rows = mysqli_num_rows($result);

echo "<div class='records'><small>" . $num_rows . " records</small></div>";


while($row = mysqli_fetch_array($result)) {

if (is_null($row['hidden'])) {
} else {
continue;
}
echo "<div class='people'><small><a href='" . $row['id'] . "'>" . $row['firstname'] . " " . $row['lastname'] . "</a> submitted on " . date("M j\, Y", strtotime($row['timestamp']))"</small></div>";
}
echo "</ul>";
mysqli_close($con);
?>
</body>
</html>

几个问题:
1)此代码是否安全,可以保护诸如mysql注入攻击之类的agains攻击?如果不是,我该怎么保护它?
2)我想设置一个速率限制,在这个限制中,用户每秒只能搜索一定的次数,以防止洪水泛滥。一分钟5个问题。这只是一个个人项目,没有任何财务信息的利害关系或诸如此类,但我想展示如何正确地做到这一点。做这个最好的方法是什么?
我怀疑有人已经告诉我把登录凭据放到一个单独的PHP文件中并包含它。我打算这么做,有人能告诉我为什么这是一个好的做法吗?是不是服务器在HTML请求时意外地发送了原始PHP?

最佳答案

这段代码是关于一些最常见的web应用程序漏洞的试验品。)完全可以,对其他人也可能有教育意义。
SQL注入
你用错了。它不是一个输入净化函数,而是一个输出编码函数。你使用它的方式是无用的,应该从那里移除。由于没有有效的保护,上面的代码很容易受到SQL注入的攻击,输入的htmlspecialchars参数类似于:q(注意开头的空格)。
有了这个,你在第17行的查询将是

SELECT *  FROM people WHERE CONCAT( firstname,  ' ', lastname) LIKE ' union select * from other; -- \' OR phone LIKE ' union select * from other; -- \' OR email LIKE ' union select * from other; -- \'

请注意, union select * from other; -- \对反斜杠没有任何作用,也不必。为了可读性和字符转义的工作原理,删除LIKE表达式字符串实际上等于
SELECT *  FROM people WHERE CONCAT( firstname,  ' ', lastname) LIKE '...' union select * from other

有些解决方案是使用 prepared statementsPHP PDO或ORM。这里已经回答过多次了。甚至在 PHP manual中也有描述。
您应该始终对SQL注入有适当的保护,并且永远不应该像以前那样将SQL语句与参数连接起来。
跨站点脚本(XSS)
上面的代码可能容易受到XSS的攻击,这取决于数据进入数据库的方式。但不管怎样,通过清理动态输出,您的代码对XSS应该更加健壮。
问题在于,在Javascript中,您使用 htmlspecialchars将数据插入到DOM中,而DOM只是用PHP从数据库中读取,在写入页面之前从不进行编码。如果 innerHTMLfirstname字段中曾经包含HTML代码,比如带有javascript的脚本标记,那么它将被写入并插入页面,javascript将被运行。
为了避免这种情况,你应该
使用 lastnamehtmlspecialchars()或输出编码库对输出进行正确编码。注意,前两个函数是针对HTML上下文的,它们不适合Javascript(这里不适用,因为您正在编写纯HTML)。因此在您的示例中,您应该对 htmlentities()行中的变量应用编码,如 echo等。
在Javascript中,尽可能避免 htmlentities($row[firstname]),而是使用 innerHTML。当PHP使用标记编写HTML时,您不能这样做,这没关系,但是所有变量都需要按照上面所示进行编码。
请注意,虽然 innerText列不太可能是用户输入,但作为最佳实践,您不应该将变量单独写入链接的ref中。如果id是 id,请考虑XSS: <a href="javascript: alert(1)">。(顺便说一句,将这样的id写入到一个ref并没有多大意义,除非数据库中有非常时髦的id。)
插入到URL中的未编码字符串(非常弱的URL注入)
在Javascript中,函数的 javascript:...参数应该是用户以某种方式输入的(可能来自输入字段的值,或者通过某种逻辑)。该字符串直接连接到URL,在复合攻击中可能会利用该URL,也可能不会利用该URL。这不是一个直接的弱点,但我认为这是一个弱点。在将该值添加到查询的URL之前,应该对其进行URL编码。
硬编码凭证
正如您正确指出的,凭证不应硬编码。但原因并不是PHP文件会以文本形式返回。如果是的话,另一个PHP也不会有帮助,因为它也会作为文本返回。:)但是,例如,如何将其放入版本控制中?任何可以访问代码库的人都可以访问生产机密,这在许多环境中是不可接受的。同时,对这些凭证的更改意味着一个新的“版本”,一个新版本的软件,因为您必须更改代码,而不仅仅是配置。
因此,作为最佳实践,应该从安全的地方读取机密(至少在生产版本中是这样),例如环境变量,web服务器可以为PHP设置这些变量。这样,如果访问权限设置正确,则必须是web服务器用户(甚至是根用户)才能访问这些凭据(或者必须模拟应用程序进程,这当然足以读取其环境)。
如何准确地为PHP进程设置环境变量取决于web服务器,但在PHP中读取它的方式类似于 str
这可防止文件包含攻击获取机密(因为机密不在应用程序可访问的文件中),还允许您自由签入任何代码以进行版本控制。
潜在拒绝服务(DoS)
问题中的查询效率很低,因为在 getenv("databasepassword")比较中使用了两个字符串字段上的 concat()
正如您所提到的,速率限制(throttling)是您可以选择的一个选项,但在PHP中实现并不简单。
您可以在Web服务器中执行此速率限制,这里不讨论此问题,但是如果配置正确,Apache、Nginx等都可以执行此操作。
您可以实现类似验证码的东西,以便有效的查询只能由人工发送。
您可以为这些功能实现身份验证,并接受已通过身份验证的用户利用DoS的剩余风险。你也许可以用不同的方法来处理,例如服务条款。

关于php - 在此AJAX/PHP MySQL搜索字段上添加速率限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50449967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com