Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporarily disabling command history #2698

Closed
JVimes opened this issue Jul 22, 2021 · 19 comments
Closed

Temporarily disabling command history #2698

JVimes opened this issue Jul 22, 2021 · 19 comments
Labels
Resolution-Declined The enhancement request is declined.

Comments

@JVimes
Copy link

JVimes commented Jul 22, 2021

Description of the new feature/enhancement

It would be nice if there were a concise way to disable/enable recording command history. This would be useful to keep sensitive data out of the history.

I know there's a need for this feature because hundreds of StackOverflow users are looking for a way to remove sensitive data from the history.

Just setting HistorySaveStyle to "SaveNothing" doesn't satisfy this. The sensitive data gets saved again when turning history back on. There's no window of time whose commands don't eventually end up in the history.

Proposed technical implementation details

One idea

Disable-PSReadlineHistory
Enable-PSReadlineHistory

The user could sandwich the sensitive command between these calls.

Another idea

Make it part of an existing PSReadLine command. As previously mentioned, disabling/enabling via HistorySaveStyle does not work (sensitive info still gets saved).

@JVimes JVimes added the Issue-Enhancement It's a feature request. label Jul 22, 2021
@ghost ghost added the Needs-Triage 🔍 It's a new issue that core contributor team needs to triage. label Jul 22, 2021
@lzybkr
Copy link
Member

lzybkr commented Jul 25, 2021

The default AddToHistoryHandler has some heuristics to avoid saving credentials in your history, but you can easily use your own custom handler. Personally I use:

Set-PSReadLineOption -AddToHistoryHandler {
        param([string]$line)
        return $line.Length -gt 3 -and $line[0] -ne ' ' -and $line[0] -ne ';'
    }

This lets me put a space at the beginning of the line or a semi-colon at the end to suppress adding to history. It also avoids adding short commands.

@JVimes
Copy link
Author

JVimes commented Jul 25, 2021

That's good to learn, @lzybkr, it could be handy.

It's just hard to sell my office on PowerShell when something like this requires plumbing rather than a real, readable command.

@lzybkr
Copy link
Member

lzybkr commented Jul 26, 2021

Commands are easily implemented, or you could wrap Set-PSReadLineOption easily enough, but I don't think they would get much use.

Disabling history briefly should feel very interactive, and entering a command to disable, then re-enable feels clunky.

@JVimes
Copy link
Author

JVimes commented Jul 26, 2021

Whatever the implementation, it will get a lot of use. Extending Set-PSReadLineOption would be a little less readable but I'd be happy enough with it.

@lzybkr
Copy link
Member

lzybkr commented Jul 26, 2021

PSReadLine has always had the capability of disabling history (via my suggestion or Set-PSReadLineOption) so I don't really think something new will see a lot of adoption.

Also note that my suggestion on ignoring commands starting with a space is exactly what folks coming from bash or zsh are used to.

Wrappers might look like:

function Disable-PSReadLineHistory {
    $global:PSReadLineOldHistorySaveStyle = (Get-PSReadLineOption).HistorySaveStyle
    Set-PSReadLineOption -HistorySaveStyle SaveNothing
}

function Enable-PSReadLineHistory {
    # Only change the history style if we previously saved it in `Disable-PSReadLineHistory`
    if (Test-Path variable:PSReadLineOldHistorySaveStyle) {
        Set-PSReadLineOption -HistorySaveStyle $global:PSReadLineOldHistorySaveStyle
    }
}

@JVimes
Copy link
Author

JVimes commented Jul 26, 2021

I guess I just disagree, It's not "good enough as is" and we shouldn't make each user add plumbing for something conceptually simple.

@progalgo
Copy link

progalgo commented Apr 8, 2022

Maybe a great idea would be to introduce a new context for inputting sensitive commands? Analogous to incognito web browsing experience.

@daxian-dbw daxian-dbw added Resolution-Declined The enhancement request is declined. and removed Issue-Enhancement It's a feature request. Needs-Triage 🔍 It's a new issue that core contributor team needs to triage. labels Apr 12, 2022
@daxian-dbw
Copy link
Member

I agree with @lzybkr's comments above. It can be even simpler as the following, which was already suggested in the stackoverflow question/comments. I think the main confusion comes from the fact that the PSReadLine uses a different history cache/persistence from the built-in PowerShell *-History commands, which has been documented in about_History.

## disable saving history to file
Set-PSReadLineOption -HistorySaveStyle SaveNothing

## enable saving history to file with the default style
Set-PSReadLineOption -HistorySaveStyle SaveIncrementally

@Hrxn
Copy link
Contributor

Hrxn commented Apr 28, 2022

The default AddToHistoryHandler has some heuristics to avoid saving credentials in your history, but you can easily use your own custom handler. Personally I use:

