ShellForCGI
(Created page with " '''This is work in progress, not all claims are yet explained and documented''' =Definitions= shell: anything which is a command interpreter: bash, ksh, zsh ... script: high...") |
(→Example of typical script) |
||
Line 44: | Line 44: | ||
This may look dangerous, but has no security issues | This may look dangerous, but has no security issues | ||
− | * | + | #!/bin/bash |
+ | echo "Content-type: image/png" | ||
+ | echo | ||
+ | exec /usr/bin/qrencode -o - -- "${PATH_INFO#/}" | ||
+ | |||
+ | It simply takes whatever is entered after a / on the script URL and creates a qrcode out of it. | ||
+ | |||
+ | Security features in this script: | ||
+ | * Using -- before parameters from user input | ||
+ | * Using " around parameters | ||
+ | * Using /usr/bin (usually your webserver has a sane PATH, but better have this in any case) | ||
+ | |||
+ | Try it: | ||
+ | PATH_INFO="hello" ./qrcode-s.sh | tail -n +3 | display | ||
+ | PATH_INFO=';\$(id)\;' ./qrcode-s.sh | tail -n +3 | display | ||
==Examples of dangerous commands== | ==Examples of dangerous commands== |
Latest revision as of 22:12, 2 January 2015
This is work in progress, not all claims are yet explained and documented
Contents |
[edit] Definitions
shell: anything which is a command interpreter: bash, ksh, zsh ...
script: high level interpreted language like php, perl, python ...
CGI: common gateway interface, method how parameters are passed from the browser to programs by the webserver
[edit] Why this page?
I'm a fan of shell scripts and since years I write CGI programs in shell. Over time, a lot of CGI exploits have seen the light. My claim is that pure shell scripts are more secure than similar scripts in common scripting laguages like perl, python or php. Unfortunately you don't find a lot on the subject on the net, and the parts you find are confuse or purlely incorrect.
The main reason for the claim that shell is more secure than script, is that all calls to external programs from high level scripting languages are done via a shell/system call, whereas external commands in shell don't call an extra shell instance.
Of course if you keep exclusively all processing internal to your scripting language, the security level is about the same.
[edit] Base security
Also in shell you need to take care of some basic protection.
[edit] Inputs
Data relative to file names should not contain .. or even / if you don't want to manage hierachies. All other characters can be contained without problem for the CGI environment. Some issues can occur if you want to access bizzarre filenames directly from unix prompt. There is no other escaping or filtering needed. All ; , * and | can stay in the variables.
*some tests need to be done*
how does \0 behave in shell script?
[edit] Outputs
This is relative to XSS problems. A simple escaping of < by < is enough to make a simple output html safe. Pre-filling forms requires some more escaping. That's the same in any other language too, nothing new here.
*insert code for filtering*
[edit] How to get the form vars
There are a couple of CGI parsing scripts out there. Some are using eval, which is dangerous and on one occasion has made a shell CGI vulnerable to command injection.
*to be filled with code*
[edit] Calling commands
Calling external commands can be done safely if those commands have no known access to different files than you intend. Some GNU programs are very "nice" to allow command options at other positions than the beginning of the parameter list. So using "--" to terminate options and start arguments is a good practice.
*to be filled with code*
[edit] Example of typical script
This may look dangerous, but has no security issues
#!/bin/bash echo "Content-type: image/png" echo exec /usr/bin/qrencode -o - -- "${PATH_INFO#/}"
It simply takes whatever is entered after a / on the script URL and creates a qrcode out of it.
Security features in this script:
- Using -- before parameters from user input
- Using " around parameters
- Using /usr/bin (usually your webserver has a sane PATH, but better have this in any case)
Try it:
PATH_INFO="hello" ./qrcode-s.sh | tail -n +3 | display PATH_INFO=';\$(id)\;' ./qrcode-s.sh | tail -n +3 | display
[edit] Examples of dangerous commands
[edit] Mitigating injection
[edit] Really more secure
I don't claim that shell is 100% secure, just that it's better than the same in e.g. perl.
*compare shell and insecure perl and secure perl*
[edit] About the author
Georges Kesseler, 20 years of unix shell scripting and 15 years of apache httpd usage.