表单随机提交为 GET 而不是 POST
这有点疯狂。
这是我们的 OpenID 提供商 上的表单:
<form method="post" action="/affiliate/form/login/submit?affId=7" autocomplete="off">
<table class="position-table">
<tr>
<td class="input-td">
<input class="framed-text-field" type="text" name="email" id="email" value="" maxlength="100" />
<span class="form-help">[email protected]</span>
</td>
<td class="input-td">
<input class="framed-text-field" type="password" name="password" id="password" />
<span class="form-help">Password</span>
</td>
<td></td>
<td class="input-td">
<input type="submit" class="affiliate-button" value="Sign In" />
</td>
</tr>
</table>
<input type="hidden" id="fkey" name="fkey" value="REDACTED" />
</form>
此表单是iframe 中托管的页面(位于 /affiliate/form/login
)。 iframe 通过 HTTPS 提供服务,主机页面通过 HTTP 提供服务。您可以使用 incognito/private- 在 /users/login
中查看此操作的实际情况浏览/色情模式浏览器窗口。
所以问题就来了,用户会定期(但不是始终)对该 URL 进行 GET 而不是 POST 操作。这种情况的发生率低得离谱,迄今为止影响的用户总数还不到 50 名。
我很想只是 dev/null
这些错误(没有操作方法等),但是......
这些看起来像真实的用户:广泛传播的 IP、多样化且有效的用户代理,以及可信的时间安排。令人沮丧的是,相同的用户有时稍后就成功发布了相同的表单。
有什么想法可能导致这种情况吗?
我曾经拥有并放弃的想法:
- HTTPS 加速器或负载均衡器处理请求
- 检查传入日志,它们与到达应用程序的内容匹配
- ASP/.NET 请求解析错误
- 将传入与记录的请求值进行比较,它们与
- Buggy 浏览器
- 匹配多个 Chrome 版本中记录的事件、FireFox 4、Safari 和移动 Safari
- 机器人,或糟糕的浏览器扩展
- 广泛的浏览器、IP 和操作系统传播。
我目前最好的猜测是操作中的 ?affId=#
正在绊倒某些东西(尽管再次不一致)。这基本上是巫毒调试,所以我希望有更权威的解释。
更新:尝试了我的巫术修复( 等)并部署。没有复制品,所以我只是让它烘烤。
我们平均每天看到几个,所以如果这个烘烤 2+ 没有问题,我会将其作为答案发布。
第二次更新:不,仍在发生。不过频率要低得多。我正在收集更多数据,看看浏览器或操作系统方面是否存在共性。
关于为什么从操作中删除 ?affId=#
会减少发生率的操作理论是在客户端乐观地获取“看起来可以安全获取的东西”之前有错误的代理。这是一个疯狂的猜测,所以要持保留态度。
第三次更新:更多关于虚假代理的证据。查询受影响 IP 的日志(在更长的时间内),其中许多 IP 的请求率比大多数未受影响的 IP 更高。它不是 100% 的剪切和干燥,我确信一些令人沮丧的刷新会稍微增加计数,但是......它仍然是一个合理的指标(差异是受影响 IP 的同一时期内请求数量的 5 倍左右) )。
此时,我将继续检测已发生的错误并提供更好的错误消息和指导。对实际获得权威答案相当不热心,特别是因为该答案似乎可能属于“我无法控制的代码”领域。
This is kind of crazy.
Here's a form on our OpenID provider:
<form method="post" action="/affiliate/form/login/submit?affId=7" autocomplete="off">
<table class="position-table">
<tr>
<td class="input-td">
<input class="framed-text-field" type="text" name="email" id="email" value="" maxlength="100" />
<span class="form-help">[email protected]</span>
</td>
<td class="input-td">
<input class="framed-text-field" type="password" name="password" id="password" />
<span class="form-help">Password</span>
</td>
<td></td>
<td class="input-td">
<input type="submit" class="affiliate-button" value="Sign In" />
</td>
</tr>
</table>
<input type="hidden" id="fkey" name="fkey" value="REDACTED" />
</form>
This form is part of a page (at /affiliate/form/login
) hosted in an iframe. The iframe is served over HTTPS, the host page over HTTP. You can see this in action at /users/login
using an incognito/private-browsing/porn-mode browser window.
So here's the problem, periodically (but not consistently) a user will GET instead of POST to this url. This is an absurdly low occurrence, affecting less than 50 total users to date.
I'm tempted to just dev/null
these errors (no action method etc. etc.), but...
These look like real users: wide spread of IPs, varied and valid user agents, and believable timings. Frustratingly, the same users sometimes successfully POST the same form just a bit later.
Any ideas what might be causing this?
Ideas I've had and discarded:
- HTTPS accelerator or load balancer munging requests
- checked incoming logs, they match what's getting to the app
- ASP/.NET request parsing error
- Compared incoming to logged Request values, they match
- Buggy browser
- Logged occurrences in multiple Chrome versions, FireFox 4, Safari, and Mobile Safari
- Bots, or crummy browser extensions
- Wide browser, IP, and OS spread.
My current best guess is that the ?affId=#
in the action is tripping something (though not consistently, again). This is basically voodoo debugging, so I'd love a more authoritative explanation.
Update: Tried my voodoo fix (<input type="hidden" name="affId" value="#" />
and so on), and deployed. Haven't got a repro, so I'm just letting it bake.
We see a couple a day on average, so if this bakes for 2+ without issue I'll post it as the answer.
Second Update: Nope, still occurring. Much less frequently however. I'm gathering more data to see if there is any commonality in terms of browsers or operating systems.
Operating theory as to why removing ?affId=#
from the action has reduced occurrence is buggy proxies in front of clients optimistically fetching "things that look safe to GET". This is a wild guess, so treat it with a grain of salt.
Third Update: More evidence for bogus proxies. Querying logs for affected IPs (over a much longer period of time), and many of them have much higher request rates than most unaffected ones. Its not 100% cut and dry, and I'm sure some frustrated refreshing is increasing the counts a tad but... its still a reasonable indicator (the difference is 5x or so the # of requests in the same period for the affected IPs).
At this point, I'm moving onto detecting the error has occurred and providing better error messages and guidance. Rather unenthusiastic about actually getting an authoritative answer, especially as that answer seems likely to lie in the realm of "code I don't control".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一些广告拦截浏览器扩展程序,例如 AdBlock Plus Popup插件“探测”伴随页面以确定其真实 URL,然后再决定是否阻止它们。具体来说,前面提到的 Popup 插件默认使用 HEAD 查询来执行此操作,但可以设置为执行 GET 查询。
Some ad-blocking browser extensions like AdBlock Plus Popup addon 'probe' companion pages to determine their real URL before deciding whether to block them. Specifically, the aforementioned Popup addon does this with HEAD queries by default but can be set up to do GET queries.
Chrome 用户也遇到了类似的问题,原因是如果有人在 Google Chrome 中使用 shift+enter 提交表单,浏览器将打开新选项卡并发出不带参数的 GET 请求。由于人们通常将大写/特殊字符作为密码的最后一个字符,因此他们在释放 Shift 之前按 Enter 键,然后发出 GET 请求。
我看到您在枚举浏览器时首先提到了 Chrome,因此如果 Chrome 中更频繁地发生问题,则可能是因为这个原因。
虽然这可能不是您遇到的唯一问题,但它可能会有所贡献。
Had a similar problem with Chrome users and the cause was if someone submits a form using shift+enter in google Chrome, browser will open new tab and make GET request with no parameters. Since people often have uppercase / special character as last character of a password, they press enter before releasing the shift and then GET request is issued.
I see that you mentioned Chrome first when enumerating browsers so if issue happens in Chrome more often, it's probably because of this reason.
While this is probably not the only issue you have, it probably contributes.
通过验证器运行源 HTML,确保其格式正确。
Make sure the source HTML is well formatted by running it through a validator.