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