Set-PSReadLineOption -AddToHistoryHandler {
        param([string]$line)
        return $line.Length -gt 3 -and $line[0] -ne ' ' -and $line[0] -ne ';'
    }

This lets me put a space at the beginning of the line or a semi-colon at the end to suppress adding to history. It also avoids adding short commands.

How's that supposed to work?
It both checks at the same index in $line?

Also, where can I find this default heuristic?

Is it this?

private string MaybeAddToHistory(
string result,
List<EditItem> edits,
int undoEditIndex,
bool fromDifferentSession = false,
bool fromInitialRead = false)

@daxian-dbw
Copy link
Member

@JVimes
Copy link
Author

JVimes commented Oct 14, 2022

⚠ "-HistorySaveStyle SaveNothing" does not work in practice

# Turn off history
Set-PSReadLineOption -HistorySaveStyle SaveNothing

# 👉 Commands here *are* saved to history (on shell close, because of the next line).

# Turn history back on
Set-PSReadLineOption -HistorySaveStyle SaveIncrementally

@kapsiR
Copy link

kapsiR commented Feb 21, 2023

Also note that my suggestion on ignoring commands starting with a space is exactly what folks coming from bash or zsh are used to.

@lzybkr @daxian-dbw Would it be an option to treat the space-behavior as sensitive in the default GetDefaultAddToHistoryOption?

If we use the custom handler as described above, we loose the default behavior for e.g. secret ... (this gets into history then)

@daxian-dbw
Copy link
Member

@kapsiR You can save the GetDefaultAddToHistoryOption to variable, and call it first within your custom handler -- if the return value is AddToHistoryOption.MemoryOnly, then just return that; if the return value is AddToHistoryOption.MemoryAndFile, then apply your custom logic and decide whether you want to skip that particular item.

@kapsiR
Copy link

kapsiR commented Feb 22, 2023

Thanks @daxian-dbw 🙏

For anyone looking for the same:

$defaultHistoryHandler = (Get-PSReadLineOption).AddToHistoryHandler;
Set-PSReadLineOption -AddToHistoryHandler {
    param([string]$line)
    
    $defaultHandlerResult = $defaultHistoryHandler.Invoke($line)
    if ($defaultHandlerResult -eq "MemoryAndFile")
    {
        return $line.Length -gt 3 -and $line[0] -ne ' ' -and $line[0] -ne ';'
    }
    
    return $defaultHandlerResult;    
}

@Hrxn
Copy link
Contributor

Hrxn commented Feb 22, 2023

To reiterate my comment from above, the linked example for a custom handler, i.e.

Set-PSReadLineOption -AddToHistoryHandler {
        param([string]$line)
        return $line.Length -gt 3 -and $line[0] -ne ' ' -and $line[0] -ne ';'
    }

does not work as described

This lets me put a space at the beginning of the line or a semi-colon at the end to suppress adding to history. It also avoids adding short commands.

.. unless there's some GetBufferState() dark magic going on in the background?

Because otherwise the check at the beginning of the line is correct, but the semi-colon at the end of the line would be $line[-1] -ne ';', or what am I missing here?

@Hrxn
Copy link
Contributor

Hrxn commented Feb 22, 2023

Warning for future readers, HistorySaveStyle does not turn off/on history in real time; the sensitive data is still saved on shell close.

Set-PSReadLineOption -HistorySaveStyle SaveNothing
# commands entered here are saved to history on shell close (because of the next line)
Set-PSReadLineOption -HistorySaveStyle SaveIncrementally

Uh, not sure what you mean here. Set-PSReadLineOption -HistorySaveStyle SaveNothing does turn off saving history in real-time (?).

If you use this, nothing gets stored into the on-disk history store of PSReadLine (which you can find with (Get-PSReadLineOption).HistorySavePath) anymore.

What might be the source of the confusion here are the different history options as defined by this enum here:

PS C:\Windows\Temp> [enum]::GetNames([Microsoft.PowerShell.AddToHistoryOption])
SkipAdding
MemoryOnly
MemoryAndFile
PS C:\Windows\Temp>

So, there's still the Memory Only type of PSReadLine history, which does not get turned off by the command above,
and is actually kinda useful, in my opinion.

If you want to clear that history (and only the history in memory, not the permanent history stored on disk), simply use this command here: [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()

@daxian-dbw
Copy link
Member

@Hrxn Regarding the semi-colon, that should be a typo. You can change it to $line[-1] as you did to check on the trailing semi-colon.

@Hrxn
Copy link
Contributor

Hrxn commented Feb 22, 2023

Yes, that's what I was trying to say, basically 😄

@koyuyesil
Copy link

Cok can sıkıcı geçmiş komutlar silinmiyor sürekli birkaç komut takılı kalıyor vscode kullanıyorum alakalı olabilir mi?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution-Declined The enhancement request is declined.
Projects
None yet
Development

No branches or pull requests

7 participants