Web Hosting Talk







View Full Version : How to secure my php script?


mystycs
03-12-2010, 07:46 PM
I have a php script that i want to be secured? How and what is the best way to go about securing it from xss and mysql exploits ect? Should i just add a strip_tags?

keserhosting
03-12-2010, 08:34 PM
In your php.ini file, add this line,

register_globals = Off

Or in an .htaccess file,

php_flag register_globals off

BH-Greg
03-12-2010, 08:57 PM
In your php.ini file, add this line,

register_globals = Off

Or in an .htaccess file,

php_flag register_globals off

Very good thing to do, If you do this It will secure your script in many ways.

speckl
03-13-2010, 01:00 AM
That is probably the worst advice on securing a php script I've ever heard. If the script is developed in PHP4, then that may be good advice, but the question is about XSS attacks.

There are many ways to secure a php script. It really depends on the script and the input methods of the script. Does it process a form? Are the form fields ran though reg expression? What about using is_numeric to prevent a form from processing if a field is NOT numeric? There are way to many ways to secure a script. You really need to look at each individual item and see what needs to be done to secure it.

JannuBl22t
03-15-2010, 06:45 PM
If you are including it in some file just do like this:

MainFile.php

define("IN_FILE", "");
include("yourfile.php");


yourfile.php

if(!defined("IN_FILE")) {
exit;
}

// Your code here

NoSupportLinuxHostin
03-15-2010, 06:58 PM
There are literally books written about developing secure code. Without looking at your source code, none of us will be able to give you perfect advice about securing your code. The advice given far is good advice in general and should as a good place to start.

One thing to always double check for are vulnerabilities in the code that allow for SQL injection attacks. Too many people don't scrub fields well enough. Here is a Wiki about the topic of SQL injection attacks:
http://en.wikipedia.org/wiki/SQL_injection

Here is a Wiki about XSS attacks:
http://en.wikipedia.org/wiki/Cross-site_scripting

Here is a PHP page about register_globals. As a general rule, you want to always make sure register_globals is disabled:
http://php.net/manual/en/security.globals.php

joelietz
03-15-2010, 07:45 PM
It's sad really - most sql injection can be blocked by simply running your queries (variables included) through mysql_real_escape_string or mysqli_real_escape_string before processing the queries. Now that can't block everything.. but generally the rest can be accomplished by limiting your input set so for usernames only accept 0-9 A-Z and a-z - if the intruder can't put quotes into the input that blocks out another whole range of potential attacks.

It's elementary dear Watson.

eeadmin
03-15-2010, 11:16 PM
I would suggest a framework of some sort. These systems are really good are removing sql type of attacks. If you have an inclination to go far and build large projects I would look at a framework. There was just an article on this in php arch http://www.phparch.com/2010/03/01/5-php-frameworks-you-should-check-out/ Really good start. Many of can help with all your security concerns.

n3r0x
03-16-2010, 03:30 AM
It's sad really - most sql injection can be blocked by simply running your queries (variables included) through mysql_real_escape_string or mysqli_real_escape_string before processing the queries. Now that can't block everything.. but generally the rest can be accomplished by limiting your input set so for usernames only accept 0-9 A-Z and a-z - if the intruder can't put quotes into the input that blocks out another whole range of potential attacks.

It's elementary dear Watson.

Using this will block 98% of the crap, and for XSS you just need to convert < > " to entities..

I validate ID numbers like this:


function is_valid_id($num)
{
if(is_numeric($num) && $num > 0)
{
return true;
}
return false;
}

Sometimes i even check against if it´s between 2 values..

tim2718281
03-16-2010, 07:31 AM
but generally the rest can be accomplished by limiting your input set so for usernames only accept 0-9 A-Z and a-z -

That's OK if all your users use the English alphabet.

Really, you should define what is valid, then validate user-supplied data to reject anything invalid.

This is easier said than done - how the heck do we write programs to validate, say, input in the Danish alphabet, if we don't know what the Danish alphabet actually is? (It's the English alphabet, plus Æ Ø Å, or lowercase æ ø å )

mattle
03-16-2010, 08:36 AM
That's OK if all your users use the English alphabet.

Really, you should define what is valid, then validate user-supplied data to reject anything invalid.

This is easier said than done - how the heck do we write programs to validate, say, input in the Danish alphabet, if we don't know what the Danish alphabet actually is? (It's the English alphabet, plus Æ Ø Å, or lowercase æ ø å )

...by using locale settings and PCRE's "\w" construct (locale-sensitive word characters)

Steve_Arm
03-16-2010, 01:55 PM
you can use this

preg_match('/^[\p{L}]+$/u', $str)

to match utf8 letters (characters).

eeadmin
03-16-2010, 02:00 PM
I thought for some reason the import_request_variables would do clean up for you. I cannot remember.

joza
03-16-2010, 03:33 PM
htmlpurifier is another php library that you can include so that you can use the functions inside to clean your uri requests or switch to codeigniter, my favourite php framework(integrated xss clean) :)

unity100
03-16-2010, 03:40 PM
mysql_real_escape_string for everything that will be used in db.

or just

foreach ($_REQUEST as $key => $value)
{
$_REQUEST[$key]=mysql_real_escape_string($_REQUEST[$key]);
}

on top of all of your scripts. though, this may cause some extra chars added to some form inputs that will not be used in a mysql entry. but its the most brutal way.

register globals totally depends on how you code your script. or what your script is. register globals being on does not mean that your code will be insecure and world will come crashing down. depends on the script being coded properly or not. even if you turn globals off, they can still inject code through form variables depending on your server, php version, and security stuff you are using or not using (like mod security).

the easy way to both have register globals functionality and security is simply going with what eeadmin said :

import_request_variables was made to fix register globals issues and also offer globals functionality. it imports variables with or without a prefix.

so, while coding, if you import all request variables with a prefix (say r_ for all request vars), you will both evade using damned $_REQUEST['keyhere'] type request array references, or having to manually assign request variables to internal variables. (which sometimes kinda undoes turning globals off, since you will have just moved the thing to a variable, and if you use that variable carelessly, it will still be same as before).

like,

foreach ($_REQUEST as $key => $value)
{
$_REQUEST[$key]=mysql_real_escape_string($_REQUEST[$key]);
}
import_request_variables("gp", "r_");

this will first clean all request variables (post and get) with mysql, then import all of them to variables prefixed with r_.

so, if you have a form field named username, after this code gets put on top it will be imported to $r_username in the script.

this way all the form input variables will be easily distinguishable, and you can avoid using them in risky positions. and wont have to go $_REQUEST['somekeyhere'] evertime you need to work on a form, or manually assign them to internal vars.

mattle
03-17-2010, 08:21 AM
foreach ($_REQUEST as $key => $value)
{
$_REQUEST[$key]=mysql_real_escape_string($_REQUEST[$key]);
}


This doesn't do you much good if you want to use the variables in other contexts as well (for example, displaying the results on the page as well.) Not to mention, it's basically just a workaround for Magic Quotes.

Instead, I would recommend using prepared db statements, or--as has been suggested--a db framework to ensure that all inputs are sanitized properly.

unity100
03-17-2010, 03:35 PM
This doesn't do you much good if you want to use the variables in other contexts as well (for example, displaying the results on the page as well.) Not to mention, it's basically just a workaround for Magic Quotes.

Instead, I would recommend using prepared db statements, or--as has been suggested--a db framework to ensure that all inputs are sanitized properly.

what difference does it make. regardless of what you do, you are going to isolate anything coming from forms and use their relevant variables, array keys, whatever cautiously and wont mix them like normal vars.

the needs wont change if you prepare your db statements or not. you still cant shove anything coming from forms directly into statements. you will sanitize. it doesnt matter whether you do the sanitization in a function that is doing querying in some db class or at the start of the script - you will still do the same sanitization.

mattle
03-19-2010, 05:10 PM
what difference does it make. regardless of what you do, you are going to isolate anything coming from forms and use their relevant variables, array keys, whatever cautiously and wont mix them like normal vars.

the needs wont change if you prepare your db statements or not. you still cant shove anything coming from forms directly into statements. you will sanitize. it doesnt matter whether you do the sanitization in a function that is doing querying in some db class or at the start of the script - you will still do the same sanitization.

The difference is that by abstracting the db routines, you are

a) less likely to forget your validation
b) able to keep your code clean
c) reuse basic routines in other projects

I like most of my code to look like this (and know that it's safe):


$Object = new Object($key);
$Object->update($_POST);
$Object->save();

tim2718281
03-20-2010, 09:36 AM
There are two separate things here:

1) Checking the user input for validity.

The reason for this is to improve the user's experience.

For example, if there is a form to search for restaurants in a particular zip code, it may be felt better to respond to invalid zip codes with a message "the zip code 123456 is not valid" rather than "no restaurants were found with zip code 123456".

2) Protecting against SQL injection attacks.

If the program takes the user input and uses it to build an SQL statement, then the program needs to protect against SQL injection. One technique is to use an SQL abstraction layer which incorporates the necessary protection for each SQL database it supports.

But if instead of taking user input and using it to build an SQL statement, the program uses prepared SQL statements, then SQL injection is not possible, so the program does not need to protect against it.

Some people think that using prepared SQL is a better technique than using a method susceptible to SQL injection together with code to protect against it.

jadursupport
03-20-2010, 06:45 PM
If you know how to use Zend then you can use the zend encoder from www dot zend dot com
A few simple techniques can help to hide PHP, possibly slowing down an attacker who is attempting to discover weaknesses in your system. By setting expose_php = off in your php.ini file, you reduce the amount of information available to them.

Another tactic is to configure web servers such as apache to parse different filetypes through PHP, either with an .htaccess directive, or in the apache configuration file itself. You can then use misleading file extensions:
1 Hiding PHP as another language

# Make PHP code look like other code types
AddType application/x-httpd-php .asp .py .pl
Or obscure it completely:

2 Using unknown types for PHP extensions

# Make PHP code look like unknown types
AddType application/x-httpd-php .bop .foo .133t
Or hide it as html code, which has a slight performance hit because all html will be parsed through the PHP engine:

3 Using html types for PHP extensions

# Make all PHP code look like html
AddType application/x-httpd-php .htm .html

For this to work effectively, you must rename your PHP files with the above extensions. While it is a form of security through obscurity, it's a minor preventative measure with few drawbacks.

gil719
09-09-2010, 04:37 PM
I found this online service that I use. I found it at www[dot]gstudios[dot]org/php-encrypter.php and it allows me to encrypt it so that no one can view the actual source code. I hope this works!