I got a report of a strange redirect loop on a website I (inherited, but help) manage. The reports were only from Chrome and Firefox users and just started suddenly last week, but the code on this site hadn't changed in at least 3 years, maybe longer.
我得到了一个有关我(继承但有帮助)管理的网站上奇怪的重定向循环的报告。 这些报告仅来自Chrome和Firefox用户,上周才突然开始,但是该网站上的代码至少三年没有变化,甚至可能更长。
![Chrome shows an error "this webpage has a redirect loop" Chrome shows an error "this webpage has a redirect loop"](https://i-blog.csdnimg.cn/blog_migrate/a1860a0be3f0ddba190f231f0f4dd191.png)
What's going on here? Well, it's a redirect loop, LOL. But what KIND of redirects?
这里发生了什么? 好吧,这是一个重定向循环,哈哈。 但是什么样的重定向?
We know about these redirects, right?
我们知道这些重定向,对吗?
- 302 - Object Moved - Look over here at THIS URL! 302-对象已移动-在这里查看此URL!
- 301 - Moved Permanently - NEVER COME HERE AGAIN. Go over to THIS URL! 301-永久移动-再也没有来过。 转到此URL!
![A redirect loop builds up in the Chrome Developer Tools A redirect loop builds up in the Chrome Developer Tools](https://i-blog.csdnimg.cn/blog_migrate/e5ce43926a0a4bfd9b77a6c35f8ed8e7.png)
But there's another kind of redirect.
但是还有另一种重定向。
307 - Internal Redirect or "Redirect with method" - Someone told me earlier to go over HERE so I'm going to go there without talking to the server. Imma redirect myself and keeping using the same VERB. That means you can redirect a POST without the extra insecure back and forth.
307-内部重定向或“使用方法重定向”-有人早些时候告诉我要在这里进行操作,所以我要去那里而不与服务器交谈。 Imma重新导向我自己,并继续使用相同的动词。 这意味着您可以重定向POST,而不会产生来回不安全的情况。
![A 307 Internal Redirect A 307 Internal Redirect](https://i-blog.csdnimg.cn/blog_migrate/42004483ef7e2b721971d20a5993a60f.png)
Note the reason for the 307! HSTS. What's that?
注意307的原因! HSTS。 那是什么?
HSTS:严格的运输安全 (HSTS: Strict Transport Security)
HSTS is a way to keep you from inadvertently switching AWAY from SSL once you've visited a site via HTTPS. For example, you'd hate to go to your bank via HTTPS, confirm that you're secure and go about your business only to notice that at some point you're on an insecure HTTP URL. How did THAT happen, you'd ask yourself.
HSTS是一种防止您通过HTTPS访问站点后无意中从SSL切换的方法。 例如,您不希望通过HTTPS进入银行,请确认您的安全,然后再开展业务,只是要注意在某个时候您使用的是不安全的HTTP URL。 您会问自己这是怎么发生的。
But didn't we write a bunch of code back in the day to force HTTPS?
但是我们不是一天前写了很多代码来强制使用HTTPS吗?
Sure, but this still required that we ask the server where to go at least once, over HTTP...and every subsequent time, user keeps going to an insecure page and then redirecting.
可以,但是这仍然需要我们通过HTTP请求服务器至少访问一次……之后,用户每次都会转到不安全的页面,然后进行重定向。
HSTS is a way of saying "seriously, stay on HTTPS for this amount of time (like weeks). If anyone says otherwise, do an Internal Redirect and be secure anyway."
HSTS是一种这样的说法:“认真地,在这段时间内(如几周)使用HTTPS。如果没有其他建议,请执行内部重定向并始终保持安全。”
Some websites and blogs say that to implement this in IIS7+ you should just add the CustomHeader require for HSTS like this in your web.config. This is NOT correct:
一些网站和博客说,要在IIS7 +中实现此功能,您只需在web.config中添加HSTS的CustomHeader要求即可。 这是不正确的:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
</system.webServer>
This isn't technically to spec. The problem here is that you're sending the header ALWAYS even when you're not under HTTPS.
从技术上讲这不是规范。 这里的问题是即使您不在HTTPS之下,也总是发送标头。
The HSTS (RFC6797) spec says
An HTTP host declares itself an HSTS Host by issuing to UAs (User Agents) an HSTS Policy, which is represented by and conveyed via the
Strict-Transport-Security HTTP response header field over secure transport (e.g., TLS).
You shouldn't send Strict-Transport-Security over HTTP, just HTTPS. Send it when they can trust you.
您不应该通过HTTP发送严格传输安全性,而只是通过HTTPS发送。 当他们可以信任您时将其发送。
Instead, redirect folks to a secure version of your canonical URL, then send Strict-Transport-Security. Here is a great answer on StackOverflow from Doug Wilson.
而是将人们重定向到您的规范URL的安全版本,然后发送Strict-Transport-Security。 这是Doug Wilson在StackOverflow上的一个很好的答案。
Note the first rule directs to a secure location from insecure one. The second one adds the HTTP header for Strict-Transport-Security. The only thing I might change would be to formally canonicalize the www. prefix versus a naked domain.
请注意,第一个规则从不安全的位置定向到安全的位置。 第二个为Strict-Transport-Security添加HTTP标头。 我可能要更改的唯一一件事就是正式规范www。 前缀与裸域。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Note also that HTTP Strict Transport Security is coming to IE and Microsoft Edge as well, so it's an important piece of technology to understand.
还请注意, HTTP严格传输安全性也将用于IE和Microsoft Edge ,因此,它是一项重要的技术。
What was happening with my old (inherited) website? Well, someone years ago wanted to make sure a specific endpoint/page on the site was served under HTTPS, so they wrote some code to do just that. No problem, right? Turns out they also added an else that effectively forced everyone to HTTP, rather than just using the current/inherited protocol.
我的旧(继承)网站发生了什么事? 好吧,几年前有人想要确保该站点上的特定端点/页面在HTTPS下得到服务,因此他们编写了一些代码来做到这一点。 没问题吧? 事实证明,他们还增加了其他人,有效地促使每个人都HTTP,而不是仅仅使用电流/继承协议。
This was a problem when Strict-Transport-Security was turned on at the root level for the entire domain. Now folks would show up on the site and get this interaction:
当在整个域的根级别上打开Strict-Transport-Security时,这是一个问题。 现在人们将出现在网站上并获得此交互:
- GET http://foo/web 获取http:// foo / web
- 301 to http://foo/web/ (canonical ending slash) 301至http:// foo / web /(标准斜杠)
- 307 to https://foo/web/ (redirect with method, in other words, internally redirect to secure and keep using the same verb (GET or POST)) 307到https:// foo / web /(使用方法重定向,换句话说,内部重定向以确保安全并继续使用相同的动词(GET或POST))
301 to http://foo/web (internal else that was dumb and legacy)
301到http:// foo / web (内部是愚蠢和遗留的)
- rinse, repeat 冲洗,重复
What's the lesson here? A configuration change that turned this feature on at the domain level of course affected all sub-directories and apps, including our legacy one. Our legacy app wasn't ready.
这是什么教训? 在域级别启用此功能的配置更改当然会影响所有子目录和应用,包括我们的旧目录和应用。 我们的旧版应用程序尚未准备就绪。
Be sure to implement HTTP Strict Transport Security (HSTS) on all your sites, but be sure to test and KNOW YOUR REDIRECTS.
确保在所有站点上实施HTTP严格传输安全性(HSTS) ,但请务必测试并知道您的重定向。
相关链接 (Related Links)
翻译自: https://www.hanselman.com/blog/how-to-enable-http-strict-transport-security-hsts-in-iis7