Defense Against Injection Attacks

Part of 22C:169, Computer Security Notes
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Two Philosophies

Theere are two basic philosophies of how to defend against parameter injection attacks:

These two philosophies have different consequences:

Forbid dangerous content

Forbidding dangerous content only works if you understand all possible attacks. For the examples from the previous lecture, it is clear that for tcsh scripts, the dangerous content includes parameter strings that include semicolon and dollar sign, so we need to scan each parameter string for those items.

This is vulnerable if you miss some attack, and it may lead you to forbid content that is perfectly reasonable in some context. For example, while semicolons in some shell parameters are dangerous, they may be perfectly safe if enclosed in appropriate quotation marks.

Permit expected content

Permitting expected content requires that you really understand your application -- something that was meaningless in the context of our toy examples where there was no real application. If your application has a parameter that should be a person's name, you can, for example, require that it conform to reasonable conventions for the rendering of people's names, that is, that it contain words separated by spaces, with periods permitted after one-letter words and apostrophes allowed within words, but nothing else.

The problem here is that some applications may actually require constructs that can pose dangers. Badly designed applications may actually require that you allow shell commands to be passed as parameters. Someone aware of security constraints should protest if this is the case, but the argument for allowing arbitrary shell commands, for example, to be passed as parameters can be quite strong in some contexts.

Checking Tools

Given that you have a suspicious parameter, you must check it. The first tool we can use here is the exit status of a command

if ({shell command}) echo success

The above demonstrates the mechanism the shell provides for executing an arbitrary shell command and checking to see if it executed successfully or terminated in error; recall that the kernel call exit takes a parameter indicating success or failure.

if ("stringa" =~ "pattern") echo match

The =~ operator allows a string to be compared to a pattern, where the pattern contains wildcards of the same sort allowed in filenames. So, asterisk matches any string of characters, ? matches any individual character, a list of characters enclosed in square braces matches any character in that list, and the shorthand [a-k] matches the same strings as [abcdefghijk]. This allows testing for strings that contain dangerous content. For example "*;*" will match any string containing a semicolon.

This can get tricky. If one argument is quoted, the other must be quoted identically, so if you need quotes to suppress improper interpretation of the first argument, the same quotes must appear on the second argument. Experiment!