-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Prompting for mandatory parameters mishandles [bool], [switch], [hashtable], and [scriptblock] parameters #4068
Comments
Prompting is by design not interpreted as PowerShell - the justification being security. From the prompt, it doesn't feel like you're being asked for valid PowerShell (and indeed you aren't, e.g. you can enter a string with spaces and not need quotes), so you might input something that would have unfortunate consequences if it were interpreted as PowerShell. Also - if this were to change, care would be needed to ensure it doesn't create a way around restricted language mode. There was some discussion about special casing true/false and variants, I don't recall any conclusions. |
Indeed, you shouldn't be able to enter just any expression. What you should be able to enter, though, is tokens that successfully - and meaningfully - bind to the parameter triggering the prompt. If that condition cannot be met, even putting up the prompt is a waste of the user's time and frustration is very likely to ensue. |
P.S.: In the case of a mandatory If you mean to input The larger issue is that the prompting feature in its present form is both incomplete (see this issue and the inability to enter |
On second thought:
Arguably, the very same rules as in argument mode should apply (even though the user supplying literals is the far likelier scenario). Yes, values with spaces being implicitly considered a single argument is unique to prompting, however. From a security perspective, however, there's no good reason to accept less than what could be passed directly as arguments. Someone who wanted to be more restrictive should implement custom prompting. That said, the following is, of course, a valid concern that needs to be addressed, as you state:
|
@lzybkr: Sorry for the revision frenzy around my previous comment - I initially hadn't considered all implications of your comments. I get that this is a tricky issue that requires serious thought, but whatever the outcome is, for the user to trust and use the feature it is important that the rules and limitations are clear, documented, and not too complex to remember. For instance, one way of resolving the issue, if allowing arbitrary expressions turns out to be infeasible, is to restrict input to:
|
I've added I think that covers all literal syntax forms now (including quasi-literals As for a quick and safe way (though not user-friendly) to resolve this issue: Given that it makes no sense to display a prompt in these cases - you won't be able to enter any / the intended value - a terminating error should be thrown instead. |
Let me attempt a pragmatic summary:
|
Before adding the If we wanted to prompt for [bool] and [switch], the prompt should just be a Y/N type of prompt. Given the security and complexity concerns, it doesn't make sense to try to prompt for [hashtable] and [scriptblock]. |
Thanks, @SteveL-MSFT - makes sense.
That's a great idea and bypasses the problem of not being able to use expressions (variables So my vote is for an amended version of the simple fix proposed above:
|
@mklement0 I think we can do this in stages. I would think it's relatively simple to throw a statement-terminating error for |
@PowerShell/powershell-committee reviewed this and agree that throwing an error is a better experience than the current prompt that fails with an error implying it should work. To support an improved experience, we should have a RFC. |
Users need not be able to pass any parameters, since the script at hand may abuse this misfeature to read parameters to internal commands. Also, PowerShell should have a non-interactive mode. I am not happy when my scripts wait forever for my input. |
|
The point was that user can already pass the output (result) of any expression as a command-line argument (assuming the language mode in effect allows it) and that that expression is evaluated before the target command sees it, which has no bearing on the the command (script, function, cmdlet) being called (this is not the type of security concern as with, say, SQL injection). The same applies in principle to interactive input of an argument value - though additional constraints there definitely makes sense: To recap my earlier statement:
That said, if I understand the committee decision correctly, the upshot is:
|
Many enterprise desktop users can only run applications and scripts that are pre-approved by IT. Such users would not be allowed to start PowerShell as such, or to edit any scripts, even if they were smart enough to do that, which most of them are not. |
Again: no one has asked for the ability to enter arbitrary commands (expressions, variable references) into an interactive mandatory-parameter prompt. Perhaps I should have been clearer in saying that you should be able to enter (quasi-)literals of the target parameter's type, such as Therefore - if we want to improve the experience - it makes sense to author an RFC to come up with a user experience that is (a) predictable and (b) flexible enough while avoiding inadvertent evaluation, which are non-trivial problems to solve. Then again, pragmatically speaking, reporting an error in lieu of prompting for unsupported types may be good enough (I've removed the word "stopgap" from my previous comment.) The only thing I personally think is missing is the previously suggested opt-in to disable the mandatory-parameter prompts altogether (independently of the I think we could even consider reversing the logic: requiring an opt-in if you want these prompts; this technically breaking change would only affect scripts that were explicitly designed to have the user answer such prompts triggered by incomplete calls inside the script - which strikes me as unlikely. |
|
Taking a step back, regarding disabling the prompts altogether: If technically feasible, a simpler solution would be to restrict the mandatory-parameter prompts solely to commands submitted at the command prompt of an interactive session. E.g., Submitting just That way, without the need for a new preference variable, we could retain the prompts in the context of the command-prompt experience while taking away the pain of having scripts that mistakenly lack mandatory arguments hang in automation contexts where |
A preference variable would still be necessary because it is a breaking change—they may be scripts in the wild that abuse this feature to ask users in the middle of something.. |
Fair enough, but such questions need to be resolved in the yet-to-be-if-ever written RFC.
Assuming you mean the called function: It should, and it can - if the language mode allows it; to put it differently: you need to use the language mode to control this ability.
Yes, it is technically breaking, as stated (in the context of the earlier suggestion of reversing the opt-in logic), but there's also the concept of a Bucket 3: Unlikely Grey Area breaking change, where users are unlikely to depend on the old behavior, in which case the benefits of the breaking change may outweigh the risk of breaking existing code. Personally, this strikes me as such a change. (And a preference variable could still be introduced, separately, to enable users to never present these prompts.) |
P.S.: Irrespective of whether the currently unsupported types will ever be supported by the prompts following a RFC, I want to reiterate that the current UX with these prompts is generally poor: no tab completion, no re-prompting on invalid input (and |
It seems like this is fairly straightforward and doesn't break anything that's not already broken.
Was an RFC ever created for this? |
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically. Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original. |
Note: A mandatory
[switch]
parameter is an edge case, given that switches are usually optional. However, mandatory[bool]
parameters are affected as well, as are[hashtable]
-and[scriptblock]
-typed ones.The value entered by the user is invariably considered a string, which means:
for a mandatory
[bool]
parameter, any nonempty input - including literal$False
- is coerced to$True
.for a mandatory
[switch]
parameter, it is currently impossible to provide input that is accepted.for a mandatory
[hashtable]
or[scriptblock]
parameter, it too is impossible to provide input that is accepted.Also, for a parameter that has the
[AllowNull()]
attribute you cannot interactively specify$null
(it will be treated as string literal'$null'
).Steps to reproduce
Expected behavior
Actual behavior
For the
[bool]
parameter, the non-empty string literal$False
was coerced to$True
.Note that the same would have happened with input
0
.By contrast, if you pass a value on the command line, things work as expected:
Environment data
The text was updated successfully, but these errors were encountered: