Skip to content

Commit 02fb7d4

Browse files
btiteuxveler
andauthored
Updated extensions manager to handle CWE-22 & CWE-23 (#1643)
* Updated extensions manager to handle CWE-22 & CWE-23 * Fixed path on Linux and Mac * Updated CI * Update Xcode version to 26.1.1 in CI workflow --------- Co-authored-by: Etienne Baudoux <[email protected]>
1 parent bfeafa7 commit 02fb7d4

File tree

13 files changed

+304
-75
lines changed

13 files changed

+304
-75
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ jobs:
3838
run: ./build.cmd RunTests
3939
macos-latest:
4040
name: macOS
41-
runs-on: macos-14
41+
runs-on: macos-15
4242
timeout-minutes: 30
4343
steps:
44-
- name: Set to use Xcode 15.1
44+
- name: Set to use Xcode 26.1.1
4545
uses: maxim-lobanov/setup-xcode@v1
4646
with:
47-
xcode-version: '15.1'
47+
xcode-version: '26.1.1'
4848
- uses: actions/checkout@v3
4949
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
5050
uses: actions/cache@v3

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,7 @@ bld/
441441
[Oo]bj/
442442
# [Oo]ut/
443443
[Ll]og/
444-
[Ll]ogs/
444+
[Ll]ogs/
445+
446+
# TestData
447+
!**/**/TestData/**

src/Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<PackageVersion Include="NuGet.Packaging" Version="6.9.1" />
3535
<PackageVersion Include="Nuke.Common" Version="8.0.0" />
3636
<PackageVersion Include="OneOf" Version="3.0.271" />
37-
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.5" />
37+
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.12" />
3838
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
3939
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
4040
<PackageVersion Include="System.ComponentModel.Composition" Version="$(DotNetVersion)" />

src/app/dev/DevToys.Blazor/BuiltInTools/ExtensionsManager/ExtensionInstallationManager.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ internal static async Task<ExtensionInstallationResult> InstallExtensionAsync(Sa
9898
if (Directory.Exists(potentialExtensionInstallationPath))
9999
{
100100
// Extension is already installed.
101-
return new(AlreadyInstalled: true, nuspecReader, ExtensionInstallationPath: string.Empty);
101+
return new(true, nuspecReader, string.Empty);
102102
}
103103
}
104104

@@ -112,11 +112,22 @@ string extensionInstallationPath
112112
{
113113
if (!pathToExclude.Any(path => packagedFile.Contains(path, StringComparison.CurrentCultureIgnoreCase)))
114114
{
115-
reader.ExtractFile(packagedFile, Path.Combine(extensionInstallationPath, packagedFile), null);
115+
// Security: Prevent path traversal vulnerability (CWE-22 & CWE-23).
116+
string fullTargetPath = Path.GetFullPath(Path.Combine(extensionInstallationPath, packagedFile));
117+
string fullPluginPath = Path.GetFullPath(extensionInstallationPath);
118+
119+
if (!fullTargetPath.StartsWith(fullPluginPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
120+
{
121+
Directory.Delete(extensionInstallationPath, true);
122+
logger.LogCritical("Security violation: Extension '{packagedFile}' contains path traversal sequence", nuspecReader.GetId());
123+
return new(nuspecReader, $"Security violation: Extension '{nuspecReader.GetId()}' contains path traversal sequence");
124+
}
125+
126+
reader.ExtractFile(packagedFile, fullTargetPath, null);
116127
}
117128
}
118129

119-
return new(AlreadyInstalled: false, nuspecReader, extensionInstallationPath);
130+
return new(false, nuspecReader, extensionInstallationPath);
120131
}
121132

122133
internal static async Task<bool> CheckForAnyUpdateAsync(IWebClientService webClientService)

src/app/dev/DevToys.Blazor/BuiltInTools/ExtensionsManager/ExtensionInstallationResult.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
namespace DevToys.Blazor.BuiltInTools.ExtensionsManager;
44

5-
internal record ExtensionInstallationResult(bool AlreadyInstalled, NuspecReader NuspecReader, string ExtensionInstallationPath)
5+
internal class ExtensionInstallationResult
66
{
7+
internal bool HasSucceeded => string.IsNullOrWhiteSpace(ErrorMessage);
8+
internal bool AlreadyInstalled { get; }
9+
internal NuspecReader NuspecReader { get; }
10+
internal string ExtensionInstallationPath { get; } = string.Empty;
11+
internal string ErrorMessage { get; } = string.Empty;
12+
13+
internal ExtensionInstallationResult(NuspecReader nuspecReader, string errorMessage)
14+
{
15+
ErrorMessage = errorMessage;
16+
NuspecReader = nuspecReader;
17+
}
18+
19+
internal ExtensionInstallationResult(bool alreadyInstalled, NuspecReader nuspecReader, string extensionInstallationPath)
20+
{
21+
AlreadyInstalled = alreadyInstalled;
22+
NuspecReader = nuspecReader;
23+
ExtensionInstallationPath = extensionInstallationPath;
24+
}
725
}
26+

0 commit comments

Comments
 (0)