From 03566a97a677426f1adf57db387b3c02754988c2 Mon Sep 17 00:00:00 2001 From: mdkoeppel Date: Tue, 25 Jan 2022 12:06:57 -0800 Subject: [PATCH 01/15] Upgrade to .Net 6 --- .../Snappass.NET.UnitTest.csproj | 22 ++++++++++++------- Snappass.NET.sln | 6 ++--- Snappass.NET/Snappass.NET.csproj | 16 ++++++++------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj index 2020075..4ba03b5 100644 --- a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj +++ b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj @@ -1,18 +1,24 @@ - + - netcoreapp3.0 + net6.0 false - - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Snappass.NET.sln b/Snappass.NET.sln index 6b656f1..6122ed5 100644 --- a/Snappass.NET.sln +++ b/Snappass.NET.sln @@ -1,11 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29411.108 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snappass.NET", "Snappass.NET\Snappass.NET.csproj", "{9D5B2889-491B-4E44-B00D-4DA803197031}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Snappass.NET.UnitTest", "Snappass.NET.UnitTest\Snappass.NET.UnitTest.csproj", "{2B880861-D49F-4C86-AB15-67BC84D5933A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snappass.NET.UnitTest", "Snappass.NET.UnitTest\Snappass.NET.UnitTest.csproj", "{2B880861-D49F-4C86-AB15-67BC84D5933A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index b53859d..0fa5ba6 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -1,22 +1,24 @@  - netcoreapp3.0 + net6.0 Snappass.NET Snappass + Exe + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + From 235f69bc7229577e25e9cc01289386224dc9631a Mon Sep 17 00:00:00 2001 From: mdkoeppel Date: Thu, 17 Nov 2022 16:03:44 -0800 Subject: [PATCH 02/15] Update To .net & --- .../Snappass.NET.UnitTest.csproj | 14 +++++----- Snappass.NET/Dockerfile | 25 ++++++++++++++++++ .../Properties/serviceDependencies.json | 7 +++++ .../Properties/serviceDependencies.local.json | 7 +++++ Snappass.NET/Snappass.NET.csproj | 12 ++++----- Snappass.NET/database.sqlite | Bin 12288 -> 12288 bytes Snappass.NET/libman.json | 5 ++++ 7 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 Snappass.NET/Dockerfile create mode 100644 Snappass.NET/Properties/serviceDependencies.json create mode 100644 Snappass.NET/Properties/serviceDependencies.local.json create mode 100644 Snappass.NET/libman.json diff --git a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj index 4ba03b5..8868283 100644 --- a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj +++ b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj @@ -1,21 +1,21 @@  - net6.0 + net7.0 false - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Snappass.NET/Dockerfile b/Snappass.NET/Dockerfile new file mode 100644 index 0000000..404f160 --- /dev/null +++ b/Snappass.NET/Dockerfile @@ -0,0 +1,25 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. +#For more information, please see https://aka.ms/containercompat + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["Snappass.NET/Snappass.NET.csproj", "Snappass.NET/"] +RUN dotnet restore "Snappass.NET/Snappass.NET.csproj" +COPY . . +WORKDIR "/src/Snappass.NET" +RUN dotnet build "Snappass.NET.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Snappass.NET.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Snappass.NET.dll"] \ No newline at end of file diff --git a/Snappass.NET/Properties/serviceDependencies.json b/Snappass.NET/Properties/serviceDependencies.json new file mode 100644 index 0000000..a4e7aa3 --- /dev/null +++ b/Snappass.NET/Properties/serviceDependencies.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "secrets1": { + "type": "secrets" + } + } +} \ No newline at end of file diff --git a/Snappass.NET/Properties/serviceDependencies.local.json b/Snappass.NET/Properties/serviceDependencies.local.json new file mode 100644 index 0000000..09b109b --- /dev/null +++ b/Snappass.NET/Properties/serviceDependencies.local.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "secrets1": { + "type": "secrets.user" + } + } +} \ No newline at end of file diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index 0fa5ba6..23b14e5 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -1,7 +1,7 @@  - net6.0 + net7.0 Snappass.NET Snappass Exe @@ -11,14 +11,14 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/Snappass.NET/database.sqlite b/Snappass.NET/database.sqlite index 4f70088309655fa630935a6ea085c5d8a95aa8dc..6efe9ab41ca4504e82858b600aec66b76e4c2c40 100644 GIT binary patch delta 254 zcmZojXh@hK&B!@X##xY)K`-2cm;VO?6F(;dKPUg`&4L0m`8IR%2Mg45HiqgNd%0Uw zdIqKj=6M;H`T69Tnx(mznJ0O98x7f delta 254 zcmZojXh@hK&B#7c##xY^LC^XlFaHk)CVox^eop?=n*{}C@@?ki4;HBBXbja&4GMNE z3Gy%VG4!v<$a61s4KB_rbF*+uH>$`l3oHmLGbwWS%+9UM@GG`WcLV{a)F?BjaGwm9 zQUi}N<4~`Z64Rt)KgR%{A`_SJ)KtIxav$@|MDJvGCokhX&&Wv2f}qGK-PB0)qD-&Q zpm_7B2*awvBv+?E)xyLe`D#swl0530Nr+DW;TU#RoBLiInV_ic71w&ISL!(U! KSNL^EaU}rR>`(;& diff --git a/Snappass.NET/libman.json b/Snappass.NET/libman.json new file mode 100644 index 0000000..ceee271 --- /dev/null +++ b/Snappass.NET/libman.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [] +} \ No newline at end of file From 682b54a9a612c677c165efb559269c93c8ff8548 Mon Sep 17 00:00:00 2001 From: pinksnafu <93672346+pinksnafu@users.noreply.github.com> Date: Thu, 18 May 2023 20:32:32 -0700 Subject: [PATCH 03/15] Create dependabot.yml --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ac6621f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" From 4e7aedfe253fa205523a0ab7c343658bb619a59f Mon Sep 17 00:00:00 2001 From: pinksnafu <93672346+pinksnafu@users.noreply.github.com> Date: Thu, 18 May 2023 20:34:41 -0700 Subject: [PATCH 04/15] Update dependabot.yml Added nuget? --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ac6621f..8c23067 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ version: 2 updates: - - package-ecosystem: "" # See documentation for possible values + - package-ecosystem: "nuget" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" From 6fd46422a1e37b8b0e2259724855ebc93e8e5643 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 03:35:07 +0000 Subject: [PATCH 05/15] Bump Microsoft.EntityFrameworkCore.Tools from 7.0.0 to 7.0.5 Bumps [Microsoft.EntityFrameworkCore.Tools](https://github.com/dotnet/efcore) from 7.0.0 to 7.0.5. - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.0...v7.0.5) --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore.Tools dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Snappass.NET/Snappass.NET.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index 23b14e5..8e2212f 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 865d2c01af4a04790e310b7993a17fe45c6c0527 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 03:35:15 +0000 Subject: [PATCH 06/15] Bump Moq from 4.18.2 to 4.18.4 Bumps [Moq](https://github.com/moq/moq4) from 4.18.2 to 4.18.4. - [Release notes](https://github.com/moq/moq4/releases) - [Changelog](https://github.com/moq/moq4/blob/main/CHANGELOG.md) - [Commits](https://github.com/moq/moq4/compare/v4.18.2...v4.18.4) --- updated-dependencies: - dependency-name: Moq dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj index 8868283..10e426d 100644 --- a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj +++ b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -8,7 +8,7 @@ - + From 47c5bac95ec0cabe50ffd8295128fd62d40c14ca Mon Sep 17 00:00:00 2001 From: pinksnafu <93672346+pinksnafu@users.noreply.github.com> Date: Thu, 18 May 2023 20:37:57 -0700 Subject: [PATCH 07/15] Create codeql.yml --- .github/workflows/codeql.yml | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..abbc343 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,76 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '42 11 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'csharp', 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From 41257a1836171a3c54bbd65e06eb027ef2692901 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 03:41:19 +0000 Subject: [PATCH 08/15] Bump Microsoft.NET.Test.Sdk from 17.4.0 to 17.6.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0 to 17.6.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.4.0...v17.6.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj index 10e426d..b4124ac 100644 --- a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj +++ b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj @@ -7,7 +7,7 @@ - + From 4c4781a54724fd22d4e63f6ddc254251a5bfbfee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 03:41:43 +0000 Subject: [PATCH 09/15] Bump Microsoft.EntityFrameworkCore.SqlServer from 7.0.0 to 7.0.5 Bumps [Microsoft.EntityFrameworkCore.SqlServer](https://github.com/dotnet/efcore) from 7.0.0 to 7.0.5. - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.0...v7.0.5) --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore.SqlServer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Snappass.NET/Snappass.NET.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index 8e2212f..2f6eaab 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 3965a1c1e2bad55ee7b73538ea2ac7a1ab280176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 03:43:03 +0000 Subject: [PATCH 10/15] Bump System.Data.SQLite from 1.0.116 to 1.0.117 Bumps System.Data.SQLite from 1.0.116 to 1.0.117. --- updated-dependencies: - dependency-name: System.Data.SQLite dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj | 2 +- Snappass.NET/Snappass.NET.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj index b4124ac..7b42af1 100644 --- a/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj +++ b/Snappass.NET.UnitTest/Snappass.NET.UnitTest.csproj @@ -9,7 +9,7 @@ - + all diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index 8e2212f..b65e2a9 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -18,7 +18,7 @@ - + From b093e4f1da380acae37a9fdf9d1455dfc58f02df Mon Sep 17 00:00:00 2001 From: Mathias Koeppel Date: Thu, 18 May 2023 21:20:24 -0700 Subject: [PATCH 11/15] Updates --- Snappass.NET/Properties/serviceDependencies.json | 6 +----- Snappass.NET/Properties/serviceDependencies.local.json | 6 +----- Snappass.NET/Snappass.NET.csproj | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/Snappass.NET/Properties/serviceDependencies.json b/Snappass.NET/Properties/serviceDependencies.json index a4e7aa3..33703d5 100644 --- a/Snappass.NET/Properties/serviceDependencies.json +++ b/Snappass.NET/Properties/serviceDependencies.json @@ -1,7 +1,3 @@ { - "dependencies": { - "secrets1": { - "type": "secrets" - } - } + "dependencies": {} } \ No newline at end of file diff --git a/Snappass.NET/Properties/serviceDependencies.local.json b/Snappass.NET/Properties/serviceDependencies.local.json index 09b109b..33703d5 100644 --- a/Snappass.NET/Properties/serviceDependencies.local.json +++ b/Snappass.NET/Properties/serviceDependencies.local.json @@ -1,7 +1,3 @@ { - "dependencies": { - "secrets1": { - "type": "secrets.user" - } - } + "dependencies": {} } \ No newline at end of file diff --git a/Snappass.NET/Snappass.NET.csproj b/Snappass.NET/Snappass.NET.csproj index 447b5d7..0dcf7f7 100644 --- a/Snappass.NET/Snappass.NET.csproj +++ b/Snappass.NET/Snappass.NET.csproj @@ -17,7 +17,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From a43628559d956d6b4d8203fffff9b73f20dc2e6a Mon Sep 17 00:00:00 2001 From: Robert Daunce Date: Tue, 15 Jun 2021 13:32:17 -0400 Subject: [PATCH 12/15] split storage key and encryption key The .NET port did not convert the storage of encrypted passwords correctly. It was using the encryption key as the dictionary key, storing the encrypted password and encrytion key in the same location. This makes the encrypted password decryptable if someone were to compromise the underlying data store. This commit creates a separate storage key for lookup purposes and does not store the encryption key. A separate token is created that includes the storage key and the encryption key that is only used to generate the URL. See https://github.com/pinterest/snappass/issues/63 for additional conversation on the original source repo. --- .../Controllers/PasswordController.cs | 9 +++-- Snappass.NET/Controllers/ShareController.cs | 8 ++-- Snappass.NET/Encryption.cs | 37 +++++++++++++++---- Snappass.NET/Models/GeneratedPassword.cs | 4 +- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Snappass.NET/Controllers/PasswordController.cs b/Snappass.NET/Controllers/PasswordController.cs index d508bf7..bf1ce4f 100644 --- a/Snappass.NET/Controllers/PasswordController.cs +++ b/Snappass.NET/Controllers/PasswordController.cs @@ -18,13 +18,14 @@ public PasswordController(IMemoryStore memoryStore, ILogger [HttpGet] public IActionResult Preview(string key) { - if (!_memoryStore.Has(key)) + (string storageKey, string encryptionKey) = Encryption.ParseToken(key); + if (!_memoryStore.Has(storageKey)) { - _logger.LogWarning($@"password with key {key} requested, but not found"); + _logger.LogWarning($@"password with key {storageKey} requested, but not found"); return NotFound(); } - string encryptedPassword = _memoryStore.Retrieve(key); - string decrypted = Encryption.Decrypt(encryptedPassword, key); + string encryptedPassword = _memoryStore.Retrieve(storageKey); + string decrypted = Encryption.Decrypt(encryptedPassword, encryptionKey); return View("Preview", new PreviewModel { Key = decrypted }); } } diff --git a/Snappass.NET/Controllers/ShareController.cs b/Snappass.NET/Controllers/ShareController.cs index acb0593..96ed9c3 100644 --- a/Snappass.NET/Controllers/ShareController.cs +++ b/Snappass.NET/Controllers/ShareController.cs @@ -38,9 +38,11 @@ public IActionResult Share(string password, string ttl) _ => throw new ArgumentException("Expected week, day or hour"), }; TimeToLive timeToLive = Parse(ttl); - (string encryptedPassword, string key) = Encryption.Encrypt(password); - _memoryStore.Store(encryptedPassword, key, timeToLive); - var model = new GeneratedPassword { Key = key, BaseUri = GetBaseUrl() }; + string storageKey = Guid.NewGuid().ToString("N").ToUpper(); + (string encryptedPassword, string encryptionKey) = Encryption.Encrypt(password); + _memoryStore.Store(encryptedPassword, storageKey, timeToLive); + string token = Encryption.CreateToken(storageKey, encryptionKey); + var model = new GeneratedPassword { Token = token, BaseUri = GetBaseUrl() }; return View("Shared", model); } } diff --git a/Snappass.NET/Encryption.cs b/Snappass.NET/Encryption.cs index 712ea2c..ca599e9 100644 --- a/Snappass.NET/Encryption.cs +++ b/Snappass.NET/Encryption.cs @@ -5,21 +5,42 @@ namespace Snappass { public class Encryption { - public static (string encryptedPassword, string key) Encrypt(string password) + private static readonly char tokenSeparator = '~'; + + public static (string encryptedPassword, string encryptionKey) Encrypt(string password) { - byte[] keyBytes = SimpleFernet.GenerateKey().UrlSafe64Decode(); + byte[] EncryptionKeyBytes = SimpleFernet.GenerateKey().UrlSafe64Decode(); var passwordBytes = System.Text.Encoding.Unicode.GetBytes(password); - string encrypted = SimpleFernet.Encrypt(keyBytes, passwordBytes); - string key = keyBytes.UrlSafe64Encode(); - return (encrypted, key); + string encryptedPassword = SimpleFernet.Encrypt(EncryptionKeyBytes, passwordBytes); + string encryptionKey = EncryptionKeyBytes.UrlSafe64Encode(); + return (encryptedPassword, encryptionKey); } - public static string Decrypt(string encrypted, string key) + public static string Decrypt(string encryptedPassword, string encryptionKey) { - var keyBytes = key.UrlSafe64Decode(); - var decryptedBytes = SimpleFernet.Decrypt(keyBytes, encrypted, out DateTime _); + var encryptionKeyBytes = encryptionKey.UrlSafe64Decode(); + var decryptedBytes = SimpleFernet.Decrypt(encryptionKeyBytes, encryptedPassword, out DateTime _); var decrypted = decryptedBytes.UrlSafe64Encode().FromBase64String().Replace("\0", ""); return decrypted; } + + public static (string storageKey, string decryptionKey) ParseToken(string token) + { + var tokenFragments = token.Split(tokenSeparator, 2); + var storageKey = tokenFragments[0]; + var decryptionKey = string.Empty; + + if (tokenFragments.Length > 1) + decryptionKey = tokenFragments[1]; + + return (storageKey, decryptionKey); + } + public static string CreateToken(string storageKey, string encryptionKey) + { + var token = string.Join(tokenSeparator, storageKey, encryptionKey); + + return token; + + } } } diff --git a/Snappass.NET/Models/GeneratedPassword.cs b/Snappass.NET/Models/GeneratedPassword.cs index c5c5161..cf0916c 100644 --- a/Snappass.NET/Models/GeneratedPassword.cs +++ b/Snappass.NET/Models/GeneratedPassword.cs @@ -2,8 +2,8 @@ { public class GeneratedPassword { - public string Key { get; set; } + public string Token { get; set; } public string BaseUri { get; set; } - public string Uri => $@"{BaseUri}/Password/{Key}"; + public string Uri => $@"{BaseUri}/Password/{Token}"; } } From da440ed522917d3cf6b1ff58e686864955a4c5c5 Mon Sep 17 00:00:00 2001 From: Robert Daunce Date: Tue, 15 Jun 2021 17:36:30 -0400 Subject: [PATCH 13/15] Fix preview mechanism The .NET port included the password on a hidden form on the initial page request. A button to reveal the password only unhid the form. This caused the initial page request to expire the password, even if it wasn't viewed. The intention of the preview feature was to prevent bots that prefetch the URL from destroying the secret. This commit removes the password from the preview page and adds a new page where the secret is revealed. Now the secret is only destroyed if the secret is revealed. Ported based on https://github.com/pinterest/snappass/pull/100 --- .../Controllers/PasswordController.cs | 12 ++++++--- Snappass.NET/Views/Password/Password.cshtml | 25 +++++++++++++++++++ Snappass.NET/Views/Password/Preview.cshtml | 16 ++---------- Snappass.NET/wwwroot/js/preview.js | 7 ++++-- 4 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 Snappass.NET/Views/Password/Password.cshtml diff --git a/Snappass.NET/Controllers/PasswordController.cs b/Snappass.NET/Controllers/PasswordController.cs index bf1ce4f..238afa5 100644 --- a/Snappass.NET/Controllers/PasswordController.cs +++ b/Snappass.NET/Controllers/PasswordController.cs @@ -16,6 +16,7 @@ public PasswordController(IMemoryStore memoryStore, ILogger } [HttpGet] + [HttpPost] public IActionResult Preview(string key) { (string storageKey, string encryptionKey) = Encryption.ParseToken(key); @@ -24,9 +25,14 @@ public IActionResult Preview(string key) _logger.LogWarning($@"password with key {storageKey} requested, but not found"); return NotFound(); } - string encryptedPassword = _memoryStore.Retrieve(storageKey); - string decrypted = Encryption.Decrypt(encryptedPassword, encryptionKey); - return View("Preview", new PreviewModel { Key = decrypted }); + if (HttpContext.Request.Method == "POST") + { + string encryptedPassword = _memoryStore.Retrieve(storageKey); + string decrypted = Encryption.Decrypt(encryptedPassword, encryptionKey); + return View("Password", new PreviewModel { Key = decrypted }); + } + + return View("Preview"); } } } diff --git a/Snappass.NET/Views/Password/Password.cshtml b/Snappass.NET/Views/Password/Password.cshtml new file mode 100644 index 0000000..30aa282 --- /dev/null +++ b/Snappass.NET/Views/Password/Password.cshtml @@ -0,0 +1,25 @@ +@{ + ViewData["Title"] = "ViewPassword"; + Layout = "~/Views/_Layout.cshtml"; +} +
+
+ +

Save the following secret to a secure location.

+
+
+ +
+ +
+ +
+
+

The secret has now been permanently deleted from the system, and the URL will no longer work. Refresh this page to verify.

+
+
+ diff --git a/Snappass.NET/Views/Password/Preview.cshtml b/Snappass.NET/Views/Password/Preview.cshtml index f52ac7d..1b28aea 100644 --- a/Snappass.NET/Views/Password/Preview.cshtml +++ b/Snappass.NET/Views/Password/Preview.cshtml @@ -1,5 +1,5 @@ @{ - ViewData["Title"] = "ViewPassword"; + ViewData["Title"] = "PreviewPassword"; Layout = "~/Views/_Layout.cshtml"; }
@@ -14,18 +14,6 @@
-
-

Save the following secret to a secure location.

-
- - -
-

The secret has now been permanently deleted from the system, and the URL will no longer work. Refresh this page to verify.

-
- + diff --git a/Snappass.NET/wwwroot/js/preview.js b/Snappass.NET/wwwroot/js/preview.js index eaa7999..fafca51 100644 --- a/Snappass.NET/wwwroot/js/preview.js +++ b/Snappass.NET/wwwroot/js/preview.js @@ -1,6 +1,9 @@ (function () { $('#revealSecret').click(function (e) { - $('#revealed').show(); - $('#revealSecret').prop("disabled", true); + var form = $('
') + .attr('id', 'revealSecretForm') + .attr('method', 'post'); + form.appendTo($('body')); + form.submit(); }); })(); \ No newline at end of file From dfed3b14c6cbd83b21798a2bab7bbad38431d999 Mon Sep 17 00:00:00 2001 From: Robert Daunce Date: Tue, 15 Jun 2021 17:51:13 -0400 Subject: [PATCH 14/15] Quote url to fix equal sign breaking outlook client This was not ported properly to encode the encryption key. See https://github.com/pinterest/snappass/issues/73 --- Snappass.NET/Encryption.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Snappass.NET/Encryption.cs b/Snappass.NET/Encryption.cs index ca599e9..89bd152 100644 --- a/Snappass.NET/Encryption.cs +++ b/Snappass.NET/Encryption.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using Fernet; namespace Snappass @@ -31,13 +32,13 @@ public static (string storageKey, string decryptionKey) ParseToken(string token) var decryptionKey = string.Empty; if (tokenFragments.Length > 1) - decryptionKey = tokenFragments[1]; + decryptionKey = WebUtility.UrlDecode(tokenFragments[1]); return (storageKey, decryptionKey); } public static string CreateToken(string storageKey, string encryptionKey) { - var token = string.Join(tokenSeparator, storageKey, encryptionKey); + var token = string.Join(tokenSeparator, storageKey, WebUtility.UrlEncode(encryptionKey)); return token; From b46270138dbcb7f18c0c1ce0bd8008d3719bf857 Mon Sep 17 00:00:00 2001 From: Robert Daunce Date: Tue, 15 Jun 2021 18:12:49 -0400 Subject: [PATCH 15/15] Added 2 weeks TTL and defaulted TTL to 1 hour --- Snappass.NET/Controllers/ShareController.cs | 3 ++- Snappass.NET/MemoryStore.cs | 12 ++++++++---- Snappass.NET/SqliteStore.cs | 11 +++++++---- Snappass.NET/TimeToLive.cs | 2 +- Snappass.NET/Views/Share/Share.cshtml | 3 ++- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Snappass.NET/Controllers/ShareController.cs b/Snappass.NET/Controllers/ShareController.cs index 96ed9c3..b1e2540 100644 --- a/Snappass.NET/Controllers/ShareController.cs +++ b/Snappass.NET/Controllers/ShareController.cs @@ -35,7 +35,8 @@ public IActionResult Share(string password, string ttl) "week" => TimeToLive.Week, "day" => TimeToLive.Day, "hour" => TimeToLive.Hour, - _ => throw new ArgumentException("Expected week, day or hour"), + "twoweeks" => TimeToLive.TwoWeeks, + _ => throw new ArgumentException("Expected twoweeks, week, day or hour"), }; TimeToLive timeToLive = Parse(ttl); string storageKey = Guid.NewGuid().ToString("N").ToUpper(); diff --git a/Snappass.NET/MemoryStore.cs b/Snappass.NET/MemoryStore.cs index a8146db..3f0ae8e 100644 --- a/Snappass.NET/MemoryStore.cs +++ b/Snappass.NET/MemoryStore.cs @@ -71,18 +71,22 @@ public string Retrieve(string key) TimeToLive.Day => item.StoredDateTime.AddDays(1), TimeToLive.Week => item.StoredDateTime.AddDays(7), TimeToLive.Hour => item.StoredDateTime.AddHours(1), + TimeToLive.TwoWeeks => item.StoredDateTime.AddDays(14), + _ => item.StoredDateTime.AddHours(1), }; DateTime atTheLatest = GetAtTheLatest(item.TimeToLive); if (_dateTimeProvider.Now > atTheLatest) { static string ToString(TimeToLive ttl) => ttl switch { - TimeToLive.Week => "week", - TimeToLive.Day => "day", - TimeToLive.Hour => "hour", + TimeToLive.Week => "1 week", + TimeToLive.Day => "1 day", + TimeToLive.Hour => "1 hour", + TimeToLive.TwoWeeks => "2 weeks", + _ => "1 hour", }; var ttlString = ToString(item.TimeToLive); - _logger.Log(LogLevel.Warning, $@"Tried to retrieve password for key [{key}] after date is expired. Key set at [{item.StoredDateTime}] for 1 [{ttlString}]"); + _logger.Log(LogLevel.Warning, $@"Tried to retrieve password for key [{key}] after date is expired. Key set at [{item.StoredDateTime}] for [{ttlString}]"); _items.Remove(key); // ensure "read-once" is implemented return null; } diff --git a/Snappass.NET/SqliteStore.cs b/Snappass.NET/SqliteStore.cs index 80096b9..c303722 100644 --- a/Snappass.NET/SqliteStore.cs +++ b/Snappass.NET/SqliteStore.cs @@ -46,6 +46,7 @@ public override TimeToLive Parse(object value) 0 => TimeToLive.Hour, 1 => TimeToLive.Day, 2 => TimeToLive.Week, + 3 => TimeToLive.TwoWeeks, _ => TimeToLive.Hour, }; } @@ -103,6 +104,7 @@ FROM SECRET TimeToLive.Day => dateTime.AddDays(1), TimeToLive.Week => dateTime.AddDays(7), TimeToLive.Hour => dateTime.AddHours(1), + TimeToLive.TwoWeeks => dateTime.AddDays(14), _ => dateTime.AddHours(1) }; DateTime atTheLatest = GetAtTheLatest(secret.TimeToLive, secret.StoredDateTime); @@ -110,13 +112,14 @@ FROM SECRET { static string ToString(TimeToLive ttl) => ttl switch { - TimeToLive.Week => "week", - TimeToLive.Day => "day", - TimeToLive.Hour => "hour", + TimeToLive.Week => "1 week", + TimeToLive.Day => "1 day", + TimeToLive.Hour => "1 hour", + TimeToLive.TwoWeeks => "2 weeks", _ => "hour" }; var ttlString = ToString(secret.TimeToLive); - _logger.Log(LogLevel.Warning, $@"Tried to retrieve password for key [{key}] after date is expired. Key set at [{secret.StoredDateTime}] for 1 [{ttlString}]"); + _logger.Log(LogLevel.Warning, $@"Tried to retrieve password for key [{key}] after date is expired. Key set at [{secret.StoredDateTime}] for [{ttlString}]"); Remove(key); return null; } diff --git a/Snappass.NET/TimeToLive.cs b/Snappass.NET/TimeToLive.cs index e5fe43b..82a223e 100644 --- a/Snappass.NET/TimeToLive.cs +++ b/Snappass.NET/TimeToLive.cs @@ -2,6 +2,6 @@ { public enum TimeToLive { - Week, Day, Hour + Week, Day, Hour, TwoWeeks } } diff --git a/Snappass.NET/Views/Share/Share.cshtml b/Snappass.NET/Views/Share/Share.cshtml index 660073c..f274b78 100644 --- a/Snappass.NET/Views/Share/Share.cshtml +++ b/Snappass.NET/Views/Share/Share.cshtml @@ -16,9 +16,10 @@