mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-15 16:38:54 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@336340 c90b9560-bf6c-de11-be94-00142212c4b1
161 lines
5.9 KiB
XML
161 lines
5.9 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- splitted from ./index.xml, last change in rev 1.66 -->
|
|
<chapter xml:id="security.globals" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Using Register Globals</title>
|
|
&warn.deprecated.feature-5-3-0.removed-5-4-0;
|
|
<para>
|
|
Perhaps the most controversial change in <acronym>PHP</acronym> is when the default value
|
|
for the <acronym>PHP</acronym> directive <link linkend="ini.register-globals">
|
|
register_globals</link> went from ON to OFF in <acronym>PHP</acronym>
|
|
<link xlink:href="&url.php.release4.2.0;">4.2.0</link>. Reliance on this
|
|
directive was quite common and many people didn't even know it existed
|
|
and assumed it's just how <acronym>PHP</acronym> works. This page will explain how one can
|
|
write insecure code with this directive but keep in mind that the
|
|
directive itself isn't insecure but rather it's the misuse of it.
|
|
</para>
|
|
<para>
|
|
When on, register_globals will inject your scripts with all
|
|
sorts of variables, like request variables from <acronym>HTML</acronym> forms. This
|
|
coupled with the fact that <acronym>PHP</acronym> doesn't require variable initialization
|
|
means writing insecure code is that much easier. It was a difficult
|
|
decision, but the <acronym>PHP</acronym> community decided to disable this directive by
|
|
default. When on, people use variables yet really don't know for sure
|
|
where they come from and can only assume. Internal variables that are
|
|
defined in the script itself get mixed up with request data sent by
|
|
users and disabling register_globals changes this. Let's demonstrate
|
|
with an example misuse of register_globals:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Example misuse with register_globals = on</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// define $authorized = true only if user is authenticated
|
|
if (authenticated_user()) {
|
|
$authorized = true;
|
|
}
|
|
|
|
// Because we didn't first initialize $authorized as false, this might be
|
|
// defined through register_globals, like from GET auth.php?authorized=1
|
|
// So, anyone can be seen as authenticated!
|
|
if ($authorized) {
|
|
include "/highly/sensitive/data.php";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
When register_globals = on, our logic above may be compromised. When
|
|
off, <varname>$authorized</varname> can't be set via request so it'll
|
|
be fine, although it really is generally a good programming practice to
|
|
initialize variables first. For example, in our example above we might
|
|
have first done <literal>$authorized = false</literal>. Doing this
|
|
first means our above code would work with register_globals on or off as
|
|
users by default would be unauthorized.
|
|
</para>
|
|
<para>
|
|
Another example is that of <link linkend="ref.session">sessions</link>.
|
|
When register_globals = on, we could also use
|
|
<varname>$username</varname> in our example below but again you must
|
|
realize that <varname>$username</varname> could also come from other
|
|
means, such as GET (through the <acronym>URL</acronym>).
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Example use of sessions with register_globals on or off</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// We wouldn't know where $username came from but do know $_SESSION is
|
|
// for session data
|
|
if (isset($_SESSION['username'])) {
|
|
|
|
echo "Hello <b>{$_SESSION['username']}</b>";
|
|
|
|
} else {
|
|
|
|
echo "Hello <b>Guest</b><br />";
|
|
echo "Would you like to login?";
|
|
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
It's even possible to take preventative measures to warn when forging is
|
|
being attempted. If you know ahead of time exactly where a variable
|
|
should be coming from, you can check to see if the submitted data is
|
|
coming from an inappropriate kind of submission. While it doesn't
|
|
guarantee that data has not been forged, it does require an attacker to
|
|
guess the right kind of forging. If you don't care where the request
|
|
data comes from, you can use <varname>$_REQUEST</varname> as it contains
|
|
a mix of GET, POST and COOKIE data. See also the manual section on
|
|
using <link linkend="language.variables.external">variables from external
|
|
sources</link>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Detecting simple variable poisoning</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
if (isset($_COOKIE['MAGIC_COOKIE'])) {
|
|
|
|
// MAGIC_COOKIE comes from a cookie.
|
|
// Be sure to validate the cookie data!
|
|
|
|
} elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) {
|
|
|
|
mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']);
|
|
echo "Security violation, admin has been alerted.";
|
|
exit;
|
|
|
|
} else {
|
|
|
|
// MAGIC_COOKIE isn't set through this REQUEST
|
|
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Of course, simply turning off register_globals does not mean your code
|
|
is secure. For every piece of data that is submitted, it should also be
|
|
checked in other ways. Always validate your user data and initialize
|
|
your variables! To check for uninitialized variables you may turn up
|
|
<function>error_reporting</function> to show
|
|
<constant>E_NOTICE</constant> level errors.
|
|
</para>
|
|
<para>
|
|
For information about emulating register_globals being On or Off, see this <link linkend="faq.misc.registerglobals">FAQ</link>.
|
|
</para>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|