Protecting Against Malicious Code Injection
If you are writing scripts that accept input from users – you need to be aware of the potential dangers of Malicious Code-Injection. Below is a good good article on this topic:
Here is a line from that article:
All code injection attacks work on the same principle: a hacker piggybacks malicious code onto good code through an input field in the application. Therefore, the protection instead has to come from the code within the application itself.
The basic idea is that you write a program or script which takes input from the user and then uses that input in a command. An evil user pjrovides input which includes a statement terminator and then an evil command. If the program/script doesn’t protect against this – bad things can and do happen.
The historical problem with protecting against code injection is that it relies upon the scripter to do this work and it is sometimes difficult to write this protection code. PowerShell’s parser was written to specifically protect you against Malicious Code Injection attacks (with no work on your part!). There is one exception (“Invoke-Expression”) that you need to be aware of and treat with the utmost of respect.
Remember that the semicolon (“;”) is PowerShell’s statement seperator. The following illustrates how that works:
PS> Write-Host Message1; Write-Host Message2
When the parser sees the “;” it considers that the end of the first command and starts to parse the second command and then executes both of them. For the next examples, I’ll try to get PowerShell to run the evil command: “Write-Host Busted”. Image that I have a script which takes user input and assigns it to $x and then uses $x as a parameter to a command (in this case we’ll just use the Write-Host command but the principle works everywhere).
PS> $x = “this is a test”
PS> Write-host $x
this is a test
Now imagine a evil user tries to use inject some code:
PS> $x=”Message1″ ; Write-Host $x
PS> $x=”Message1;Write-Host Busted” ; Write-Host $x
Notice that it did not work – the entire string (statement terminator and all) was output. The reason for this is that PowerShell’s parser binds the value to the parameter – it doesn’t replace the text in-line and THEN do the parse. If you think about it – it has to. Many of PowerShell parameters are OBJECTS (i.e. not strings) therefore it cannot do put the text in-line and parse – there is no text to put in-line.
NOTE: The exception to this rule is INVOKE-EXPRESSION. This will expand all variables and then do the parse (and thus is subject to Code Injection attacks). Now Invoke-Expression can be extraordinarily powerful so it is not that you want to never use it but you need to be VERY VERY careful about using it. In particular, you are probably on safe ground if the data ONLY comes from the program itself. If you include any data provided from the user – you need to protect yourself from Code Injection. Here is an example of the danger.
PS> $x=”Write-Host Message1;Write-Host Busted” ; Invoke-Expression $x
The bottom line to all of this is that PowerShell’s Parser provides intrinsic protection for a class of problems that use to be difficult to protect against. We often get asked about the security of PowerShell and I point out a couple things:
- First is that we are super humble about security. The bad guys continue to get smarter so while we’ve done a ton of work and raised the bar signficantly, we’ll always invest in security.
- Second is that this project was started AFTER Bill’s famous TrustWorthy Computing Memo so everyone got trained on security and everything was done with an eye towards security.
- Third is that our security “buddy” is superstar Michael Howard ( http://www.microsoft.com/mspress/books/5957.aspx ). You just don’t get any better than that. Full stop.
Anyway – there are lots of visible security features/elements in PowerShell (Secure by default, Execution Policies, Digitial Sigatures, warnings on scripts that get downloaded from the internet, double-clicking a script invokes notepad, etc, etc, etc) but there is also a ton of non-visible security features/elements as well. The way our parser protects scripts from malicious code injection is just one of those features.
Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx