Skip to content

Web Cmdlets should warn when legacy -Credential is sent over unencrypted connections #5112

Description

Problem

In #5052 we are introducing the new -Authentication parameter which include a terminating error when any scheme other than https:// is provided in the URI. The legacy -Credential usage currently does not offer any warnings or errors when the secrets are sent over an unencrypted connection.

This issue is to track and discuss which method to go with.

Possible Solutions

Add a warning

This solution would add a warning message (via WriteWarning()) that the use could suppress with the -AllowUnencryptedAuthentication parameter. This would likely be a non-breaking change that would simply the user politely when they use the legacy -Credential and something other than 'https://

Add an Error

This is similar to the previous but instead return an error. This could be a terminating or non-terminating error, but either would be a breaking change. A common usage of the web cmdlets is to use -ErrorAction Stop in a try/catch and this would introduce new stops for previously working code if users were sending credentials over HTTP before

Remove the legacy -Credential usage.

The new -Authentication usage has some duplication of functionality in that it does the same thing on its Basic option as the legacy -Credential usage. Legacy -Credential would only sent the Authorization header when the server present an Authorization request where the new method always sends the Authorization header (as many OAuth systems do not present auth realm). This would require some discovery and clean up. I think this is the ultimate choice, but probably not a good candidate for 6.0.0 RTM.

