同一域的HTTP和HTTPS版本之间的XSS(XSS between HTTP and HTTPS versions of the same domain)

我想要完成的是使用ajax的内联登录,它执行以下操作:

登录链接显示在不安全的HTTP页面上,让我们说“ http://www.somedomain.com/somepage/ ” 这里没有收集登录信息

单击时,登录链接会创建一个iframe,其中src指向“ https://www.somedomain.com/rest_api/values/ ” 这是首次通过HTTPS显示登录表单的位置

在新的iframe弹出窗口中,向用户显示一个登录表单,该表单本身是安全的,已经通过HTTPS加载,用户填写表单并继续点击并返回自身。

假设用户成功登录,则对可通过window.parent.document访问的脚本进行jquery调用,该脚本使用当前用户窗口小部件更新原始页面,然后调用iframe将被销毁。

当我强制iframe使用相同的域和协议时,这很有用,但是一旦我进入HTTP并强制IFRAME使用HTTPS加载登录脚本,我就会得到可怕的“权限被拒绝访问属性'文档' “成功登录后Firebug中的错误。

我知道需要设置Access-Control-Allow-Origin标头,因此它会动态设置为使用所请求页面的域的HTTPS版本,并且我已经在Firebug中的Header Response中验证了这一点。原始页面请求。

那么为什么我仍然得到错误,响应标题显示:

Access-Control-Allow-Origin: https://www.somedomain.com

那么我需要设置其他东西,还是可能在其他地方出现问题?

谢谢你的帮助!


编辑:上面更新,以指出我不是愚蠢的,并确实登录表格确实加载;)

What I'm trying to accomplish is an inline login using ajax that does the following:

Login link is displayed on an unsecured HTTP page, lets say "http://www.somedomain.com/somepage/" No login info is collected here

When clicked the login link creates an iframe with a src pointing to "https://www.somedomain.com/rest_api/values/" This is where the login form is first displayed, via HTTPS

Within the new iframe popup, the user is presented a login form which itself is secure having been loaded via HTTPS, user fills in form and clicks continue which posts back to itself.

Assuming user is logged in successfully a jquery call is made to a script accessible via window.parent.document which updates the original page with the current user widget, and then calls for the iframe to be destroyed.

This works great when I force the iframe to use the same domain and protocol, but as soon as I come in on HTTP and force the IFRAME to load the login script with HTTPS, I get the dreaded "Permission denied to access property 'document'" error in Firebug after a successful login.

I understand that the Access-Control-Allow-Origin header needs to be set, so it's dynamically set to use the HTTPS version of what ever domain the page is being requested under, and I've verified this in the Header Response in Firebug on the original page request.

So why am I still getting the error, the response header shows:

Access-Control-Allow-Origin: https://www.somedomain.com

so is there something else I need to set, or is the problem possibly somewhere else?

Thanks for any help!


EDIT: Updated above to point out that I am not stupid and that the login form is indeed loaded securely ;)

最满意答案

除了@SLaks上面提到的“我应该/不应该”这个问题,这是有效的,但任何网站都需要权衡自己的问题......我面临的技术问题就是这个, Access-Control-Allow-Origin 就自己来说还不够,需要与以下内容一起设置:

Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: X-Requested-With

我不是肯定的,如果第一个对于我描述的确切场景是必要的,因为jquery只是成功的POST 之后运行而不是POST或GET调用本身,但是它在那里供你参考,因为我需要它我们网站的其他用例。

第二个...Allow-Headers是踢球者,因为标题包括X-Requested-With: XMLHttpRequest因为它最初是使用jquery中的XMLHttpRequest调用的,特别是.ajax()

有了这三个,我就没有问题了。 希望这能帮助其他人处于同样的境地!


编辑:自欺欺人,HTTPS到HTTP仍然无法正常工作,从剩下的一天我仍然试图弄明白这一点,很明显,尽管它应该这样做,但它不会。

所以最终的解决方案是,通过HTTPS加载登录页面,通过HTTPS提交,并在成功登录后,重定向到HTTP以发送回父母的呼叫以删除登录iframe。

Aside from the "should I / shouldn't I" issue raised above by @SLaks, which is valid, but a question that any site needs to weigh for itself... the technical problem I was facing was this, the Access-Control-Allow-Origin on it's own was not enough, it needs to be set along with the following:

Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: X-Requested-With

I'm not positive if the first one is necessary for the exact scenario I was describing since the jquery was simply run after a successful POST rather than a POST or GET call itself, but it's there for your reference, and because I needed it for other use cases for our site.

The second one ...Allow-Headers was the kicker though, since the headers included X-Requested-With: XMLHttpRequest because it was originally called using an XMLHttpRequest out of jquery, specifically .ajax().

With all three in place, I've had no problems since. Hope this helps others in the same situation!


EDIT: Fooled myself, the HTTPS to HTTP still didn't work, and from the remaining day I spent still trying to figure this out, it's become obvious that it won't despite the fact it should.

So the end solution was, Load the login page via HTTPS, submit via HTTPS, and upon successful login, redirect to HTTP to send a call back to the parent to remove the login iframe.

更多推荐