Fix security issue. SHA1 has collisions, switching to SHA256

This commit is contained in:
Joseph Milazzo 2021-03-14 10:23:10 -05:00
parent 98c23af680
commit 126fb57f4d
2 changed files with 75 additions and 83 deletions

View File

@ -48,79 +48,79 @@ namespace API.Tests.Services
// } // }
//string GetCachedPagePath(Volume volume, int page) //string GetCachedPagePath(Volume volume, int page)
[Fact] // [Fact]
//[InlineData("", 0, "")] // //[InlineData("", 0, "")]
public void GetCachedPagePathTest_Should() // public void GetCachedPagePathTest_Should()
{ // {
// TODO: Figure out how to test this // // TODO: Figure out how to test this
// string archivePath = "flat file.zip"; // // string archivePath = "flat file.zip";
// int pageNum = 0; // // int pageNum = 0;
// string expected = "cache/1/pexels-photo-6551949.jpg"; // // string expected = "cache/1/pexels-photo-6551949.jpg";
// // //
// var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives"); // // var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives");
// var file = Path.Join(testDirectory, archivePath); // // var file = Path.Join(testDirectory, archivePath);
// var volume = new Volume // // var volume = new Volume
// { // // {
// Id = 1, // // Id = 1,
// Files = new List<MangaFile>() // // Files = new List<MangaFile>()
// { // // {
// new() // // new()
// { // // {
// Id = 1, // // Id = 1,
// Chapter = 0, // // Chapter = 0,
// FilePath = archivePath, // // FilePath = archivePath,
// Format = MangaFormat.Archive, // // Format = MangaFormat.Archive,
// NumberOfPages = 1, // // NumberOfPages = 1,
// } // // }
// }, // // },
// Name = "1", // // Name = "1",
// Number = 1 // // Number = 1
// }; // // };
// // //
// var cacheService = Substitute.ForPartsOf<CacheService>(); // // var cacheService = Substitute.ForPartsOf<CacheService>();
// cacheService.Configure().CacheDirectoryIsAccessible().Returns(true); // // cacheService.Configure().CacheDirectoryIsAccessible().Returns(true);
// cacheService.Configure().GetVolumeCachePath(1, volume.Files.ElementAt(0)).Returns("cache/1/"); // // cacheService.Configure().GetVolumeCachePath(1, volume.Files.ElementAt(0)).Returns("cache/1/");
// _directoryService.Configure().GetFilesWithExtension("cache/1/").Returns(new string[] {"pexels-photo-6551949.jpg"}); // // _directoryService.Configure().GetFilesWithExtension("cache/1/").Returns(new string[] {"pexels-photo-6551949.jpg"});
// Assert.Equal(expected, _cacheService.GetCachedPagePath(volume, pageNum)); // // Assert.Equal(expected, _cacheService.GetCachedPagePath(volume, pageNum));
//Assert.True(true); // //Assert.True(true);
} // }
//
[Fact] // [Fact]
public void GetOrderedChaptersTest() // public void GetOrderedChaptersTest()
{ // {
// var files = new List<Chapter>() // // var files = new List<Chapter>()
// { // // {
// new() // // new()
// { // // {
// Number = "1" // // Number = "1"
// }, // // },
// new() // // new()
// { // // {
// Chapter = 2 // // Chapter = 2
// }, // // },
// new() // // new()
// { // // {
// Chapter = 0 // // Chapter = 0
// }, // // },
// }; // // };
// var expected = new List<MangaFile>() // // var expected = new List<MangaFile>()
// { // // {
// new() // // new()
// { // // {
// Chapter = 1 // // Chapter = 1
// }, // // },
// new() // // new()
// { // // {
// Chapter = 2 // // Chapter = 2
// }, // // },
// new() // // new()
// { // // {
// Chapter = 0 // // Chapter = 0
// }, // // },
// }; // // };
// Assert.NotStrictEqual(expected, _cacheService.GetOrderedChapters(files)); // // Assert.NotStrictEqual(expected, _cacheService.GetOrderedChapters(files));
} // }
//
} }
} }

View File

@ -21,23 +21,15 @@ namespace API.Extensions
} }
/// <summary> /// <summary>
/// Calculates SHA1 hash for a byte[] and sets as ETag. Ensures Cache-Control: private header is added. /// Calculates SHA256 hash for a byte[] and sets as ETag. Ensures Cache-Control: private header is added.
/// </summary> /// </summary>
/// <param name="response"></param> /// <param name="response"></param>
/// <param name="content">If byte[] is null or empty, will only add cache-control</param> /// <param name="content">If byte[] is null or empty, will only add cache-control</param>
public static void AddCacheHeader(this HttpResponse response, byte[] content) public static void AddCacheHeader(this HttpResponse response, byte[] content)
{ {
// Calculates SHA1 Hash for byte[]
if (content == null || content.Length <= 0) return; if (content == null || content.Length <= 0) return;
using var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider(); using var sha1 = new System.Security.Cryptography.SHA256CryptoServiceProvider();
response.Headers.Add("ETag", string.Concat(sha1.ComputeHash(content).Select(x => x.ToString("X2")))); response.Headers.Add("ETag", string.Concat(sha1.ComputeHash(content).Select(x => x.ToString("X2"))));
// Not Needed with Response Caching
// if (!response.Headers.Keys.Contains("Cache-Control"))
// {
// response.Headers.Add("Cache-Control", "private");
// }
} }
} }