I have the following url to reset my password:
我有以下网址重置我的密码:
http://example.com/resetPassword/LtoyURJd5AYuP3KEGg4gx8fvUprT37LBQDlvhg22qjg=.eyJ0b2tlbiI6IiQyeSQxMCRMTlgzU29HdEdOaExsay5yQ1puQ2ZlZ1wvbVNcL09BMDV2SjhcL1wvcHNRNjZaQmRpbWpOdnhGQlciLCJ0aW1lIjoiMjAxNS0xMi0xMVQwOTozOToyOSswMTAwIiwiZW1haWwiOiJsb3JlbS51dC5hbGlxdWFtQGZldWdpYXRwbGFjZXJhdHZlbGl0Lm9yZyJ9
On the local development machine it works without any problems. But on the public server (hosted on amazon ec2) i get a 414 Uri to long. I have tried to fix it but i can't seem to solve the issue. ps: i have replaced the url to example.com
在本地开发机器上它没有任何问题。但是在公共服务器上(托管在亚马逊ec2上),我得到了一个414 Uri。我试图解决它,但我似乎无法解决问题。 ps:我已将url替换为example.com
I have tried adding the following line to /etc/apache2/apache2.conf, the vhosts conf. Both at the same time and seperate. And yes. I also restarted apache service every time.
我尝试将以下行添加到/etc/apache2/apache2.conf,vhosts conf。两者同时又分开。是的。我每次都重启apache服务。
LimitRequestLine 8190
Also when i request other long url's there is no problem. For example. i renamed robots.txt so i could request the following urls:
此外,当我要求其他长网址没有问题。例如。我重命名为robots.txt,所以我可以请求以下网址:
http://example.com/robotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsr/robotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsroborobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobots.txtrobots.txtrobots.txtrobots.txtrobots.txtrobots.txtrobots.php?test=ok
http://example.com/robotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsr/robotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsroborobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobotsrobots.txtrobots.txtrobots.txtrobots.txtrobots.txtrobots.txtrobots.php
http://example.com/robots.txt?klsadjflkasdjflkdsajflkdsja=sdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfjsdakjflksadjfoaiwsefnalkfj
I also moved robots.txt to a other location and made a rewrite rule for it. Even then it seems to work correct. So mod_rewrite does not seme to be the problem.
我还将robots.txt移动到其他位置并为其制作了重写规则。即便如此,它似乎工作正确。因此mod_rewrite不会成为问题。
The problem occurs when the url becomes longer as +/- 275 chars. It worked with a reset link of 273 and the longer was 324 chars. The robots long url was arround 400 chars i think.
当网址变长+/- 275个字符时,会出现此问题。它使用273的重置链接,更长的是324个字符。我认为机器人长的网址是400个字符。
I also seem to have the problem (which i am not shure is related or not) that my vhosts is not loaded correctly. The server always redirects to the path defined in the default. Not of the vhosts. apache2ctl -s output gives the following:
我似乎也有问题(我不是shure是否相关)我的vhosts没有正确加载。服务器始终重定向到默认路由中定义的路径。不是vhosts。 apache2ctl -s输出提供以下内容:
ubuntu@ip-172-31-28-19:~$ apache2ctl -S
VirtualHost configuration:
:80 example.com (/etc/apache2/apache2.conf:228)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/public"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex proxy: using_defaults
Mutex default: dir="/var/lock/apache2" mechanism=fcntl
Mutex mpm-accept: using_defaults
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: using_defaults
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33 not_used
Group: name="www-data" id=33 not_used
Update 2015-12-18 In discussion with the other developers in my team we will be choosing a different base image for this server on amazon. There seemed to be more problems than this. So this question has become obsolete.
更新2015-12-18在与我的团队中的其他开发人员讨论时,我们将在亚马逊上为此服务器选择不同的基本映像。似乎有比这更多的问题。所以这个问题已经过时了。
4
Instead of base64_encode()
ing the information you need to reset a password, with all the information there for everyone to base64_decode()
it, see this:
而不是base64_encode()您需要重置密码的信息,并且每个人都有base64_decode()的所有信息,请参阅:
// this is from your example
$encoded = 'eyJ0b2tlbiI6IiQyeSQxMCRMTlgzU29HdEdOaExsay5yQ1puQ2ZlZ1wvbVNcL09BMDV2SjhcL1wvcHNRNjZaQmRpbWpOdnhGQlciLCJ0aW1lIjoiMjAxNS0xMi0xMVQwOTozOToyOSswMTAwIiwiZW1haWwiOiJsb3JlbS51dC5hbGlxdWFtQGZldWdpYXRwbGFjZXJhdHZlbGl0Lm9yZyJ9';
$data = json_decode(
base64_decode($encoded),
true
);
// array (
// 'token' => '$2y$10$LNX3SoGtGNhLlk.rCZnCfeg/mS/OA05vJ8//psQ66ZBdimjNvxFBW',
// 'time' => '2015-12-11T09:39:29+0100',
// 'email' => 'lorem.ut.aliquam@feugiatplaceratvelit.org',
// )
Persist data in a table
How about instead persisting that data - either in a database or elsewhere with limited lifetime - and then either using a UUID or a hash created with that data above as an identifier for the password reset?
相反,如果要将数据保存在数据库或生命周期有限的其他地方,然后使用UUID或使用上述数据创建的哈希作为密码重置的标识符?
CREATE TABLE `password_reset` (
`id` char(40) NOT NULL DEFAULT '',
`token` char(60) NOT NULL DEFAULT '',
`time` datetime NOT NULL,
`email` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Then generate your identifier:
然后生成您的标识符:
$id = sha1(serialize([
'token' => '$2y$10$LNX3SoGtGNhLlk.rCZnCfeg/mS/OA05vJ8//psQ66ZBdimjNvxFBW',
'time' => '2015-12-11T09:39:29+0100',
'email' => 'lorem.ut.aliquam@feugiatplaceratvelit.org',
'foo' => microtime(), // for some variation
]);
Store the data in your table, and there your have your fixed length identifier, and your password reset URL becomes
将数据存储在您的表中,并且您有固定长度标识符,并且密码重置URL变为
http://example.com/resetPassword/0f4d2541c25ba8edbb3cd6df362d7dbf6317d7a5
Instead of using sha1()
to create a hash from some input, it would probably be better to use, for example, ramsey/uuid
to generate a time-based UUID (fixed length, 36 characters):
而不是使用sha1()从某些输入创建哈希,例如,使用ramsey / uuid生成基于时间的UUID(固定长度,36个字符)可能更好:
use Ramsey\Uuid\Uuid;
$id = Uuid::uuid1()->toString()
While this doesn't solve your problem of allowing really long URIs, it solves the problem in a better, much safer way.
虽然这并没有解决您允许真正长URI的问题,但它以更好,更安全的方式解决了问题。
BonusHave a look at OWASP's Forgot Password Cheatsheet and related, maybe it helps in making your application more secure!
看看OWASP的Forgot Password Cheatsheet和相关内容,也许它有助于提高您的应用程序的安全性!
1
Use POST method instead of get and it will resolve your problem.
使用POST方法代替get,它将解决您的问题。
But if you still would like to use "GET" method instead of "POST" method, then under Apache, value of LimitRequestLine
can be changed to something larger than its default of 8190 if you want to support a longer request URI.
但是如果你仍然想使用“GET”方法而不是“POST”方法,那么在Apache下,如果你想支持更长的请求URI,可以将LimitRequestLine的值更改为大于默认值8190的值。
If you can't find LimitRequestLine
into apache config file, just add the line yourself anywhere you like. e.g: LimitRequestLine 100000
如果您无法在apache配置文件中找到LimitRequestLine,只需在您喜欢的任何地方添加该行。例如:LimitRequestLine 100000
However, note that if you're actually running into this limit, you are probably abusing GET to begin with. You should use POST to transmit this sort of data -- especially since you even concede that you're using it to update values
但请注意,如果您实际上遇到此限制,则可能会开始滥用GET。您应该使用POST来传输此类数据 - 特别是因为您甚至承认您正在使用它来更新值
0
There are at least 2 config variables that can cause 414 error.
至少有2个配置变量可能导致414错误。
LimitRequestLine directive allows the server administrator to set the limit on the allowed size of a client's HTTP request-line. By default it is 4094.
LimitRequestLine指令允许服务器管理员设置客户端HTTP请求行的允许大小限制。默认情况下是4094。
LimitRequestFieldSize directive allows the server administrator to set the limit on the allowed size of an HTTP request header field. By default it is 4094 bytes
LimitRequestFieldSize指令允许服务器管理员设置HTTP请求标头字段的允许大小限制。默认情况下,它是4094字节
Try increase both of them or try to see how big is request that comes to server. It could be useful if you put here the request that you send to server.
尝试增加它们或尝试查看服务器的请求有多大。如果您将此处发送到服务器的请求放在此处可能很有用。
Useful links:
如何解决HTTP 414“请求URI太长”错误?
0
You shouldn't use this pattern even if it works after changing the EC2 image.
即使在更改EC2图像后它起作用,也不应使用此模式。
In your example the schema + host, i.e. http://example.com
, is 18 bytes long. If your actual host has a similar length then the 275 char limitation might indicate that a limit of 255 characters is applied on the path.
在您的示例中,架构+主机(即http://example.com)长度为18个字节。如果您的实际主机具有相似的长度,则275 char限制可能表示路径上应用了255个字符的限制。
Whatever the reason, RFC 2068 advises against longer URIs (although the spec requires servers to be able to handle any URI length):
无论什么原因,RFC 2068建议不要使用更长的URI(尽管规范要求服务器能够处理任何URI长度):
Servers should be cautious about depending on URI lengths above 255 bytes, because some older client or proxy implementations may not properly support these lengths.
服务器应该谨慎依赖于高于255字节的URI长度,因为某些较旧的客户端或代理实现可能无法正确支持这些长度。
So it is very possible that the email client from which you click is redirecting the click via some internal proxy (such as anti-phishing) that issues the 414 code. This is for example how Zimbra works. It is common practice in email clients in order to reduce threats from malicious links. In that case a POST won't help you because you cannot POST from an email client.
因此,您单击的电子邮件客户端很可能通过发出414代码的某些内部代理(例如反网络钓鱼)重定向单击。这就是Zimbra的工作原理。电子邮件客户端的常见做法是减少恶意链接的威胁。在这种情况下,POST不会帮助您,因为您无法从电子邮件客户端POST。
So the only solution is to persist the reset information on the server side, and have the URI point to it with a shorter token.
所以唯一的解决方案是在服务器端保留重置信息,并让URI指向更短的令牌。