That was the title of a recent blog post by Jeffery Snover on the PowerShell team blog. I recently had the privilege of sitting down with Jeffery Snover and the PowerShell team and just talk about bits and pieces in PowerShell and PrimalScript.
One question I was asked was what I would think the PowerShell team could do to make PowerShell’s acceptance become even faster moving. I am flattered that they thought I had an answer to that, so I’ll give it a shot. And sticking with Jeff’s “A Thousand Things 1% Better” theme, I’ll pick something that can easily be fixed.
One thing, that makes me go to the standard command prompt rather than PowerShell is the ./ requirement for some commands.
Just say I am deep down in some folder, like “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727”
and I want to run regasm against some dll I created.
I have to type ./regasm because my framework folder is not in the path. Which makes me end up ALWAYS typing it twice because I can never remember to type the darn dot slash. The inconsistency of sometimes having to type it and sometimes not makes it impossible to get used to it. Am I in a folder that is in the path? Trial and error every time.
I understand that this dot slash scheme was invented to prevent command injection. So that you cannot substitute an internal command with a potentially malicious external script or executable, you have to fully specify the path name to the file.
But since regasm is no internal command it won’t substitute anything. And since I can put a malicious notepad.cmd anywhere in a folder in the PATH environment and it gets executed instead of the real notepad.exe, the entire command injection prevention fails for me.
The problem here is not with the PowerShell team though. Preventing command injection is a job for the operating system, not for a shell. UNIX systems had a mechanism for decades for that, called the executable attribute. Any exe, cmd, ps1, bat and whatnot file would be as dead as a doorknob unless that attribute exists. It simply would not run.
Any file system activity, like moving, copying or opening and modifying a file results in this attribute being removed. It takes an admin user with chmod to add that bit again. Simple, effective and elegant.
Microsoft already has a mechanism for that, just try to download a CHM file to your desktop from some website and view it. You will have to right click and unlock it before it works.
So please, PowerShell folks, make it better by making it easier for us to execute commands. Remove the inconsistency and influence the powers at work to add proper command injection protection to the OS. It is not a shell’s job to do that.
Technorati Tags: PowerShell,PrimalScript
If you use Tab completion to enter regasm.exe PowerShell will auto-insert the .\ prefix for you
I just use this tip:
http://huddledmasses.org/powershell-power-user-tips-current-directory/
I personally think that they just left this out accidently (or maybe purposefully) because of the provider model.
IIRC, **ix shells don’t search the current directory first; they restrict themselves _only_ to the directories in the path. PS is merely following this (more secure) convention. In any case, if you really want to search the current directory first, use the following line in your profile:
if ($ENV:Path[0] -ne “.”) { $ENV:Path = “.;$env:Path” }
Bill
The point is that it shouldn’t require me to do something in just a few instances. It is inconsistent and provides no security.
typing
./regasm whatever.dll
is not adding security over typing
regasm whatever.dll
Command injection must be prevented at a much lower level, not at the shell for a few very isolated cases.
I am aware of all the work-arounds, the just prove my case.
If so many folks come up with a work-around, is it really a feature?
Just to make sure, this has NOTHING to do with signing. I wish there was a setting that would only allow running signed executables.
I don’t understand what you mean by inconsistent. The rule is simple: PowerShell doesn’t search the current directory for executables. I also disagree that it provides no security: You can’t simply drop fake executables in the path unless you already have permissions to do so.
I think the default behavior (search only in the path) has a long pedigree, makes sense, and is reasonable.
Inconsistent: I have to type ./ for executables NOT in a folder that is included in the PATH environment variable, I do NOT have to type that for executable in the search path. Two rules for the same thing.
Security: The assumption that this prevents me from executing “fake” executables is flawed. If anyone has managed to drop a malicious executable onto my machine they could just as well have dropped it into a folder included in PATH.
Inconsistent: I am in C:\Windows\System32 and type Notepad, notepad is executed, even though it is in the current folder.
I do not understand what this would ever protect me from.
The protection against replacing command executables must be done at a much lower level to be successful. typeing ./ to execute something does not protect against files being copied onto your hard drive.
Pedigree: Most unix systems I work on have . (current folder) as part of the search path. CMD.EXE never required this.
I am eager to learn when this was established as a default behavior and why?
Hi Alex,
Regarding inconsistent: I still don’t understand, since the basic rule (search only the path, not the current directory first) applies in both of your use cases. If the current directory happens to be in the path, then PS is executing Notepad by finding it in the path, not because it’s in the current directory.
Regarding security: Not all directory permissions are the same. There are places where a rogue limited user can write files (including executables) that are not necessarily in the path.
Regarding “./”: Typing “./” to run a command from the current directory is an explicit request: Don’t search the path, but run the executable that’s sitting in the current directory.
Regarding pedigree: I believe that **ix shells require “.” in the path to tell a shell to search the current directory. Likewise, PS doesn’t blindly run executables in the current directory like cmd.exe.
I believe the following blog posts might be helpful:
http://blogs.msdn.com/powershell/archive/2008/09/30/powershell-s-security-guiding-principles.aspx
http://www.leeholmes.com/blog/DemonstrationOfMonadsSecurityFeatures.aspx (old, but still applicable)
HTH,
Bill
I have read those posts. I am preparing another post that will clarify (or so I hope) what I mean.