1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Added security headers, and file download last modified/content type.

This commit is contained in:
Uncled1023 2018-06-18 19:07:03 -07:00
parent 21a3a31f02
commit 9093c0f699
5 changed files with 81 additions and 5 deletions

View File

@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Teknik.Utilities.Cryptography;
@ -33,6 +34,7 @@ namespace Teknik.Configuration
private string _CdnHost;
private string _IPBlacklistFile;
private string _ReferrerBlacklistFile;
private List<string> _PublicKeys;
private UserConfig _UserConfig;
private ContactConfig _ContactConfig;
private EmailConfig _EmailConfig;
@ -68,6 +70,8 @@ namespace Teknik.Configuration
public string IPBlacklistFile { get { return _IPBlacklistFile;} set { _IPBlacklistFile = value; }}
public string ReferrerBlacklistFile { get { return _ReferrerBlacklistFile;} set { _ReferrerBlacklistFile = value; }}
public List<string> PublicKeys { get { return _PublicKeys; } set { _PublicKeys = value; } }
// User Configuration
public UserConfig UserConfig { get { return _UserConfig; } set { _UserConfig = value; } }
@ -143,6 +147,7 @@ namespace Teknik.Configuration
CdnHost = string.Empty;
IPBlacklistFile = string.Empty;
ReferrerBlacklistFile = string.Empty;
PublicKeys = new List<string>();
UserConfig = new UserConfig();
EmailConfig = new EmailConfig();
ContactConfig = new ContactConfig();

View File

@ -138,8 +138,7 @@ namespace Teknik.Areas.Upload.Controllers
return Json(new { error = new { message = "Exception while uploading file: " + ex.GetFullMessage(true) } });
}
}
// User did not supply key
[HttpGet]
[AllowAnonymous]
[ResponseCache(Duration = 31536000, Location = ResponseCacheLocation.Any)]
@ -301,6 +300,9 @@ namespace Teknik.Areas.Upload.Controllers
}
#endregion
// Set Last Modified
Response.GetTypedHeaders().LastModified = dateUploaded;
// We accept ranges
Response.Headers.Add("Accept-Ranges", "0-" + contentLength);
@ -310,6 +312,9 @@ namespace Teknik.Areas.Upload.Controllers
// Notify the client the content length we'll be outputting
Response.Headers.Add("Content-Length", length.ToString());
// Set the content type of this response
Response.Headers.Add("Content-Type", contentType);
// Create content disposition
var cd = new System.Net.Mime.ContentDisposition
{
@ -333,12 +338,12 @@ namespace Teknik.Areas.Upload.Controllers
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
return new BufferedFileStreamResult(contentType, (response) => ResponseHelper.StreamToOutput(response, true, new AesCounterStream(fs, false, keyBytes, ivBytes), (int)length, _config.UploadConfig.ChunkSize), false);
return new BufferedFileStreamResult(contentType, async (response) => await ResponseHelper.StreamToOutput(response, true, new AesCounterStream(fs, false, keyBytes, ivBytes), (int)length, _config.UploadConfig.ChunkSize), false);
}
else // Otherwise just send it
{
// Send the file
return new BufferedFileStreamResult(contentType, (response) => ResponseHelper.StreamToOutput(response, true, fs, (int)length, _config.UploadConfig.ChunkSize), false);
return new BufferedFileStreamResult(contentType, async (response) => await ResponseHelper.StreamToOutput(response, true, fs, (int)length, _config.UploadConfig.ChunkSize), false);
}
}
catch (Exception ex)
@ -376,6 +381,9 @@ namespace Teknik.Areas.Upload.Controllers
Inline = true
};
// Set the content type of this response
Response.Headers.Add("Content-Type", upload.ContentType);
Response.Headers.Add("Content-Disposition", cd.ToString());
// Read in the file

View File

@ -55,6 +55,7 @@ namespace Teknik.Middleware
}
httpContext.Response.Headers.Append("Access-Control-Allow-Origin", origin);
httpContext.Response.Headers.Append("Vary", "Origin");
return _next(httpContext);
}

View File

@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Teknik.Configuration;
namespace Teknik.Middleware
{
public class SecurityHeadersMiddleware
{
private readonly RequestDelegate _next;
public SecurityHeadersMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext, Config config)
{
IHeaderDictionary headers = httpContext.Response.Headers;
// Access Control
headers.Append("Access-Control-Allow-Credentials", "true");
headers.Append("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
headers.Append("Access-Control-Allow-Headers", "Authorization, Accept, Origin, Content-Type, X-Requested-With, Connection, Transfer-Encoding");
// HSTS
headers.Append("strict-transport-security", "max-age=31536000; includeSubdomains; preload");
// XSS Protection
headers.Append("X-XSS-Protection", "1; mode=block");
// Content Type Options
headers.Append("X-Content-Type-Options", "nosniff");
// Public Key Pinning
string keys = string.Empty;
foreach (string key in config.PublicKeys)
{
keys += $"pin-sha256=\"{key}\";";
}
headers.Append("Public-Key-Pins", $"max-age=300; includeSubDomains; {keys}");
// Referrer Policy
headers.Append("Referrer-Policy", "no-referrer, strict-origin-when-cross-origin");
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class SecurityHeadersMiddlewareExtensions
{
public static IApplicationBuilder UseSecurityHeaders(this IApplicationBuilder builder)
{
return builder.UseMiddleware<SecurityHeadersMiddleware>();
}
}
}

View File

@ -144,7 +144,7 @@ namespace Teknik
}
else
{
app.UseHsts();
//app.UseHsts();
}
// Performance Monitor the entire request
@ -154,6 +154,7 @@ namespace Teknik
app.UseBlacklist();
app.UseCORS();
app.UseCSP();
app.UseSecurityHeaders();
// Cache Responses
app.UseResponseCaching();