CrowdStrike / psfalcon

PowerShell for CrowdStrike's OAuth2 APIs
The Unlicense
360 stars 67 forks source link

ClientSecret is a plaintext [string]. Use [securestring] instead? #42

Closed finackninja closed 3 years ago

finackninja commented 3 years ago

I noticed in oauth2.ps1 that the ClientSecret isn't being stored in memory as a [securestring]. I would recommend doing that.

I have a code sample that should handle the prompt when a user didn't supply the ClientSecret as a parameter, but I'm not familiar with dynamic parameters in PowerShell so I'm not sure how to handle it if it is supplied as a parameter.

bk-cs commented 3 years ago

Earlier versions used [SecureString], but I took that out when I realized that it is not encrypted on anything other than Windows. I don't want to give any illusion of client secret security, especially when the client secret can be captured by the Windows Event Log during the token request.

The PowerShell Secret Management module looks like a much better option for storing credentials as it offers cross-platform encryption. Once I get some time to review, I plan on seeing whether that can be easily integrated into the token mechanisms within PSFalcon.

finackninja commented 3 years ago

I don't necessarily agree that using [securestring] is an illusion (at least not on Windows), but I certainly do understand your reasoning and do not dispute your claims. In fact I see that Microsoft discourages its use too; however, it doesn't offer suggested alternatives other than to not use passwords.

Thanks!

bk-cs commented 3 years ago

Thanks, and I appreciate your feedback and suggestion!

I thought [SecureString] was the best option initially, since it offers encryption and "over the shoulder" protection, but without encryption being present on Linux/Mac I was more concerned about a false sense of security than protecting "over the shoulder" viewing of a client secret. Since OAuth2 API clients are disposable, I figured it was easier to replace them if any concerns of compromise were present.

The earlier versions of PSFalcon effectively used [SecureString] to blank out the client secret during input, but then reversed it whenever passing the secret to a command... something that a malicious actor could use to reverse it just as easily using one line of code:

[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString))

On Windows (as you mentioned) this is protected if you're not running as the user that created the [SecureString], but on Linux/Mac it can be done by anyone with access to the string.

From the initial reading I've done, the Secret Management module should provide encryption no matter the platform and if you're interested you should be able to use it independently and pass ClientId/ClientSecret/Cloud/MemberCID to Request-FalconToken. If you decide to do that, I'd love your feedback from that experience because it would be helpful for implementing a more formal integration between that module and PSFalcon.

finackninja commented 3 years ago

The earlier versions of PSFalcon effectively used [SecureString] to blank out the client secret during input, but then reversed it whenever passing the secret to a command... something that a malicious actor could use to reverse it just as easily using one line of code:

On PowerShell Core (v6+), it's even simpler!

$SecureString | ConvertFrom-SecureString -AsPlainText

I haven't come across the SecretManagement module before. I'll have to look into it.

I do have my own (non-public) PsFalconHelper module that uses PsFalcon as middleware. In my module, I have a Request-FalconTokenAuto (formerly Get-CsTokenAuto) that uses a [pscredential] object stored as an XML file in the user profile for the API client ID and secret. In this way the user only has to enter the client ID and secret once: the very first time they run it. After that, it's stored encrypted on disk in the user profile. You just call Request-FalconTokenAuto and it reads from the file and gets a token through your Request-FalconToken cmdlet.

bk-cs commented 3 years ago

That's funny--I had a command with the first iteration of PSFalcon v2 that did the same thing. I'm hoping the SecretManagement module will offer the same results (plus it might store the Cloud and MemberCid values too).