Injection
flaws allow attackers to relay malicious code through a web application to
another system. These attacks include calls to the operating system via system
calls, the use of external programs via shell commands, as well as calls to
backend databases via SQL (i.e., SQL injection). Whole scripts written in perl,
python, and other languages can be injected into poorly designed web
applications and executed. Any time a web application uses an interpreter of
any type there is a danger of an injection attack.
Injection
attacks can be very easy to discover and exploit, but they can also be
extremely obscure. The consequences can also run the entire range of severity,
from trivial to complete system compromise or destruction. In any case, the use
of external calls is quite widespread, so the likelihood of a web application
having a command injection flaw should be considered high.
Shell Commands
Many web
applications use operating system features and external programs to perform
their functions. Sendmail is probably the most frequently invoked external
program, but many other programs are used as well. When a web application
passes information from an HTTP request through to the command line, it must be
carefully scrubbed. This also applies when opening files in the file system.
Otherwise, the attacker can inject special (meta) characters, malicious
commands, or command modifiers into the information and the web application
will blindly pass these on to the external system for execution.
SQL
SQL
injection is a particularly widespread and dangerous form of attack. To exploit
a SQL injection flaw, the attacker must find a parameter that the web
application passes through to a database. By carefully embedding malicious SQL
commands into the content of the parameter, the attacker can trick the web
application into forwarding a malicious query to the database. These attacks
are not difficult to attempt and more tools are emerging that scan for these
flaws. The consequences are particularly damaging, as an attacker can obtain,
corrupt, or destroy database contents.
Environments Affected
Every web
application environment allows the execution of external commands such as
system calls, shell commands, and SQL requests. The susceptibility of an
external call to command injection depends on how the call is made and the
specific component that is being called, but almost all external calls can be
attacked if the web application is not properly coded.
Some environment specific considerations:
MySQL – older mysql libraries only processes one statement at a time when you
pass it a query. Newer mysql libraries (e.g., mysql in PHP) will process
multiple SQL commands in one query
Oracle –
most Oracle client libraries support variable binding. This is the best way to
avoid SQL injection.
Perl –
check for shell injection when you open a file if the filename is derived from
user input
Examples:
A
malicious parameter could modify the actions taken by a system call that
normally retrieves the current user’s file to access another user’s file (e.g.,
by including path traversal “../” characters as part of a filename request).
Additional
commands could be tacked on to the end of a parameter that is passed to a shell
script to execute an additional shell command (e.g., “; rm -r *”) along with
the intended command.
SQL
queries could be modified by adding additional ‘constraints’ to a where clause
(e.g., “OR 1=1″) to gain access to or modify unauthorized data.
Example:
DELETE
FROM CRITICALTABLE WHERE USER=’$VAR’
where the
user enters
HACKER’
OR ’1′=’1
Notice
the mismatched quotes! Inserting this into the SQL statement, we’d get:
DELETE
FROM CRITICALTABLE WHERE USER=’BADGUY’ OR ’1′=’1′
This
would delete all the information in the critical table.
How to
Determine If You Are Vulnerable
The best
way to determine if you are vulnerable to command line or SQL injection attacks
is to search the source code for all calls to external resources (e.g., system,
exec, fork, Runtime.exec, SQL queries, or whatever the syntax is for making
requests to interpreters in your environment). Note that many languages have
multiple ways to run external commands. Developers should review their code and
search for all places where input from an HTTP request could possibly make its
way into any of these calls. You should carefully examine each of these calls
to be sure that the protection steps outlined below are followed.
How to
Protect Yourself
The
simplest way to protect against injection is to avoid accessing external interpreters
wherever possible. For many shell commands and some system calls, there are
language specific libraries that perform the same functions. Using such
libraries does not involve the operating system shell interpreter, and
therefore avoids a large number of problems with shell commands.
Use bind
variables where ever possible. If not, escape all user variables which be used
in a SQL statement or on the command line.
In
Coldfusion, use variable binding by using the CFQueryParam Tag within your
CFQuery tags.
In Perl,
prepare your statements using variable binding and then pass the parameters
when executing the query:
$cursor =
$db->prepare(“DELETE FROM CRITICALTABLE WHERE USER=?”);
$cursor->execute($user);
Use
pattern matching to verify user input is an expected value. If input is not
what is expected, throw an error. Error messages should be generic.
Turn
off/control debug messages to avoid giving an attacker potentially useful
information.
Database
level: Limit access to the web account that is accessing the database.
Write procedures to insert records and update data rather than give the
application direct access to the tables; Limit application to READ-only
access where possible – at user level as well as database level.
Reuse
previously tested code wherever possible.
For those
calls that you must still employ, such as calls to backend databases, you must
carefully validate the data provided to ensure that it does not contain any
malicious content. You can also structure many requests in a manner that
ensures that all supplied parameters are treated as data, rather than
potentially executable content. The use of stored procedures or prepared
statements will provide significant protection, ensuring that supplied input is
treated as data. These measures will reduce, but not completely eliminate the
risk involved in these external calls. You still must always validate such
input to make sure it meets the expectations of the application in question.
Another
strong protection against command injection is to ensure that the web
application runs with only the privileges it absolutely needs to perform its
function. So you should not run the webserver as root or access a database as
DBADMIN, otherwise an attacker can abuse these administrative privileges
granted to the web application. Some of the J2EE environments allow the use of
the Java sandbox, which can prevent the execution of system commands.
If an
external command must be used, any user information that is being inserted into
the command should be rigorously checked. Mechanisms should be put in
place to handle any possible errors, timeouts, or blockages during the call.
All
output, return codes and error codes from the call should be checked to ensure
that the expected processing actually occurred. At a minimum, this will allow
you to determine that something has gone wrong. Otherwise, the attack may occur
and never be detected.
The OWASP
Filters project is producing reusable components in several languages to help
prevent many forms of injection. OWASP has also released CodeSeeker, an
application level firewall.
Injection
flaws allow attackers to relay malicious code through a web application to
another system. These attacks include calls to the operating system via system
calls, the use of external programs via shell commands, as well as calls to
backend databases via SQL (i.e., SQL injection). Whole scripts written in perl,
python, and other languages can be injected into poorly designed web
applications and executed. Any time a web application uses an interpreter of
any type there is a danger of an injection attack.
Injection
attacks can be very easy to discover and exploit, but they can also be
extremely obscure. The consequences can also run the entire range of severity,
from trivial to complete system compromise or destruction. In any case, the use
of external calls is quite widespread, so the likelihood of a web application
having a command injection flaw should be considered high.
Shell Commands
Many web
applications use operating system features and external programs to perform
their functions. Sendmail is probably the most frequently invoked external
program, but many other programs are used as well. When a web application
passes information from an HTTP request through to the command line, it must be
carefully scrubbed. This also applies when opening files in the file system.
Otherwise, the attacker can inject special (meta) characters, malicious
commands, or command modifiers into the information and the web application
will blindly pass these on to the external system for execution.
SQL
SQL
injection is a particularly widespread and dangerous form of attack. To exploit
a SQL injection flaw, the attacker must find a parameter that the web
application passes through to a database. By carefully embedding malicious SQL
commands into the content of the parameter, the attacker can trick the web
application into forwarding a malicious query to the database. These attacks
are not difficult to attempt and more tools are emerging that scan for these
flaws. The consequences are particularly damaging, as an attacker can obtain,
corrupt, or destroy database contents.
Environments Affected
Every web
application environment allows the execution of external commands such as
system calls, shell commands, and SQL requests. The susceptibility of an
external call to command injection depends on how the call is made and the
specific component that is being called, but almost all external calls can be
attacked if the web application is not properly coded.
Some environment specific considerations:
MySQL – older mysql libraries only processes one statement at a time when you
pass it a query. Newer mysql libraries (e.g., mysql in PHP) will process
multiple SQL commands in one query
Oracle –
most Oracle client libraries support variable binding. This is the best way to
avoid SQL injection.
Perl –
check for shell injection when you open a file if the filename is derived from
user input
Examples:
A
malicious parameter could modify the actions taken by a system call that
normally retrieves the current user’s file to access another user’s file (e.g.,
by including path traversal “../” characters as part of a filename request).
Additional
commands could be tacked on to the end of a parameter that is passed to a shell
script to execute an additional shell command (e.g., “; rm -r *”) along with
the intended command.
SQL
queries could be modified by adding additional ‘constraints’ to a where clause
(e.g., “OR 1=1″) to gain access to or modify unauthorized data.
Example:
DELETE
FROM CRITICALTABLE WHERE USER=’$VAR’
where the
user enters
HACKER’
OR ’1′=’1
Notice
the mismatched quotes! Inserting this into the SQL statement, we’d get:
DELETE
FROM CRITICALTABLE WHERE USER=’BADGUY’ OR ’1′=’1′
This
would delete all the information in the critical table.
How to
Determine If You Are Vulnerable
The best
way to determine if you are vulnerable to command line or SQL injection attacks
is to search the source code for all calls to external resources (e.g., system,
exec, fork, Runtime.exec, SQL queries, or whatever the syntax is for making
requests to interpreters in your environment). Note that many languages have
multiple ways to run external commands. Developers should review their code and
search for all places where input from an HTTP request could possibly make its
way into any of these calls. You should carefully examine each of these calls
to be sure that the protection steps outlined below are followed.
How to
Protect Yourself
The
simplest way to protect against injection is to avoid accessing external interpreters
wherever possible. For many shell commands and some system calls, there are
language specific libraries that perform the same functions. Using such
libraries does not involve the operating system shell interpreter, and
therefore avoids a large number of problems with shell commands.
Use bind
variables where ever possible. If not, escape all user variables which be used
in a SQL statement or on the command line.
In
Coldfusion, use variable binding by using the CFQueryParam Tag within your
CFQuery tags.
In Perl,
prepare your statements using variable binding and then pass the parameters
when executing the query:
$cursor =
$db->prepare(“DELETE FROM CRITICALTABLE WHERE USER=?”);
$cursor->execute($user);
$cursor->execute($user);
Use
pattern matching to verify user input is an expected value. If input is not
what is expected, throw an error. Error messages should be generic.
Turn
off/control debug messages to avoid giving an attacker potentially useful
information.
Database
level: Limit access to the web account that is accessing the database.
Write procedures to insert records and update data rather than give the
application direct access to the tables; Limit application to READ-only
access where possible – at user level as well as database level.
Reuse
previously tested code wherever possible.
For those
calls that you must still employ, such as calls to backend databases, you must
carefully validate the data provided to ensure that it does not contain any
malicious content. You can also structure many requests in a manner that
ensures that all supplied parameters are treated as data, rather than
potentially executable content. The use of stored procedures or prepared
statements will provide significant protection, ensuring that supplied input is
treated as data. These measures will reduce, but not completely eliminate the
risk involved in these external calls. You still must always validate such
input to make sure it meets the expectations of the application in question.
Another
strong protection against command injection is to ensure that the web
application runs with only the privileges it absolutely needs to perform its
function. So you should not run the webserver as root or access a database as
DBADMIN, otherwise an attacker can abuse these administrative privileges
granted to the web application. Some of the J2EE environments allow the use of
the Java sandbox, which can prevent the execution of system commands.
If an
external command must be used, any user information that is being inserted into
the command should be rigorously checked. Mechanisms should be put in
place to handle any possible errors, timeouts, or blockages during the call.
All
output, return codes and error codes from the call should be checked to ensure
that the expected processing actually occurred. At a minimum, this will allow
you to determine that something has gone wrong. Otherwise, the attack may occur
and never be detected.
The OWASP
Filters project is producing reusable components in several languages to help
prevent many forms of injection. OWASP has also released CodeSeeker, an
application level firewall.
No comments:
Post a Comment