git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@146052 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Derek Ford 2003-12-09 19:07:42 +00:00
parent 8cc5a88173
commit be04523f33

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.62 $ -->
<!-- $Revision: 1.63 $ -->
<chapter id="security.index">
<title>Security</title>
@ -492,26 +492,26 @@ if (!ereg('^[^./][^/]*$', $username))
<simpara>
Nowadays, databases are cardinal components of any web based application by
enabling websites to provide varying dynamic content. Since very sensitive
or secret informations can be stored in such database, you should strongly
consider to protect them somehow.
or secret information can be stored in a database, you should strongly
consider protecting your databases.
</simpara>
<simpara>
To retrieve or to store any information you need to connect to the database,
send a legitimate query, fetch the result, and close the connecion.
send a legitimate query, fetch the result, and close the connection.
Nowadays, the commonly used query language in this interaction is the
Structured Query Language (SQL). See how an attacker can <link
linkend="security.database.sql-injection">tamper with an SQL query</link>.
</simpara>
<simpara>
As you can realize, PHP cannot protect your database by itself. The
As you can surmise, PHP cannot protect your database by itself. The
following sections aim to be an introduction into the very basics of how to
access and manipulate databases within PHP scripts.
</simpara>
<simpara>
Keep in mind this simple rule: defence in depth. In the more place you
take the more action to increase the protection of your database, the less
probability of that an attacker succeeds, and exposes or abuse any stored
secret information. Good design of the database schema and the application
Keep in mind this simple rule: defense in depth. The more places you
take action to increase the protection of your database, the less
probability of an attacker succeeding in exposing or abusing any stored
information. Good design of the database schema and the application
deals with your greatest fears.
</simpara>
@ -519,7 +519,7 @@ if (!ereg('^[^./][^/]*$', $username))
<title>Designing Databases</title>
<simpara>
The first step is always to create the database, unless you want to use
an existing third party's one. When a database is created, it is
one from a third party. When a database is created, it is
assigned to an owner, who executed the creation statement. Usually, only
the owner (or a superuser) can do anything with the objects in that
database, and in order to allow other users to use it, privileges must be
@ -536,14 +536,14 @@ if (!ereg('^[^./][^/]*$', $username))
application with very limited rights to database objects. The most
required privileges should be granted only, and avoid that the same user
can interact with the database in different use cases. This means that if
intruders gain access to your database using one of these credentials,
intruders gain access to your database using your applications credentials,
they can only effect as many changes as your application can.
</simpara>
<simpara>
You are encouraged not to implement all the business logic in the web
application (i.e. your script), instead to do it in the database schema
application (i.e. your script), instead do it in the database schema
using views, triggers or rules. If the system evolves, new ports will be
intended to open to the database, and you have to reimplement the logic
intended to open to the database, and you have to re-implement the logic
in each separate database client. Over and above, triggers can be used
to transparently and automatically handle fields, which often provides
insight when debugging problems with your application or tracing back
@ -557,11 +557,11 @@ if (!ereg('^[^./][^/]*$', $username))
You may want to estabilish the connections over SSL to encrypt
client/server communications for increased security, or you can use ssh
to encrypt the network connection between clients and the database server.
If either of them is done, then monitoring your traffic and gaining
informations in this way will be a hard work.
If either of these is used, then monitoring your traffic and gaining
information about your database will be difficult for a would-be attacker.
</simpara>
<!--simpara>
If your database server has native SSL support, consider to use <link
If your database server has native SSL support, consider using <link
linkend="ref.openssl">OpenSSL functions</link> in communication between
PHP and database via SSL.
</simpara-->
@ -584,16 +584,16 @@ if (!ereg('^[^./][^/]*$', $username))
<simpara>
The easiest way to work around this problem is to first create your own
encryption package, and then use it from within your PHP scripts. PHP
can assist you in this case with its several extensions, such as <link
can assist you in this with several extensions, such as <link
linkend="ref.mcrypt">Mcrypt</link> and <link
linkend="ref.mhash">Mhash</link>, covering a wide variety of encryption
algorithms. The script encrypts the data be stored first, and decrypts
it when retrieving. See the references for further examples how
algorithms. The script encrypts the data before inserting it into the database, and decrypts
it when retrieving. See the references for further examples of how
encryption works.
</simpara>
<simpara>
In case of truly hidden data, if its raw representation is not needed
(i.e. not be displayed), hashing may be also taken into consideration.
(i.e. not be displayed), hashing may also be taken into consideration.
The well-known example for the hashing is storing the MD5 hash of a
password in a database, instead of the password itself. See also
<function>crypt</function> and <function>md5</function>.
@ -662,8 +662,8 @@ $result = mysql_query($query);
</example>
Normal users click on the 'next', 'prev' links where the <varname>$offset</varname>
is encoded into the URL. The script expects that the incoming
<varname>$offset</varname> is decimal number. However, someone tries to
break in with appending <function>urlencode</function>'d form of the
<varname>$offset</varname> is a decimal number. However, what if someone tries to
break in by appending a <function>urlencode</function>'d form of the
following to the URL
<informalexample>
<programlisting>
@ -695,8 +695,8 @@ FLUSH PRIVILEGES;
</note>
<para>
A feasible way to gain passwords is to circumvent your search result pages.
What the attacker needs only is to try if there is any submitted variable
used in SQL statement which is not handled properly. These filters can be set
The only thing the attacker needs to do is to see if there are any submitted variables
used in SQL statements which are not handled properly. These filters can be set
commonly in a preceding form to customize <literal>WHERE, ORDER BY,
LIMIT</literal> and <literal>OFFSET</literal> clauses in <literal>SELECT</literal>
statements. If your database supports the <literal>UNION</literal> construct,
@ -732,12 +732,12 @@ union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from use
<varname>$query</varname>, the query beast awakened.
</para>
<para>
SQL UPDATEs are also subject to attacking your database. These queries are
SQL UPDATE's are also susceptible to attack. These queries are
also threatened by chopping and appending an entirely new query to it. But
the attacker might fiddle with the <literal>SET</literal> clause. In this
case some schema information must be possessed to manipulate the query
successfully. This can be acquired by examining the form variable names, or
just simply brute forcing. There are not so many naming convention for
just simply brute forcing. There are not so many naming conventions for
fields storing passwords or usernames.
<example>
<title>
@ -770,7 +770,7 @@ $query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE ...;
A frightening example how operating system level commands can be accessed
on some database hosts.
<example>
<title>Attacking the database host's operating system (MSSQL Server)</title>
<title>Attacking the database hosts operating system (MSSQL Server)</title>
<programlisting role="php">
<![CDATA[
$query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
@ -801,7 +801,7 @@ $result = mssql_query($query);
<para>
Some of the examples above is tied to a specific database server. This
does not mean that a similar attack is impossible against other products.
Your database server may be so vulnerable in other manner.
Your database server may be similarly vulnerable in another manner.
</para>
</note>
@ -819,7 +819,7 @@ $result = mssql_query($query);
</simpara>
<simpara>
These attacks are mainly based on exploiting the code not being written
with security in mind. Never trust on any kind of input, especially
with security in mind. Never trust any kind of input, especially that
which comes from the client side, even though it comes from a select box,
a hidden input field or a cookie. The first example shows that such a
blameless query can cause disasters.
@ -839,14 +839,14 @@ $result = mssql_query($query);
found in <link linkend="ref.variables">Variable Functions</link> and
in <link linkend="ref.ctype">Character Type Functions</link>
(e.g. <function>is_numeric</function>, <function>ctype_digit</function>
respectively) onwards the
respectively) and onwards to the
<link linkend="ref.pcre">Perl compatible Regular Expressions</link>
support.
</simpara>
</listitem>
<listitem>
<para>
If the application waits for numerical input, consider to verify data
If the application waits for numerical input, consider verifying data
with <function>is_numeric</function>, or silently change its type
using <function>settype</function>, or use its numeric representation
by <function>sprintf</function>.
@ -871,7 +871,7 @@ $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d
<function>addslashes</function> or <function>addcslashes</function>.
See <link linkend="security.database.storage">the first example</link>.
As the examples shows, quotes burnt into the static part of the query
is not enough, and can be easily hacked.
is not enough, and can be easily cracked.
</simpara>
</listitem>
<listitem>
@ -893,10 +893,10 @@ $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d
<simpara>
Besides these, you benefit from logging queries either within your script
or by the database itself, if it supports. Obviously, the logging is unable
or by the database itself, if it supports logging. Obviously, the logging is unable
to prevent any harmful attempt, but it can be helpful to trace back which
application has been circumvented. The log is not useful by itself, but
through the information it contains. The more detail is generally better.
through the information it contains. More detail is generally better than less.
</simpara>
</sect3>
</sect2>