NOTE: This issue was only validated on Linux (RHEL7) but could potentially be an issue on Windows as well, depending on how the history file is stored/used.
Install pwsh, and perform an ls -l on the following file:
~/.local/share/powershell/PSReadLine/ConsoleHost_history.txt
Only the owner should have access to read this file. In it's current configuration, in addition to the owner, both group/everyone can also read this file. Due to the content of this file, only the owner should have read rights by default. With the current permission structure, a threat actor could read/replay the command history and use it for malicious purposes.
The CHMOD file map should be set to 700 or 600 by default.
By default the CHMOD access map on this file is: 664
The above file map grants the owner R/W, the group R/W, and everyone R.
> Name Value
---- -----
PSVersion 6.0.0
PSEdition Core
GitCommitId v6.0.0
OS Linux 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Dec 28 14:23:39 EST 2017
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
FYI, @SteveL-MSFT & @MaximoTrinidad , the item mentioned in #6675 's comment
This is behavior of [System.IO.File]::CreateText("file") which is what PSReadline uses. I checked on my Ubuntu16.04 machine and the default umask is 0002 which results in the permissions you are observing. Changing it to 0022 should get the result you want.
Yes, I agree, that having an umask of 0077 would solve it, but should not rather the files and the directories created by pwsh be more secure by default?
@psmulovics but then you'd have other people complain that PowerShell or .Net is not respecting umask
Just a quick pointer for those who want to change the umask value:
You cannot do it from $PROFILE, because umask is a POSIX-like shell _builtin_ that affects the current process only, so calling something like sh -c 'umask 0022' is an effective _no-op_.
(However, if your default shell is bash and you launch pwsh from there, you can add something like umask 0022 to your ~/.bash_profile (macOS) / ~/.bashrc (Linux) file.)
On _Linux_ system you can change it _globally_ via /etc/profile.
On _macOS_ however, this only works if pwsh is invoked via a POSIX-like shell such as bash (a shell that when launched as a _login_ shell (the default on macOS) sources /etc/profile, which pwsh cannot); in other words: it wouldn't work if you used pwsh as your _default shell_.
@SteveL-MSFT: Do you know of a .NET Core way to do what umask does?
@mklement0 it appears that the recommended way is to use Mono.Posix.NETStandard
Thanks, @SteveL-MSFT.
There is now a v1 (not a beta), and its use from a .NET Core C# project is pretty straightforward.
By contrast, trying to use it from PowerShell turned out to be a major headache:
An incorrect NuGet API URL prevented discovery of NuGet packages with Find-Package / Install-Package - see this SO answer.
Even once the package is successfully downloaded, using it is far from straightforward, for two reasons:
*.dll must be located. *.dll in order for Add-Type -Path to correctly load the assembly.Here's a working solution, whose complexity is disconcerting:
$ErrorActionPreference = 'Stop'; Set-StrictMode -Version 1
if (-not ($IsMacOS -or $IsLinux)) { Throw "Only supported on Unix platforms." }
$packageName = 'Mono.Posix.NETStandard'
$package = Get-Package -ea Ignore $packageName
$wasInstalled = [bool] $package
if (-not $wasInstalled) {
# Install the Nuget package via Install-Package
# Note: Requires installation and correct setup of the Nuget package provider - see https://stackoverflow.com/a/50004706/45375
Write-Verbose "Installing package '$packageName' in user scope..."
# Note: Even though both Install-Package and Get-Package return [Microsoft.PackageManagement.Packaging.SoftwareIdentity] instances,
# the Install-Package output objects do not yet contain the local filesystem path in the .Source property.
$null = Install-Package $packageName -Scope CurrentUser
$package = Get-Package $packageName -Scope CurrentUser
}
# Determine the full path to the platform-appropriate DLL
$osSpec = if ($IsMacOS) {
'osx'
} else { # Linux
$arch = switch -regex (uname -m) {
'x86_64' { 'x64'}
'i.86' { 'x86' }
default { Throw "Unanticipated architecture: $(uname -m)"}
}
'{0}-{1}' -f 'linux', $arch
}
$dllFilePath = "$(Split-Path -Parent $package.Source)/runtimes/$osSpec/lib/netstandard2.0/$packageName.dll"
if (-not $wasInstalled) {
# !! The native helper *.dylib file / *.so is NOT found by default (even though from a .NET Core C# source-code project it is)
# !! and on macOS even setting $env:DYLD_LIBRARY_PATH and $env:DYLD_FALLBACK_LIBRARY_PATH doesn't seem to help.
# !! The only thing that helps is to *symlink* (or copy) the *.dylib file / *.so file into the directory where the *.dll lives
$nativeExt = ('dylib', 'so')[$IsLinux]
Write-Verbose "Linking ../../native/libMonoPosixHelper.$nativeExt to $(Split-Path -Parent $dllFilePath)/"
ln -s ../../native/libMonoPosixHelper.$nativeExt (Split-Path -Parent $dllFilePath)
}
# Load the assembly via the full path to the DLL.
# This makes the types in the Mono.Unix.Native namespace available.
Write-Verbose "Loading assembly '$dllFilePath'..."
Add-Type -Path $dllFilePath
# Finally, call the static `.umask()` method in [Mono.Unix.Native.Syscall]
# The equivalent of umask 0066: only the owning user can read and write.
# Note that the *old* value is output, as a list of symbolic [Mono.Unix.Native.FilePermissions]
# enumeration values.
[Mono.Unix.Native.Syscall]::umask('S_IROTH, S_IWOTH, S_IRGRP, S_IWGRP')
# Print the newly set `umask` value for verification.
sh -c umask
So maybe this is something we should have built-in to PowerShell on *nix: Set-UMask.
@BrucePay: Certainly worth considering, and, while we're at it, let's look at _all_ methods exposed by [Mono.Unix.Native.Syscall] to see which ones we'd expect shell users to use routinely and are therefore worth surfacing via cmdlets.
@mklement0 we should continue this in a new issue rather than this one
Separately, it's worth considering adding better support for loading assemblies from installed NuGet packages to Add-Type - please see #6724.
@SteveL-MSFT: Sounds good; please see #6725.
Most helpful comment
@mklement0 we should continue this in a new issue rather than this one