-
Notifications
You must be signed in to change notification settings - Fork 25.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HSTS and UseHttpsRedirection #5902
Changes from 3 commits
eed6596
7bd742d
b7c9e60
d00ba7a
f269b4d
ec038fb
dbaa0f6
8a86318
bf6a91d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,26 @@ This document shows how to: | |
|
||
## Require HTTPS | ||
|
||
# [ASP.NET Core 2.1](#tab/aspnetcore2x) | ||
|
||
[!INCLUDE[](~/includes/2.1.md)] | ||
|
||
We recommend all ASP.NET Core web apps call `UseHttpsRedirection` to redirect all HTTP requests to HTTPS. If `UseHsts` is called in the app, it must be called before `UseHttpsRedirection`. | ||
|
||
The following code calls `UseHttpsRedirection` in the `Startup` class: | ||
|
||
[!code-csharp[sample](enforcing-ssl/sample/Startup.cs?name=snippet1&highlight=13)] | ||
|
||
|
||
The following code: | ||
|
||
[!code-csharp[sample](enforcing-ssl/sample/Startup.cs?name=snippet2&highlight=18-22)] | ||
|
||
* Sets `RedirectStatusCode`. | ||
* Sets the HTTPS port to 5001. | ||
|
||
# [ASP.NET Core 1.x and 2.0](#tab/aspnetcore1x) | ||
|
||
The [RequireHttpsAttribute](/dotnet/api/Microsoft.AspNetCore.Mvc.RequireHttpsAttribute) is used to require HTTPS. `[RequireHttpsAttribute]` can decorate controllers or methods, or can be applied globally. To apply the attribute globally, add the following code to `ConfigureServices` in `Startup`: | ||
|
||
[!code-csharp[](authentication/accconfirm/sample/WebApp1/Startup.cs?name=snippet2&highlight=4-999)] | ||
|
@@ -39,3 +59,34 @@ For more information, see [URL Rewriting Middleware](xref:fundamentals/url-rewri | |
|
||
Requiring HTTPS globally (`options.Filters.Add(new RequireHttpsAttribute());`) is a security best practice. Applying the | ||
`[RequireHttps]` attribute to all controllers/Razor Pages isn't considered as secure as requiring HTTPS globally. You can't guarantee the `[RequireHttps]` attribute is applied when new controllers and Razor Pages are added. | ||
|
||
------------------- | ||
|
||
<a name="hsts"></a> | ||
## HTTP Strict Transport Security Protocol (HSTS) | ||
|
||
|
||
Per [OWASP](https://www.owasp.org/index.php/About_The_Open_Web_Application_Security_Project), [HTTP Strict Transport Security (HSTS)](https://www.owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet) is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers. | ||
|
||
ASP.NET Core 2.1 preview1 or later implements HSTS with the `UseHsts` extension method. The following code calls `UseHsts` when the app isn't in [development mode](xref:fundamentals/environments): | ||
|
||
[!code-csharp[sample](enforcing-ssl/sample/Startup.cs?name=snippet1&highlight=10)] | ||
|
||
`UseHsts` not recommend in development because calling `UseHsts` excludes the local loopback address. | ||
|
||
The following code: | ||
|
||
[!code-csharp[sample](enforcing-ssl/sample/Startup.cs?name=snippet2&highlight=11-16)] | ||
|
||
* Sets the preload parameter of the Strict-Transport-Security header. Preload is not part of the [RFC HSTS specification](https://tools.ietf.org/html/rfc6797), but is supported by web browsers to preload HSTS sites on fresh install. See [https://hstspreload.org/](https://hstspreload.org/) for more information. | ||
* Enables [includeSubDomain](https://tools.ietf.org/html/rfc6797#section-6.1.2), which applies the HSTS policy to Host subdomains. | ||
* Explicitly sets the max-age parameter of the Strict-Transport-Security header to to 60 days. If not set, defaults to 30 days. See the [max-age directive](https://tools.ietf.org/html/rfc6797#section-6.1.1) for more information. | ||
|
||
`UseHsts` excludes the following loopback hosts: | ||
|
||
* `localhost` : The IPv4 loopback address. | ||
* `127.0.0.1` : The IPv4 loopback address. | ||
* `[::1]` : The IPv6 loopback address. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add that you also may specify other excluded hosts on the HstsOptions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No setter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can still call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is part of the HstsOptions, not the HttpsRedirectionOptions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you send me the code to do that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind, wrong place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah looks good! |
||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Link to sample here? |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@page | ||
@model AboutModel | ||
@{ | ||
ViewData["Title"] = "About"; | ||
} | ||
<h2>@ViewData["Title"]</h2> | ||
<h3>@Model.Message</h3> | ||
|
||
<p>Use this area to provide additional information.</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace WebHTTPS.Pages | ||
{ | ||
public class AboutModel : PageModel | ||
{ | ||
public string Message { get; set; } | ||
|
||
public void OnGet() | ||
{ | ||
Message = "Your application description page."; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
@page | ||
@model ContactModel | ||
@{ | ||
ViewData["Title"] = "Contact"; | ||
} | ||
<h2>@ViewData["Title"]</h2> | ||
<h3>@Model.Message</h3> | ||
|
||
<address> | ||
One Microsoft Way<br /> | ||
Redmond, WA 98052-6399<br /> | ||
<abbr title="Phone">P:</abbr> | ||
425.555.0100 | ||
</address> | ||
|
||
<address> | ||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> | ||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> | ||
</address> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace WebHTTPS.Pages | ||
{ | ||
public class ContactModel : PageModel | ||
{ | ||
public string Message { get; set; } | ||
|
||
public void OnGet() | ||
{ | ||
Message = "Your contact page."; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
@page | ||
@model ErrorModel | ||
@{ | ||
ViewData["Title"] = "Error"; | ||
} | ||
|
||
<h1 class="text-danger">Error.</h1> | ||
<h2 class="text-danger">An error occurred while processing your request.</h2> | ||
|
||
@if (Model.ShowRequestId) | ||
{ | ||
<p> | ||
<strong>Request ID:</strong> <code>@Model.RequestId</code> | ||
</p> | ||
} | ||
|
||
<h3>Development Mode</h3> | ||
<p> | ||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred. | ||
</p> | ||
<p> | ||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application. | ||
</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace WebHTTPS.Pages | ||
{ | ||
public class ErrorModel : PageModel | ||
{ | ||
public string RequestId { get; set; } | ||
|
||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); | ||
|
||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] | ||
public void OnGet() | ||
{ | ||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
@page | ||
@model IndexModel | ||
@{ | ||
ViewData["Title"] = "Home page"; | ||
} | ||
|
||
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000"> | ||
<ol class="carousel-indicators"> | ||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li> | ||
<li data-target="#myCarousel" data-slide-to="1"></li> | ||
<li data-target="#myCarousel" data-slide-to="2"></li> | ||
<li data-target="#myCarousel" data-slide-to="3"></li> | ||
</ol> | ||
<div class="carousel-inner" role="listbox"> | ||
<div class="item active"> | ||
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" /> | ||
<div class="carousel-caption" role="option"> | ||
<p> | ||
Learn how to build ASP.NET apps that can run anywhere. | ||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409"> | ||
Learn More | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
<div class="item"> | ||
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" /> | ||
<div class="carousel-caption" role="option"> | ||
<p> | ||
There are powerful new features in Visual Studio for building modern web apps. | ||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409"> | ||
Learn More | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
<div class="item"> | ||
<img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" /> | ||
<div class="carousel-caption" role="option"> | ||
<p> | ||
Bring in libraries from NuGet and npm, and automate tasks using Grunt or Gulp. | ||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409"> | ||
Learn More | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
<div class="item"> | ||
<img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" /> | ||
<div class="carousel-caption" role="option"> | ||
<p> | ||
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps. | ||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409"> | ||
Learn More | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> | ||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> | ||
<span class="sr-only">Previous</span> | ||
</a> | ||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> | ||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> | ||
<span class="sr-only">Next</span> | ||
</a> | ||
</div> | ||
|
||
<div class="row"> | ||
<div class="col-md-3"> | ||
<h2>Application uses</h2> | ||
<ul> | ||
<li>Sample pages using ASP.NET Core Razor Pages</li> | ||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li> | ||
</ul> | ||
</div> | ||
<div class="col-md-3"> | ||
<h2>How to</h2> | ||
<ul> | ||
<li><a href="https://go.microsoft.com/fwlink/?linkid=852130">Working with Razor Pages.</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li> | ||
</ul> | ||
</div> | ||
<div class="col-md-3"> | ||
<h2>Overview</h2> | ||
<ul> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li> | ||
</ul> | ||
</div> | ||
<div class="col-md-3"> | ||
<h2>Run & Deploy</h2> | ||
<ul> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li> | ||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure App Service</a></li> | ||
</ul> | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace WebHTTPS.Pages | ||
{ | ||
public class IndexModel : PageModel | ||
{ | ||
public void OnGet() | ||
{ | ||
|
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
@page | ||
@model PrivacyModel | ||
@{ | ||
ViewData["Title"] = "Privacy Policy"; | ||
} | ||
<h2>@ViewData["Title"]</h2> | ||
|
||
<p>Use this page to detail your site's privacy policy.</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace WebHTTPS.Pages | ||
{ | ||
public class PrivacyModel : PageModel | ||
{ | ||
public void OnGet() | ||
{ | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
@using Microsoft.AspNetCore.Http.Features | ||
|
||
@{ | ||
var consentFeature = Context.Features.Get<ITrackingConsentFeature>(); | ||
var showBanner = !consentFeature?.CanTrack ?? false; | ||
var cookieString = consentFeature?.CreateConsentCookie(); | ||
} | ||
|
||
@if (showBanner) | ||
{ | ||
<nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert"> | ||
<div class="container"> | ||
<div class="navbar-header"> | ||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse"> | ||
<span class="sr-only">Toggle cookie consent banner</span> | ||
<span class="icon-bar"></span> | ||
<span class="icon-bar"></span> | ||
<span class="icon-bar"></span> | ||
</button> | ||
<span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span> | ||
</div> | ||
<div class="collapse navbar-collapse"> | ||
<p class="navbar-text"> | ||
Use this space to summarize your privacy and cookie use policy. | ||
</p> | ||
<div class="navbar-right"> | ||
<a asp-page="/Privacy" class="btn btn-info navbar-btn">Learn More</a> | ||
<button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button> | ||
</div> | ||
</div> | ||
</div> | ||
</nav> | ||
<script> | ||
(function () { | ||
document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) { | ||
document.cookie = el.target.dataset.cookieString; | ||
document.querySelector("#cookieConsent").classList.add("hidden"); | ||
}, false); | ||
})(); | ||
</script> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"
UseHsts
not recommend in development because the HSTS header is highly cachable by browsers. By default, UseHsts excludes the local loopback address."