Difference between revisions of "Unsafe command processing"
(→Auditing) |
|||
(5 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | + | It is never safe or secure to process user input into system commands. The '''system()''' and '''exec()''' functions are mostly universal between [[programming language]]s along with the backtick ('''`''') characters for ''command substitution''. In some languages, the '''$()''' operator for command substitution is also valid. | |
− | + | === Proof of concept === | |
− | + | ||
− | + | {{code|text=<source lang="python"> >>> os.system("echo %s" % input("# "))</source> | |
− | + | <source lang="bash">$ unsafe; ping -c1 google.com | |
− | + | PING google.com (74.125.224.168) 56(84) bytes of data. | |
− | + | 64 bytes from lax02s01-in-f8.1e100.net (74.125.224.168): icmp_req=1 ttl=51 time=13.1 ms</source>}} | |
− | + | === Mitigation === | |
− | + | Instead of using system, backticks, popen, exec or any other command executing function, use the language's native built in library. If it does not have one, then write one - but do not simply wrap system() and call this a library; this is bad form. All [[interpreted languages]] have a way to load shared libraries (*.so files) and interface with the functions provided by their export tables. These are what should be utilized when authoring libraries that seemingly need you to run a command. Instead, the C interface (CTypes) can be used. | |
− | + | Ctype or native examples: | |
− | + | * [[Python]]: | |
− | + | {{code|text=<source lang="python">>>> from ctypes import *; cdll.LoadLibrary("libc.so.6").printf(c_char_p("abcdefgh\n")); # import printf() from libc.so.6 | |
− | + | 'abcdefgh'</source>}} | |
− | + | * [[Perl]]: | |
− | + | * [[PHP]]: | |
− | + | * [[Ruby]]: | |
− | + | === Auditing === | |
− | + | Auditing command processing is simple: check for all uses of system(), exec(), backticks, popen, and any language specific function. | |
− | {{code|text=<source lang="bash">find -type f -regextype posix-awk -regex ".*\.(rb|php|py|pl|pm)" -exec grep -EHnC2 "system\(\|[pP]open\(\|\`\|exec.*\(\|passthru\(" '{}' \; | + | {{code|text=<source lang="bash">find -type f -regextype posix-awk -regex ".*\.(rb|php|py|pl|pm)" -exec grep -EHnC2 "system\(\|[pP]open\(\|\`\|exec.*\(\|passthru\(" '{}' \;</source>}} |
[[Category:Secure programming]] | [[Category:Secure programming]] |
Latest revision as of 01:02, 12 May 2013
It is never safe or secure to process user input into system commands. The system() and exec() functions are mostly universal between programming languages along with the backtick (`) characters for command substitution. In some languages, the $() operator for command substitution is also valid.
Proof of concept
>>> os.system("echo %s" % input("# ")) $ unsafe; ping -c1 google.com PING google.com (74.125.224.168) 56(84) bytes of data. 64 bytes from lax02s01-in-f8.1e100.net (74.125.224.168): icmp_req=1 ttl=51 time=13.1 ms |
Mitigation
Instead of using system, backticks, popen, exec or any other command executing function, use the language's native built in library. If it does not have one, then write one - but do not simply wrap system() and call this a library; this is bad form. All interpreted languages have a way to load shared libraries (*.so files) and interface with the functions provided by their export tables. These are what should be utilized when authoring libraries that seemingly need you to run a command. Instead, the C interface (CTypes) can be used.
Ctype or native examples:
>>> from ctypes import *; cdll.LoadLibrary("libc.so.6").printf(c_char_p("abcdefgh\n")); # import printf() from libc.so.6 'abcdefgh' |
- Perl:
- PHP:
- Ruby:
Auditing
Auditing command processing is simple: check for all uses of system(), exec(), backticks, popen, and any language specific function.
find -type f -regextype posix-awk -regex ".*\.(rb|php|py|pl|pm)" -exec grep -EHnC2 "system\(\|[pP]open\(\|\`\|exec.*\(\|passthru\(" '{}' \; |