The Background
Security headers are HTTP response headers that provide an additional layer of security to web applications. They help to protect against attacks such as cross-site scripting (XSS), clickjacking, and more.
Testing
1. Public URL of the application - Best solution is using dev tunnels. Be sure you check my last newsletter issue to find out how to expose the localhost.
2. Websites that scan the URL and return the result which headers are accessible. You can use 2 separated websites:
Current score:
1. Using the Middleware
2. Using NuGet packages:
I did it with the middleware:
app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder().AddDefaultSecurePolicy());
• X-Frame-Options
• X-Xss-Protection
• X-Content-Type-Options
• Strict-Transport-Security
• Referrer-Policy
• Content-Security-Policy
• Permissions-Policy
• Server
• X-Permitted-Cross-Domain-Policies
Let's start!
X-Frame-Options
This security feature prevents attackers from using iframes to manipulate your website's content and protects your users from falling victim to clickjacking attacks.
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
It has three possible values:
1. DENY: not allow your website to be embedded in an iframe under any circumstances.
2. SAMEORIGIN: allow your website to be embedded in an iframe only if the iframe is on the same domain as your website.
3. ALLOW-FROM uri: allow your website to be embedded in an iframe only if the iframe is on the specified uri.
X-Xss-Protection
context.Response.Headers.Add("X-Xss-Protection", "1; mode=block");
But...
• Chrome has removed their XSS Auditor
• Firefox has not, and will not implement X-XSS-Protection
• Edge has retired their XSS filter
X-Content-Type-Options
However, if you set the X-Content-Type-Options header to "nosniff" in your website's HTTP response, the browser will not attempt to sniff the content type and will instead use the declared content type. In this case, the browser would correctly identify the uploaded file as a JavaScript file and prevent it from executing as an image.
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
Strict-Transport-Security
Strict-Transport-Security (STS) is a security header that helps to protect web applications against man-in-the-middle (MITM) attacks by enforcing the use of HTTPS for all communications between the browser and the server.
if(!app.Environment.IsDevelopment())
{
app.UseHsts();
}
builder.Service.AddHsts(options =>
{
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(365);
})
This code will produce a header with subdomains included and a max-age of 1 year:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy
• "strict-origin": The Referer header will only be sent if the destination URL has the same origin as the referring URL, and will only include the scheme, host, and port (but not the path).
• "strict-origin-when-cross-origin": The Referer header will be sent when navigating from HTTPS to HTTP, but will only include the scheme, host, and port (but not the path).
context.Response.Headers.Add("Referrer-Policy", "no-referrer");
Content-Security-Policy
Content-Security-Policy (CSP) is a security header that helps to protect web applications against cross-site scripting (XSS) attacks and other types of code injection attacks. The header allows you to specify the sources from which various types of content can be loaded or executed, such as scripts, stylesheets, images, and media files.
By using CSP, you can prevent attackers from injecting malicious code into your web pages, because any code that is not explicitly allowed by the policy will be blocked by the browser. This can help to protect your users from attacks that could steal their personal information, install malware on their devices, or perform other unauthorized actions.
context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com");
In this example, the policy allows content to be loaded only from the website itself ('self') for most types of content (default-src), but allows scripts to be loaded from both the website and the external source https://cdnjs.cloudflare.com (script-src). This would allow the use of external JavaScript libraries like jQuery or Bootstrap, while still ensuring that any other scripts are blocked by the browser.
- default-src 'self': Allows content to be loaded only from the same origin as the page itself.
- default-src 'self' https://example.com: Allows content to be loaded from the same origin as the page itself, as well as from the https://example.com domain.
- default-src 'none': Disallows all content from being loaded.
- default-src 'self' script-src 'unsafe-inline': Allows scripts to be loaded only from the same origin as the page itself, but also allows inline scripts.
- default-src 'self'; img-src 'self' data: Allows images to be loaded only from the same origin as the page itself, as well as from data URLs.
Other possible directives and their meanings include:
- script-src: Defines the policy for scripts
- img-src: Defines the policy for images
- style-src: Defines the policy for styles
- connect-src: Defines the policy for network connections
- font-src: Defines the policy for fonts
- object-src: Defines the policy for objects and plugins
Permissions-Policy
Permissions-Policy is a security header that allows web developers to control and limit the permissions of various browser features and APIs. This header provides a way to specify which features are allowed to be used on a web page and which are not, allowing developers to improve the security of their web applications.
The Permissions-Policy header allows you to control access to a variety of browser features and APIs, including:
• Geolocation
• Camera and microphone access
• Fullscreen mode
• Payment processing APIs
• Clipboard access
• Navigation APIs
• Sensors
context.Response.Headers.Add("Permissions-Policy", "accelerator=(), camera=(),
geolocation=(), gyroscope=(), magnetometer=(), microphone=(),
payment=(), usb=()");
In this case, the permissions listed are "accelerometer", "camera", "geolocation", "gyroscope", "magnetometer", "microphone", "payment", and "usb". The values for each permission are empty, indicated by the parentheses after each permission name. This means that access to these features is completely disabled for the web application.
Server
context.Response.Headers.Remove("Server");
- X-Powered-By
- X-AspNet-Version
- X-AspNetMvc-Version
- X-Forwarded-Host
Expect-CT
Expect-CT is an HTTP response header that is used to enforce Certificate Transparency (CT) for HTTPS connections. Certificate Transparency is a mechanism designed to provide greater transparency and accountability for the issuance and use of SSL/TLS certificates, which are used to secure HTTPS connections.
By enabling Expect-CT in your web application, you can help to protect against attacks such as certificate misissuance or SSL/TLS interception.
context.Response.Headers.Add("Expect-CT", "max-age=2592000");
Result
What's next?
Security headers will not make your application completely secure, but they are certainly a starting point from which to start and which must be solved at the developer level.
In the future, in agreement with colleagues, other security flaws can be resolved.
That's all from me today.
Make a coffee and check the whole project on GitHub repository.