-
Notifications
You must be signed in to change notification settings - Fork 7.2k
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
Conversation
There was a problem hiding this 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:
- The underlying validation should never return a false valid, so the call is safe.
- we cannot validate windows signatures, when called WITH contents. So, we should try without contents first.
- manipulating the contents makes it more likely to get a false invalid.
…ent. Only validate the signature with the content if the first non-content validation fails
Co-authored-by: Ilya <darpa@yandex.ru>
45ba910
to
72e4cd1
Compare
Co-authored-by: Robert Holt <rjmholt_msft@outlook.com>
@JamesWTruher Is there a way we can add a test for the change? |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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'.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
@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 |
@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. |
@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 |
I think the difference lies here:
|
I wonder that
It could be so if a test script file is in Unicode but without BOM otherwise StreamReader() detected right an encoding of the file. |
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 |
I see. This does seem like it could be the culprit. But the comment in |
I am marking this PR as WIP as more discussion is required here. |
There was a problem hiding this 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.
🎉 Handy links: |
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 inGet-AuthenticodeSignature
into our invocation path.PR Context
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.(which runs in a different PS Host).