Activity

  1. dragonwolf83 commented on Oct 13, 2017

    @dragonwolf83

    The wording of -AllowUnencryptedAuthentication doesn't make sense for Warning. By issuing a warning, you are by default allowing unencrypted. I propose an -IgnoreUnencryptedWarning should be used if Warning is chosen. The Error proposal should continue with -AllowUnencryptedAuthentication.

  2. markekraus commented on Oct 13, 2017

    @markekraus
    ContributorAuthor

    I disagree with -IgnoreUnencryptedWarning. -AllowUnencryptedAuthentication will already be present and there is no need to add a second parameter to do the same thing. There were already discussions and back and forth on -AllowUnencryptedAuthentication and I think that debate does not need to be revisited.

  3. dragonwolf83 commented on Oct 13, 2017

    @dragonwolf83

    -AllowUnencryptedAuthentication is a parameter switch to do what exactly? I thought it was a new parameter that was pulled out from previous PR specifically for this discussion of whether a Warning or Error should happen if no parameter is specified.

    What I'm suggesting is that for Warning Proposal, it is very confusing and doesn't make any sense. If I run Invoke-WebRequest -Credential and it works with a warning displayed then you have by default allowed it to happen. So why would I need to set -AllowUnencryptedAuthentication? I never would.

    Now, if you want Confirmation to happen so the user interactively chooses yes or no. Then it makes sense to have an -AllowUnencryptedAuthentication switch to hide confirmation and choose yes.

    Error Proposal is fine, I just think the wording doesn't make sense if credentials are still sent with just a warning let the user know it happened.

  4. markekraus commented on Oct 13, 2017

    @markekraus
    ContributorAuthor

    What I'm suggesting is that for Warning Proposal

    And what I'm saying is there is no point in having yet another parameter that does the same thing. If -AllowUnencryptedAuthentication didn't already exist, then yea, maybe something else. But there is no point in two parameters doing the same thing. Seeing both -IgnoreUnencryptedWarning and -AllowUnencryptedAuthentication would be awkward.

    The warning would be temporary. The end game is removing the legacy usage, IMO. For that temporary period of time having using the same parameter even if the wording doesn't suit everyone, is better than adding another parameter that will just end up being removed.

  5. markekraus commented on Oct 13, 2017

    @markekraus
    ContributorAuthor

    -AllowUnencryptedAuthentication is a parameter switch to do what exactly?

    The new -Authentication parameter options give a terminating error for non-https and can only by suppressed with -AllowUnencryptedAuthentication.

  6. dragonwolf83 commented on Oct 13, 2017

    @dragonwolf83

    I think you are separating out logic that shouldn't be separated. -Credential and -Authentication behavior should match when sent over unencrypted. I think that is where my confusion is coming in. Having one error by default and the other give a warning would be inconsistent. So either both error, both warn, or both ask confirmation. Maybe that is what your 3rd proposal about -Credential is about?

    Also, you are not proposing removing the -Credential parameter right, just cleaning up the code on how it used?

  7. markekraus commented on Oct 13, 2017

    @markekraus
    ContributorAuthor

    I think you are separating out logic that shouldn't be separated.

    Having one error by default and the other give a warning would be inconsistent.

    That's to avoid a breaking change now. Ultimately, there will be a breaking change. But, we can go this route with a warning temporarily an avoid breaking it until we have to.

    Maybe that is what your 3rd proposal about -Credential is about?

    That's exactly it. Basically, -Credential has 2 uses now. The legacy use where it is just -Credential and the new use where it is -Authentication Basic -Credential. The legacy use only sends the Authorization header when a web server has issues a 401 and WWW-Authenticate: Basic realm=<realm>. Many APIs and OAuth grant flows require Basic auth without the 401 or WWW-Authenticate: Basic . The legacy never errors. The new usage allows for sending the Authorization header always and it gives a terminating error when you try anything other that HTTPS unless you provide the switch.

    My goal (what I think is the right direction) is to remove the legacy usage and just standardize on the -Authentication parameter. That way we can add more authentication methods which may or may not use the -Credential parameter (such as OAuth/Bearer use of -Token). But that is not a trivial task. For one it is a significant breaking change and for another there is a lot of code cleanup associated with it. So getting that done before 6.0.0 RTM when it's not really a priority is unlikely.

    So that is what the 3rd option is about. It's more of a "do nothing until we do it right and when we can doit right, this is how". But I would rather up the security game in the Web Cmdlets before 6.0.0 RTM even if some of those measure are temporary.

    Also, you are not proposing removing the -Credential parameter right, just cleaning up the code on how it used?

    No, it will stay. But, to use it, in the future you will need to supply -Authentication Basic (or maybe a few other flavors of -Authentication <option> which haven't been discussed yet). For now, the legacy behavior is left in.

  8. markekraus commented on Oct 15, 2017

    @markekraus
    ContributorAuthor

    Digging into this a bit, removing the legacy usage isn't as simple and I thought. HttpClient apparently does some magic authentication for Basic, NTLM, and Digest using these credentials and it handles some automated detection and resolution, something I'd rather not bring into the web cmdlets. Might be able to get as way with a -Authentication BuiltIn or something like that.

  9. SteveL-MSFT commented on Nov 8, 2017

    @SteveL-MSFT
    Member

    @PowerShell/powershell-committee reviewed this. desire is that we can use -Authentication Negotiate (which is default for compat reasons) to handle the builtin dotnet auth. and throwing a terminating error (telling them about -AllowEncryptedAuthentication switch) if -url is "http:" if -AllowUnencryptedAuthentication is not used.

  10. 7 remaining items

  11. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    Mark Kraus (@markekraus) since this deviated a bit from the original expectation from the Committee, let me bring it back up.

  12. markekraus commented on Nov 9, 2017

    @markekraus
    ContributorAuthor

    Thanks! I would have had a more fleshed out proposal for this.. but I didn't plan on breaking this until later, all I wanted for now was possibly an error on -Credential/-UseDefaultCredential on http. but if we are going to break it.. we might as well break it all the way.

  13. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    Can we do this? -Auth is Default if not specified, but meaning of Default changes depending on whether -Cred is used. No cred Default = none, with cred Default = negotiate. There is no explicit none or negotiate for -Auth.

  14. joeyaiello commented on Nov 9, 2017

    @joeyaiello
    Contributor

    Mark Kraus (@markekraus) I'm actually fine with the full break proposal you made, but I think we need another +1.

    Steve Lee (@SteveL-MSFT) that seems a bit harder to follow intuitively. The error messages would have to be really good if we went that route. :)

  15. markekraus commented on Nov 9, 2017

    @markekraus
    ContributorAuthor

    Steve Lee (@SteveL-MSFT) My objection to doing that kind of logic (Default's behavior changing on whether Credential is provided or not) is that it relies on checking for bound parameters as opposed to Parameter value. It's also complicated by -UseDefaultCredential. if we could use parameter sets with the cmdlets, this might have been ok except that it would result in the need for 12 more parameter sets (at least). It's basically the same reason i was against using Negotiate as the default. It leads to a bunch of ugly hacky logic that would normally be offloaded to the parameter binding.

    I also agree with Joey Aiello (@joeyaiello) that its a bit tough to follow. both from a coding and a user perspective.

  16. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    Perhaps for now, the best thing to do is simply return an error if -AllowUnencryptedAuth isn't used and the -URI is http. Let's leave the other discussion for now which means we'll just have to have that inconsistency.

  17. markekraus commented on Nov 9, 2017

    @markekraus
    ContributorAuthor

    Steve Lee (@SteveL-MSFT) that is certainly my minimum ask.

    The breaking change for -Credential, is that something that would be possibly for 6.1/6.2? or is that something that would need to tabled until the next major version?

  18. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    Mark Kraus (@markekraus) ideally, I'd like to have telemetry in the future to show that only a small set of customers were using the legacy -Credential with PSCore6 so we can deprecate it and eventually remove it. At this point, we can worry about that later and accept a possibility that we have to just live with it.

  19. markekraus commented on Nov 9, 2017

    @markekraus
    ContributorAuthor

    Steve Lee (@SteveL-MSFT) my only fear is that the situations where -Credential and -UseDefaultCredentials would be used also don't lend themselves well to telemetry: internal applications. They are currently the only means for NTLM and Digest authentication and those kinds of sites and the automation working against them may not have internet access to dial home. I'd rather keep it by breaking the current usage and move it to the new -Authentication usage than to break access to legacy systems. *shrugs

    But, I'm OK with a PR for just the error on non-https -Uri without -AllowUnencryptedAuth for now and living with the legacy behavior.

  20. markekraus commented on Nov 10, 2017

    @markekraus
    ContributorAuthor

    #5402 for the non-HTTPS -Credential (legacy) and -UseDefaultCredentials errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Breaking-Changebreaking change that may affect usersIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifIssue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.WG-Cmdletsgeneral cmdlet issues

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions