如何防止用户向 php 文件发送如此多的 post 请求

Posted

技术标签:

【中文标题】如何防止用户向 php 文件发送如此多的 post 请求【英文标题】:How can I prevent user to send so many post requests to php file 【发布时间】:2020-09-22 16:06:12 【问题描述】:

我有一个 html 文件,里面有一个表单。当这个表单提交时,它会向 php 文件发送一个 POST 请求。 PHP 文件创建与 mysql DB 的连接并更新其中的一行。

问题是任何人都可以获取此 POST 请求并将其发送到 PHP 文件同时,当 PHP 收到这些请求时,它将在数据库中执行更新并破坏数据库。

如何阻止用户发送这些请求?如何更改我的代码并使其更安全?

非常感谢!

index.html

<form action="send.php" method="post">
    <input type="text" name="product">
    <button type="submit">Submit and Send</button>
</form>

和...

发送.php

<?php

$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'test';

$conn = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) 
    // If there is an error with the connection, stop the script and display the error.
    exit('Failed to connect to MySQL: ' . mysqli_connect_error());


$prod = $_POST['product'];
$date = date('d.m.Y');

$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, "INSERT INTO store (product, date_added) VALUES (?,?)")) 
    exit('MySQL Error');
 else 
    mysqli_stmt_bind_param($stmt, 'ss', $prod, $date);
    mysqli_stmt_execute($stmt);
    header('Location: index.html');
    exit();    


 ?>

我的数据库是这样的:

id  |  product  |  date_added |
--------------------------------
1   |  wood     |  01.01.2020 |
--------------------------------

【问题讨论】:

请给我们看代码 @nbk 对不起,我会补充。 google.com/recaptcha/intro/v3.html 同时 POST 请求究竟应该如何“破坏”数据库? @gre_gor 我的意思是,例如,我可以编写一个 Python 脚本,将随机的 1000 个发布请求发送到文件。它的数据库将充满随机垃圾。 【参考方案1】:

有一个使用fail2ban 的解决方案。请提供fail2ban的文档

您可以在代码中引入一行,在客户日志文件中添加一行,例如/var/log/mysites/somesite.log

以这样的方式:

 <?php 
 # ( we will use this function to determine the corect ip of the spammer)

 function getRealUserIp()
    switch(true)
      case (!empty($_SERVER['HTTP_X_REAL_IP'])) : return $_SERVER['HTTP_X_REAL_IP'];
      case (!empty($_SERVER['HTTP_CLIENT_IP'])) : return $_SERVER['HTTP_CLIENT_IP'];
      case (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) : return $_SERVER['HTTP_X_FORWARDED_FOR'];
      default : return $_SERVER['REMOTE_ADDR'];
    
 



[...]
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, "INSERT INTO store (product, date_added) VALUES (?,?)")) 
    exit('MySQL Error');
 else 
    mysqli_stmt_bind_param($stmt, 'ss', $prod, $date);
    mysqli_stmt_execute($stmt);
    $ip = getRealUserIp();  // <<<<<<<<
    error_log("Visitor from - $ip !", 3, "/var/log/mysites/somesite.log");   // <<<<<<
    header('Location: index.html');
    exit();    

[...]

在下一步中,您必须安装和配置 fail2ban

apt install fail2ban

那么你必须在你的 /etc/fail2ban/jail.conf 中添加一个部分并在最后添加这个

[your_app]
port = http,https
logpath = /var/log/mysites/somesite.log

那么你需要在/etc/fail2ban/filter.d/your_app.conf中插入一个过滤器

# Fail2Ban filter for your_app.conf, looks for failed access attempts

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

# Regexp to fit your logfile entry ... read the fail2ban documentation
# and customize as this is just a example
failregex = ^(*.) <HOST> !$
ignoreregex =

然后你回到控制台并打开怪物......

fail2ban-client stop
fail2ban-client add your_app
fail2ban-client start

fail2ban-client status your_app

【讨论】:

以上是关于如何防止用户向 php 文件发送如此多的 post 请求的主要内容,如果未能解决你的问题,请参考以下文章

如何防止从客户端向服务器端发送数据(位置、纬度和经度)作弊?

如何向php服务器发送数据为json的post请求

通过arduino向PHP文件发送POST请求[重复]

如何用php向服务器发送post请求

php如何接收别的服务器post过来的数据 - 技术问答

如何防止用户向群组发送消息,但继续接收来自该群组的消息(只读)?