Rob van der Woude's Scripting Pages

Batch How To ...

Prevent Code Insertion Exploits

The recent (September 2014) disclosure of a command insertion vulnerability for command-shell scripts (batch files), by The Security Factory, made it painfully clear that batch files can be vulnerable to exploits.

Code Insertion, in short, means input (data) is (unintentionally, for the script author anyway) interpreted as code to be executed.

Batch files are extremely "weakly typed" (to use the understatement of the millennium): everything is a string, and a string can be everything, command as well as data, and there is no way to distinguish between the two.
This makes batch code insertion more than just a potential threat.


Beware of ampersands in file or folder names

The vulnerability disclosure discusses a real-life scenario: with the dynamic system variable %CD% used unquoted in a batch file running on a (file) server, a simple exploit could get (malicious) code executed with elevated privileges.
The solution offered is to use doublequotes: "%CD%", which does indeed inhibit the vulnerability.
Sometimes however, using doublequotes isn't an option, but checking my own batch files I always found a solution that did inhibit the vulnerability.

Note: As was stated in the disclosure, quoting %CD% only solves this particular vulnerability because doublequotes are not allowed in paths.
If a variable (e.g. "%Variable%") can contain doublequotes, quoting it (i.e. "%Variable%") still doesn't solve the issue.

How to test for unquoted %CD%

To test your own batch files for this particular vulnerability, you can run the following batch code against your batch files directory:

IF NOT "%~1"=="" PUSHD "%~1"
FOR %%A IN (*.bat *.cmd) DO (
	TYPE "%%~A" | FIND /I /N "%%CD" | FINDSTR /R /I /C:"[^""]%%CD[:%%]"
		ECHO.========== "%%~nxA" ==========
IF NOT "%~1"=="" POPD

The code first uses FIND to search for %CD, and then uses FINDSTR to filter out "%CD and variables whose names start with but are not equal to CD (e.g. %CDROM%).
FIND's /N switch is used to display the line numbers.

If you expect more "advanced" variations like %__CD__% too, adapt the code accordingly.

Instead of this batch code, you could also use BatCodeCheck to test for this particular vulnerability plus many common errors.
BatCodeCheck will test for all known variations of this vulnerability.

Alternatives to unquoted %CD%:

  1. Use doublequotes, i.e. "%CD%" (or "%__CD__%" or "!CD!" or "!__CD__!" or "%CD:~2" or "%__CD__:\=/%" etc.)
  2. If doublequotes are not an option because you use %CD% to build a path which will then be doublequoted, try building the path immediately and doublequote it immediately
  3. If building the entire path immediately is not an option, do at least doublequote the parts immediately, and use FOR loops to concatenate them:
    FOR %%A IN ("part1") DO FOR %%B IN ("part2") DO SET part1and2="%%~A%%~B" (or ...part1and2="%%~A.\%%~B")
  4. Or use . or .\ instead of %CD%
  5. Abort on ampersands in paths, e.g.
    CD | FIND "&" && EXIT /B 1
    and recursively:
    DIR . /AD /S /B | FIND "&" && EXIT /B 1

page last modified: 2017-03-06