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

Change signature validation logic to call first without the file content #14849

Merged
merged 5 commits into from
Feb 23, 2021

Conversation

JamesWTruher
Copy link
Member

@JamesWTruher JamesWTruher commented Feb 19, 2021

Only validate the signature with the content if the first non-content validation fails

PR Summary

When ExecutionPolicy is set to require a signature, under some circumstances a signature placed in a file will not execute with a "hash mismatch" error, even though Get-AuthenticodeSignature will return that the signature is valid.
This is because Get-AuthenticodeSignature and our invocation path are not symmetrical. This PR adds the same check that we do in Get-AuthenticodeSignature into our invocation path.

PR Context

PR Checklist

@JamesWTruher JamesWTruher added the WG-Security security related areas such as JEA label Feb 19, 2021
Copy link
Member

@TravisEz13 TravisEz13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is correct.
GetSignature should be called without contents first, because:

  1. The underlying validation should never return a false valid, so the call is safe.
  2. we cannot validate windows signatures, when called WITH contents. So, we should try without contents first.
  3. manipulating the contents makes it more likely to get a false invalid.

Co-authored-by: Robert Holt <rjmholt_msft@outlook.com>
@TravisEz13 TravisEz13 added the CL-Engine Indicates that a PR should be marked as an engine change in the Change Log label Feb 22, 2021
@adityapatwardhan
Copy link
Member

@JamesWTruher Is there a way we can add a test for the change?

Copy link
Contributor

@PaulHigin PaulHigin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change need to be backported to Windows PowerShell?

private static Signature GetSignatureWithEncodingRetry(string path, ExternalScriptInfo script)
{
string verificationContents = System.Text.Encoding.Unicode.GetString(script.OriginalEncoding.GetPreamble()) + script.ScriptContents;
Signature signature = SignatureHelper.GetSignature(path, verificationContents);
// Invoke the SIP directly with the most simple method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is confusing to me, what is the simple method? I think it should say something like 'first try to get a catalog signature, by passing in null content'.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that the missing catalog look up is only part of the problem, and that we should be letting the SIP try to validate with out our "help". @TravisEz13 can perhaps address additional points.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think getting the catalog is only half of it, like James is saying. If we fail to get a catalog signature, we try to get the embedded signature without modifying the content. This should be what we try first. It is the only thing we do in Get-AuthenticodeSignature.

@ghost ghost added the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Feb 22, 2021
@JamesWTruher
Copy link
Member Author

@adityapatwardhan I couldn't think of one other than the tests we have, and I'm not sure why the tests we have didn't find this. It may be that @PaulHigin can figure out a way

@ghost ghost removed the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Feb 22, 2021
@SteveL-MSFT
Copy link
Member

@PaulHigin we initially checked against WinPS and for whatever reason it doesn't fail in WinPS. I compared the code between WinPS and PS7 and don't see any differences in this specific code path so it remains a mystery why it only fails on PS7.

@PaulHigin
Copy link
Contributor

@SteveL-MSFT Hmm, I don't like those kinds of mysteries. Could it be a PInvoke difference between .Net frameworks? But this seems like the right fix since it matches what Get-AuthenticodeSignature does.

@rjmholt
Copy link
Collaborator

rjmholt commented Feb 22, 2021

I think the difference lies here:

Encoding defaultEncoding = ClrFacade.GetDefaultEncoding();

@iSazonov
Copy link
Collaborator

I wonder that Get-AuthenticodeSignature -Content assumes the Content is always in Unicode.

I think the difference lies here:

Encoding defaultEncoding = ClrFacade.GetDefaultEncoding();

It could be so if a test script file is in Unicode but without BOM otherwise StreamReader() detected right an encoding of the file.

@iSazonov
Copy link
Collaborator

iSazonov commented Feb 22, 2021

Although it may be just the same

[System.Text.Encoding] :: Utf8.GetPreamble ()
239
187
191

I mean, now we get the default BOM for Uft8 when it shouldn't be (in GetSignatureWithEncodingRetry()).

@PaulHigin
Copy link
Contributor

I see. This does seem like it could be the culprit. But the comment in GetSignatureWithEncodingRetry says the SIP will (may?) replace with a Unicode BOM when signing, in which case the code should handle it. We should investigate this more.

@adityapatwardhan
Copy link
Member

I am marking this PR as WIP as more discussion is required here.

@adityapatwardhan adityapatwardhan changed the title Change signature validation logic to call first without the file content WIP: Change signature validation logic to call first without the file content Feb 22, 2021
Copy link
Contributor

@PaulHigin PaulHigin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good to me. I feel we can look into the SIP issue separately.

@adityapatwardhan adityapatwardhan changed the title WIP: Change signature validation logic to call first without the file content Change signature validation logic to call first without the file content Feb 23, 2021
@adityapatwardhan adityapatwardhan merged commit 907746c into PowerShell:master Feb 23, 2021
@adityapatwardhan adityapatwardhan added this to the 7.2.0-preview.4 milestone Feb 23, 2021
@ghost
Copy link

ghost commented Mar 16, 2021

🎉v7.2.0-preview.4 has been released which incorporates this pull request.:tada:

Handy links:

@JamesWTruher JamesWTruher deleted the signfix001 branch September 23, 2023 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CL-Engine Indicates that a PR should be marked as an engine change in the Change Log WG-Security security related areas such as JEA
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants