this passes all the tests
This commit is contained in:
parent
8e43c9d8ce
commit
2445cedb92
|
@ -84,8 +84,12 @@ namespace TerminalAppLocalTests
|
||||||
|
|
||||||
void TrustCommandlineTests::WslTests()
|
void TrustCommandlineTests::WslTests()
|
||||||
{
|
{
|
||||||
|
Log::Comment(L"We are explicitly deciding to not auto-approve "
|
||||||
|
L"`wsl.exe -d distro`-like commandlines. If we change this"
|
||||||
|
L" policy, remove this test.");
|
||||||
|
|
||||||
VERIFY_IS_FALSE(trust(L"C:\\Windows\\System32\\wsl"));
|
VERIFY_IS_FALSE(trust(L"C:\\Windows\\System32\\wsl"));
|
||||||
VERIFY_IS_FALSE(trust(L"C:\\Windows\\System32\\wsl.exe"));
|
VERIFY_IS_TRUE(trust(L"C:\\Windows\\System32\\wsl.exe"), L"This we will trust though, since it's an exe in system32");
|
||||||
VERIFY_IS_FALSE(trust(L"C:\\Windows\\System32\\wsl.exe -d Ubuntu"));
|
VERIFY_IS_FALSE(trust(L"C:\\Windows\\System32\\wsl.exe -d Ubuntu"));
|
||||||
VERIFY_IS_FALSE(trust(L"wsl.exe"));
|
VERIFY_IS_FALSE(trust(L"wsl.exe"));
|
||||||
}
|
}
|
||||||
|
@ -94,5 +98,8 @@ namespace TerminalAppLocalTests
|
||||||
{
|
{
|
||||||
VERIFY_IS_TRUE(trust(L"%ProgramFiles%\\PowerShell\\7\\pwsh.exe"));
|
VERIFY_IS_TRUE(trust(L"%ProgramFiles%\\PowerShell\\7\\pwsh.exe"));
|
||||||
VERIFY_IS_TRUE(trust(L"%LOCALAPPDATA%\\Microsoft\\WindowsApps\\pwsh.exe"));
|
VERIFY_IS_TRUE(trust(L"%LOCALAPPDATA%\\Microsoft\\WindowsApps\\pwsh.exe"));
|
||||||
|
VERIFY_IS_TRUE(trust(L"%ProgramFiles%\\PowerShell\\10\\pwsh.exe"));
|
||||||
|
VERIFY_IS_TRUE(trust(L"%ProgramFiles%\\PowerShell\\7.1.5\\pwsh.exe"));
|
||||||
|
VERIFY_IS_FALSE(trust(L"%ProgramFiles%\\PowerShell\\7\\pwsh.exe bad-stuff pwsh.exe"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1526,19 +1526,19 @@ namespace winrt::TerminalApp::implementation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::filesystem::path fullCommandlinePath{
|
const std::wstring fullCommandline{
|
||||||
wil::ExpandEnvironmentStringsW<std::wstring>(commandLine.data())
|
wil::ExpandEnvironmentStringsW<std::wstring>(commandLine.data())
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fullCommandlinePath.wstring().size() > systemDirectory.size())
|
if (fullCommandline.size() > systemDirectory.size())
|
||||||
{
|
{
|
||||||
// Get the first part of the executable path
|
// Get the first part of the executable path
|
||||||
const auto start = fullCommandlinePath.wstring().substr(0, systemDirectory.size());
|
const auto start = fullCommandline.substr(0, systemDirectory.size());
|
||||||
// Doing this as an ASCII only check might be wrong, but I'm
|
// Doing this as an ASCII only check might be wrong, but I'm
|
||||||
// guessing if system32 isn't at X:\windows\system32... this isn't
|
// guessing if system32 isn't at X:\windows\system32... this isn't
|
||||||
// the only thing that is going to be sad in Windows.
|
// the only thing that is going to be sad in Windows.
|
||||||
const auto pathEquals = til::equals_insensitive_ascii(start, systemDirectory);
|
const auto pathEquals = til::equals_insensitive_ascii(start, systemDirectory);
|
||||||
if (pathEquals && std::filesystem::exists(fullCommandlinePath))
|
if (pathEquals && std::filesystem::exists(std::filesystem::path{ fullCommandline }))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1547,97 +1547,73 @@ namespace winrt::TerminalApp::implementation
|
||||||
// TODO! Remove the WSL allowing. it's trivial to insert some malicious
|
// TODO! Remove the WSL allowing. it's trivial to insert some malicious
|
||||||
// stuff into WSL, via .bash_profile, so we're not giving them the (y)
|
// stuff into WSL, via .bash_profile, so we're not giving them the (y)
|
||||||
|
|
||||||
|
// is does executablePath start with %ProgramFiles%\\PowerShell, and end
|
||||||
|
// with `pwsh.exe`?
|
||||||
|
const std::vector<std::filesystem::path> powershellCoreRoots
|
||||||
|
{
|
||||||
|
// Always look in "%LOCALAPPDATA%\Microsoft\WindowsApps", which is
|
||||||
|
// where the pwsh.exe execution alias lives.
|
||||||
|
{ wil::ExpandEnvironmentStringsW<std::wstring>(L"%LOCALAPPDATA%\\Microsoft\\WindowsApps") },
|
||||||
|
|
||||||
|
// Always look in "%ProgramFiles%\PowerShell"
|
||||||
|
{ wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles%\\PowerShell") },
|
||||||
|
|
||||||
|
#if defined(_M_AMD64) || defined(_M_ARM64) // No point in looking for WOW if we're not somewhere it exists
|
||||||
|
{ wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles(x86)%\\PowerShell") },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_M_ARM64) // same with ARM
|
||||||
|
{
|
||||||
|
wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles(Arm)%\\PowerShell")
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
// TODO! CommandlineToArgv to get the executable from the commandline.
|
// TODO! CommandlineToArgv to get the executable from the commandline.
|
||||||
// If there's one argc, and it's parent path is %ProgramFiles%, and it
|
// If there's one argc, and it's parent path is %ProgramFiles%, and it
|
||||||
// ends in pwsh.exe, then it's fine.
|
// ends in pwsh.exe, then it's fine.
|
||||||
|
|
||||||
// Also, if the path is literally
|
// const auto terminator{ commandLine.find_first_of(LR"(" )", 1) }; // look past the first character in case it starts with "
|
||||||
// %SystemRoot%\System32\wsl.exe -d <distro name>
|
// const auto start{ til::at(commandLine, 0) == L'"' ? 1 : 0 };
|
||||||
// then allow it.
|
// const std::filesystem::path executablePath{ commandLine.substr(start, terminator - start) };
|
||||||
|
// const auto executableFilename{ executablePath.filename().wstring() };
|
||||||
|
|
||||||
// Largely stolen from _tryMangleStartingDirectoryForWSL in ConptyConnection.
|
const std::filesystem::path exePath{ fullCommandline };
|
||||||
// Find the first space, quote or the end of the string -- we'll look
|
exePath;
|
||||||
// for wsl before that.
|
|
||||||
const auto terminator{ commandLine.find_first_of(LR"(" )", 1) }; // look past the first character in case it starts with "
|
|
||||||
const auto start{ til::at(commandLine, 0) == L'"' ? 1 : 0 };
|
|
||||||
const std::filesystem::path executablePath{ commandLine.substr(start, terminator - start) };
|
|
||||||
const auto executableFilename{ executablePath.filename().wstring() };
|
|
||||||
|
|
||||||
if (executableFilename == L"wsl" || executableFilename == L"wsl.exe")
|
for (const auto& pwshRoot : powershellCoreRoots)
|
||||||
{
|
{
|
||||||
// We've got a WSL -- let's just make sure it's the right one.
|
// Is the commandline's length (root.length + 8 + 3) characters long?
|
||||||
if (executablePath.has_parent_path())
|
// * root.length: Length of the parent directory
|
||||||
{
|
// * 8: pwsh.exe
|
||||||
if (executablePath.parent_path().wstring() != systemDirectory)
|
// * 3: `/7/` (or some other version number)
|
||||||
{
|
//
|
||||||
return false; // it wasn't in system32!
|
// NO
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Unqualified WSL, this is dangerous, so return false.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get everything after the wsl.exe
|
// Does the commandline start with this root, and end with pwsh.exe?
|
||||||
const auto arguments{ terminator == std::wstring_view::npos ?
|
const auto startsWithRoot{ til::starts_with(fullCommandline, pwshRoot.c_str()) };
|
||||||
std::wstring_view{} :
|
// const auto endsWithPwsh{ til::ends_with(fullCommandline, L"pwsh.exe") };
|
||||||
commandLine.substr(terminator + 1) };
|
const auto endsWithPwsh{ exePath.filename() == L"pwsh.exe" };
|
||||||
const auto dashD{ arguments.find(L"-d ") };
|
// Is the filename of the exe `pwsh.exe`
|
||||||
|
if (startsWithRoot && endsWithPwsh)
|
||||||
// If we found a "-d " IMMEDIATELY AFTER wsl.exe. If it wasn't
|
|
||||||
// immediately after, it could have been `wsl.exe --doSomethingEvil`
|
|
||||||
if (dashD == 0)
|
|
||||||
{
|
{
|
||||||
// Using the string following "-d "...
|
return true;
|
||||||
const auto afterDashD{ arguments.substr(dashD + 3) };
|
|
||||||
// Find the next space
|
|
||||||
const auto afterFirstWord = afterDashD.find(L" ");
|
|
||||||
// if that space _wasn't_ at the end of the commandline, then
|
|
||||||
// there were some other args. That means it was `wsl -d distro
|
|
||||||
// anything`, and we should ask the user.
|
|
||||||
//
|
|
||||||
// So if it was at the end of the commandline, then there were
|
|
||||||
// no other args besides the distro name.
|
|
||||||
if (afterFirstWord == std::wstring::npos)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (executableFilename == L"pwsh" || executableFilename == L"pwsh.exe")
|
|
||||||
{
|
|
||||||
// is does executablePath start with %ProgramFiles%\\PowerShell?
|
|
||||||
const std::vector<std::filesystem::path> powershellCoreRoots
|
|
||||||
{
|
|
||||||
// Always look in "%ProgramFiles%
|
|
||||||
{ wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles%\\PowerShell") },
|
|
||||||
|
|
||||||
#if defined(_M_AMD64) || defined(_M_ARM64) // No point in looking for WOW if we're not somewhere it exists
|
// if (executableFilename == L"pwsh" || executableFilename == L"pwsh.exe")
|
||||||
{ wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles(x86)%\\PowerShell") },
|
// {
|
||||||
#endif
|
// // Is the path to the commandline actually exactly one of the
|
||||||
|
// // versions that exists in this directory?
|
||||||
#if defined(_M_ARM64) // same with ARM
|
// for (const auto& versionedDir : std::filesystem::directory_iterator(pwshRoot))
|
||||||
{
|
// {
|
||||||
wil::ExpandEnvironmentStringsW<std::wstring>(L"%ProgramFiles(Arm)%\\PowerShell")
|
// const auto versionedPath = versionedDir.path();
|
||||||
}
|
// if (executablePath.parent_path() == versionedPath)
|
||||||
#endif
|
// {
|
||||||
};
|
// return true;
|
||||||
|
// }
|
||||||
for (const auto& pwshRoot : powershellCoreRoots)
|
// }
|
||||||
{
|
// }
|
||||||
// Is the path to the commandline actually exactly one of the
|
|
||||||
// versions that exists in this directory?
|
|
||||||
for (const auto& versionedDir : std::filesystem::directory_iterator(pwshRoot))
|
|
||||||
{
|
|
||||||
const auto versionedPath = versionedDir.path();
|
|
||||||
if (executablePath.parent_path() == versionedPath)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue