Questions about this topic? Sign up to ask in the talk tab.

Difference between revisions of "Unsafe command processing"

From NetSec
Jump to: navigation, search
Line 1: Line 1:
    Unsafe command processing
+
It is never safe or secure to process user input into system commands.  The '''system()''' and '''exec()''' functions are mostly universal between languages along with the backtick ('''`''') characters for command substitution.  In some languages, the '''$()''' operator for command substitution is also valid.
        Using user input as arguments for a system call should never be done.  The system() and exec() functions are mostly universal between languages along with the backtick (`) characters for command substitution.  In some languages, the $() operator for command substitution is also valid.
+
=== Proof of concept ===
      Proof of concept
+
  
      {{code|text=<source lang="python"> >>> os.system("echo %s" % input("# "))</source>
+
{{code|text=<source lang="python"> >>> os.system("echo %s" % input("# "))</source>
      <source lang="bash"># unsafe; ping -c1 google.com
+
<source lang="bash">$ unsafe; ping -c1 google.com
      PING google.com (74.125.224.168) 56(84) bytes of data.
+
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>}}
+
64 bytes from lax02s01-in-f8.1e100.net (74.125.224.168): icmp_req=1 ttl=51 time=13.1 ms</source>}}
 
        
 
        
    Mitigation:
+
=== 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.   
+
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:
 
Ctype or native examples:
 
* Python:
 
* 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
+
{{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>}}
+
'abcdefgh'</source>}}
 
            
 
            
 
* Perl:
 
* Perl:
Line 22: Line 21:
 
* Ruby:
 
* Ruby:
 
        
 
        
    Auditing:  
+
=== Auditing ===  
      Auditing command processing is simple: check for all uses of system(), exec(), backticks, popen, and any language specific function.
+
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\(" '{}' \; &> command_processing.txt</source>}}
 
{{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\(" '{}' \; &> command_processing.txt</source>}}
  
 
[[Category:Secure programming]]
 
[[Category:Secure programming]]

Revision as of 02:00, 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 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:

  • Python:
>>> 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\(" '{}' \; &> command_processing.txt