简体   繁体   English

大型POST传输仅适用于已登录的用户?

[英]Large POST transfer only for logged-in users?

On my homepage, users that are "logged in" (via a PHP-session), should be allowed to upload very large files (via standard HTML5/PHP/XMLHttpRequest/POST-formular). 在我的主页上,应该允许“登录”(通过PHP会话)的用户上传非常大的文件(通过标准HTML5 / PHP / XMLHttpRequest / POST形式)。 Therefore, I set 'post_max_size' to 0 in order to remove any restriction on the file size. 因此,我将“ post_max_size”设置为0,以消除对文件大小的任何限制。

However, I want to avoid that now everybody can send arbitrary large POST data to my server and block it. 但是,我要避免现在每个人都可以向我的服务器发送任意大的POST数据并将其阻止。 I want to first validate the login, and then accept a very large POST transfer to start. 要先验证登录名, 然后接受非常大的POST传输才能开始。

How to achieve this? 如何实现呢?

Inspired by the comments of Jari, I implemented the following strategy, which works fine for me. 受到贾里(Jari)评论的启发,我实施了以下策略,对我来说效果很好。 Since I use HTTPS for the website and the file upload, this strategy is even save against network sniffing attacks. 由于我将HTTPS用于网站和文件上传,因此这种策略甚至可以避免网络嗅探攻击。

My website is based on php, where logged-in users retrieve a php-session(-id). 我的网站基于php,已登录的用户在其中检索php-session(-id)。

php.ini has the default value of post_max_size = 8M back, so no large POST-transfers are accepted by my server in general. php.ini的默认值为post_max_size = 8M back,因此我的服务器通常不接受大的POST传输。

When logging in, I set a temporary cookie secret=XXXXXXXX at the client, where the X's represent a random string that is also saved on server-side in $_SESSION["secret"] . 登录时,我在客户端设置了一个临时cookie secret=XXXXXXXX ,其中X代表一个随机字符串,该字符串也保存在服务器端的$_SESSION["secret"]

On the server-side, I create a web-accessible "user-directory" tmp-YYYYYYYY for each session, where the Y's are just another random string. 在服务器端,我为每个会话创建一个可通过网络访问的“用户目录” tmp-YYYYYYYY ,其中Y只是另一个随机字符串。 In this directory, I put a symlink that points to my global upload.php -script that receives the file-uploads via POST from the upload-form (you could also just copy upload.php to the user-directory). 在此目录中,我放置了一个指向我的全局upload.php -script的符号链接,该upload.php通过POST通过POST从上载表单接收文件上载(您也可以将upload.php复制到用户目录中)。 Now, in order to allow that a POST-transfer to tmp-YYYYYYYY/upload.php may have unlimited size, I also create the file tmp-YYYYYYYY/.htaccess which contains the line php_value post_max_size 0 . 现在,为了允许对tmp-YYYYYYYY/upload.php的POST传输具有无限大小,我还创建了文件tmp-YYYYYYYY/.htaccess ,其中包含php_value post_max_size 0 This enables to pass unlimited size POST-data to the linked upload-script. 这样可以将大小不受限制的POST数据传递到链接的上载脚本。 However, this is unsecure in the sense that everybody who knows/sniffes the URL tmp-YYYYYYYY/upload.php is able to send arbitrary large POST-data to this file, which may flood the server's tmp-directory. 但是,这在某种意义上是不安全的,因为每个知道/ tmp-YYYYYYYY/upload.php URL tmp-YYYYYYYY/upload.php都可以向该文件发送任意大的POST数据,这可能会淹没服务器的tmp目录。 In order to avoid this, my full .htaccess -file looks like this: 为了避免这种情况,我完整的.htaccess -file如下所示:

RewriteEngine On
RewriteCond %{HTTP_COOKIE} !secret=XXXXXXXX;?
RewriteRule ^ https://www.myserver.com/secreterror.php [L]
php_value post_max_size 0

That is, whenever the client that sends the large POST-data has no cookie with the secret value, then I re direct (since the target is an absolute url) him to some error-notification-script. 也就是说,只要发送大量POST数据与秘密值没有cookie中的客户端,那么我再直接 (因为目标是一个绝对URL)他的一些错误通知脚本。 This redirection does not forward POST-data, so no POST-data is stored on my server in this case. 这种重定向转发后的数据,所以没有POST数据存储我在这种情况下,服务器上。 If the client has the correct secret cookie set, then the maximum allowed POST-data size is set to unlimited for the user-directory, thus for upload.php . 如果客户端设置了正确的秘密Cookie,则对于用户目录(对于upload.php ,最大允许POST数据大小将设置为无限制。

Final comments: 最后评论:

  • you can also use post_max_size 4G in order to not allow 'really' arbitrary large data 您也可以使用post_max_size 4G ,以防止“真正”任意大数据
  • you can also overwrite other php-values here, all those that are labeled as PHP_INI_PERDIR in this list 您还可以在此处覆盖其他php值, 列表中所有标记为PHP_INI_PERDIR的值
  • in order to be able to allow to override post_max_size in .htaccess , apache must not run php in CGI mode, but as an apache module. 为了能够覆盖.htaccess post_max_size ,apache不能以CGI模式运行php,而应作为apache模块运行。 You can check for this by phpinfo() in the field "Server API". 您可以在“服务器API”字段中通过phpinfo()进行检查。 See here and here 这里这里
  • the mod_rewrite apache module must be enabled, for example by sudo a2enmod rewrite plus restarting apache service apache2 restart 必须启用mod_rewrite apache模块,例如通过sudo a2enmod rewrite加上重新启动apache service apache2 restart
  • probably your virtual host configuration must be be modified such that .htaccess is allowed to enable rewriting, for example by AllowOverride All 可能必须修改您的虚拟主机配置,以便允许.htaccess启用重写,例如,通过AllowOverride All
  • without HTTPS, the cookie is transmitted unsecurely, so the method is then vulnerable to network sniffers, just like php-sessions via HTTP in general, too 如果没有HTTPS,则cookie的传输是不安全的,因此该方法容易受到网络嗅探器的攻击,就像通常通过HTTP进行php会话一样
  • instead of creating a single directory for each session, containing its own .htaccess -file for a single secret key, one could alternatively use for all users the same upload-file (in its own single directory), and store/update all temporary secret keys in a data-base, and then use a modified RewriteCond that checks this data-base for the secret key that is passed in the cookie 与其为每个会话创建一个目录(而不是为单个密钥包含自己的.htaccess -file),还可以为所有用户使用相同的上传文件(在其单个目录中),并存储/更新所有临时密钥。数据库中的密钥,然后使用修改后的RewriteCond来检查此数据库中是否存在Cookie中传递的密钥

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM