Solved

PHP Security issues

Posted on 2010-11-30
9
413 Views
Last Modified: 2012-05-10
Hello all,

 I'm new in PHP but I have web scripting back ground. I am coding a website which will fit my needs. Regardless to say security subject makes me worry the most.

 I have a programmer who is dealing with our websites for some years, but I would like to do it myself again. Till now, everything is going smooth. Our website got hacked before that's why it is making me more nervous.

 We had poison null byte attacks, session stealing, adding <script> to our database etc... How do I protect our websites from such hack attempts?

Thank you for your help in advance.
0
Comment
Question by:pixalax
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
9 Comments
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 34239628
Start your study here:
http://php.net/manual/en/security.php

And learn about PHPSEC.
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 34239669
If you've experienced session stealing and script insertion, you might want to change hosting services (at once)!  I use and recommend ChiHost.com.  They have great support and are very security conscious.

The overall philosophy for handling any external input is "accept only known good values."  In practice, this means testing everything that comes from outside your script, and only using it if it is good.  That is the opposite of trying to exclude bad values.  Nothing wrong with excluding bad values, but that is not enough.  If you expect an integer, test for it.  If you expect that the input data will be text, and not HTML, use strip_tags().  Learn about mysql_real_escape_string() and use it before you put information into your data base.  Learn about htmlentities() and use it before you echo data to the browser.  Things like that will overcome a great many issues.
0
 
LVL 2

Author Comment

by:pixalax
ID: 34239868
Thank you for the info.
Well currently I am using following function for security;

For Integers;
// CHECK IF VARIABLE IS INTEGER / NUMBER
#IF SWITCH = 1, IT WILL CHECK IF IT IS INTEGER AND IF NOT ECHO ERROR.
	function check_id ($id, $switch = 0) {
		
		if ($switch == 1) {
			$id = $this->clean($id, 1);
			
			if (!isset($id) || !is_numeric($id) ) {
			echo "<div class=\"error\">Data (<strong>{$id}</strong>) is not a number.</div>";
			exit;
			}
			
		}else {
		
			if (isset($id)) {
				$id = $this->clean($id, 1);
				
				if (!is_int($id)) {
					settype($id, "integer");
				}
			}else {
				unset($id);
			}
		}
		
		return $id;
 	}

Open in new window


For strings (FOR USING EDITORS such as CK Editor, I have no idea what to add for security);
// CHECK IF VARIABLE IS STRING.
#IF SWITCH = 1, IT WILL PREPARE THE STRING FOR EDITOR (ALLOWING HTML).
	function check_string ($string, $switch = 0) {
		if (isset($string)) {
			if ($switch == 0) {
				$string = $this->clean($string);
				
				if (!is_string($string)) {
					settype($string, "string");
				}
			}else {
				$string=trim($string);
				$string=stripslashes($string);
			}
		}else {
			unset($string);
		}
		
		return $string;
 	}

Open in new window


My Cleaning function
// CLEAN THE VARIABLE
# IF SWITCH = 1, IT WILL SET $veri AS INTEGER ELSE STRING.
	function clean ($veri, $int=0) {
		if(!get_magic_quotes_gpc()) {
			$veri = addslashes($veri);
		}
		$veri = mysql_real_escape_string($veri);
		$veri = trim($veri);
		$veri = htmlentities($veri);
		if ($int == 1) {
			$veri = strip_tags((int)($veri));
		}else {
			$veri = strip_tags((string)($veri));
		}
		return $veri;
 	}

Open in new window


I also check variables if they are set with $_POST and $_GET super global s;
function check_get_post ($veri) {
		if(is_array($veri)) {
			foreach ($veri as $key => $value) {
				
				if (isset($_GET[$key]) && isset($_POST[$key])) {
				echo "Security Warning. Log has been created and administrators are informed.";
				exit;
				}
			}
			
		}else {
			
			if (isset($_GET[$veri]) && isset($_POST[$veri])) {
				echo "Security Warning. Log has been created and administrators are informed.";
				exit;
			}
			
		}
 	}

Open in new window


These are only protection measures I took. I don't know if it is enough or not.

What I really would like to know is;
1. What kind of security measures I can take for receiving rich text editor's form data?
2. For Sessions, I only use cookies, I believe I also have to record some stuff to database each time each user logs in (such as log in key). How do I do that? How Should I do that?

Thank you for your help.
0
Major Incident Management Communications

Major incidents and IT service outages cost companies millions. Often the solution to minimizing damage is automated communication. Find out more in our Major Incident Management Communications infographic.

 
LVL 110

Expert Comment

by:Ray Paseur
ID: 34240126
Some of these code segments appear to be kind of old, and maybe application specific.  The subject of security is too big to address in a back-and-forth dialog at EE.  Information Technology Security is not a full-time four year college major in the Engineering school at the University of Maryland and there are a number of master's degrees, too.

To handle RTE form input data use mysql_real_escape_string() when you store the data into your data base.  Use htmlentities() when you echo the output to the browser.  You might want to go a little further, too.  Do you expect your clients to insert any HTML or SCRIPT?  If not, why not just translate all the < characters into "LT" or something like that.

To handle client logins, you can use a design pattern like this one:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_2391-PHP-login-logout-and-easy-access-control.html

Data validation is data-specific, but the new PHP filter_var() functions are very helpful.  Here is how I validate an email address.  I am sure you can think of many other data types that you might want to validate.
<?php // RAY_email_validation.php
error_reporting(E_ALL);



// A FUNCTION TO TEST FOR A VALID EMAIL ADDRESS, RETURN TRUE OR FALSE
function check_valid_email($email)
{
    // IF PHP 5.2 OR ABOVE, WE CAN USE THE FILTER
    // MAN PAGE: http://us3.php.net/manual/en/intro.filter.php
    if (strnatcmp(phpversion(),'5.2') >= 0)
    {
        if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) return FALSE;
    }
    // IF LOWER-LEVEL PHP, WE CAN CONSTRUCT A REGULAR EXPRESSION
    else
    {
        $regex
        = '/'                       // START REGEX DELIMITER
        . '^'                       // START STRING
        . '[A-Z0-9_-]'              // AN EMAIL - SOME CHARACTER(S)
        . '[A-Z0-9._-]*'            // AN EMAIL - SOME CHARACTER(S) PERMITS DOT
        . '@'                       // A SINGLE AT-SIGN
        . '([A-Z0-9][A-Z0-9-]*\.)+' // A DOMAIN NAME PERMITS DOT, ENDS DOT
        . '[A-Z\.]'                 // A TOP-LEVEL DOMAIN PERMITS DOT
        . '{2,6}'                   // TLD LENGTH >= 2 AND =< 6
        . '$'                       // ENDOF STRING
        . '/'                       // ENDOF REGEX DELIMITER
        . 'i'                       // CASE INSENSITIVE
        ;
        if (!preg_match($regex, $email)) return FALSE;
    }

    // FILTER_VAR OR PREG_MATCH DOES NOT TEST IF THE DOMAIN IS ROUTABLE
    $domain = explode('@', $email);

    // MAN PAGE: http://us3.php.net/manual/en/function.checkdnsrr.php
    if ( checkdnsrr($domain[1],"MX") || checkdnsrr($domain[1],"A") ) return TRUE;

    // EMAIL IS NOT ROUTABLE
    return FALSE;
}




// DEMONSTRATE THE FUNCTION IN ACTION
$e = '';
if (!empty($_GET["e"]))
{
    $e = $_GET["e"];
    if (check_valid_email($e))
    {
        echo "<br/>VALID: $e \n";
    } else
    {
        echo "<br/>BOGUS: $e \n";
    }
}
// END OF PHP - PUT UP THE FORM
?>
<form method="get">
TEST A STRING FOR A VALID EMAIL ADDRESS:
<input name="e" value="<?php echo $e; ?>" />
<input type="submit" />
</form>

Open in new window

0
 
LVL 25

Expert Comment

by:madunix
ID: 34240687
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 34244981
Agree with madunix: OWASP is a good organization to get involved with.  Attend their conferences - you will develop contacts and a knowledge base that is very valuable.
0
 
LVL 25

Accepted Solution

by:
madunix earned 500 total points
ID: 34252233
@pixalax    >>>> adding <script> to our database <<<

Well, adding scripts to databases and such — you should probably have filters in your application for XSS (cross-site scripting), both to avoid storing such HTML and to avoid displaying it.

OWASP Guide explains how to perform data validation, which is the best way to resolve XSS
it explains what XSS is @
http://www.owasp.org/index.php/Cross_Site_Scripting ;
http://www.virtualforge.de/vmovie/xss_selling_platform_v1.0.php
http://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
http://www.owasp.org/index.php/Guide_Table_of_Contents#Data_Validation
https://www.owasp.org/images/8/89/OWASP_Testing_Guide_V3.pdf
http://www.ibm.com/developerworks/web/library/wa-secxss/
http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

my recommendations:
there are several issues whose remediation lies in sanitizing user input. By verifying that user input does not contain hazardous characters, it is possible to prevent malicious users from causing your application to execute unintended operations, such as launch arbitrary SQL queries, embed JavaScript code to be executed on the client side, run various operating system commands etc. It is advised to filter out all the following characters:
"      | (pipe sign)
"      & (ampersand sign)
"      ; (semicolon sign)
"      $ (dollar sign)
"      % (percent sign)
"      @ (at sign)
"      ' (single apostrophe)
"      " (quotation mark)
"      \' (backslash-escaped apostrophe)
"      \" (backslash-escaped quotation mark)
"      < > (triangular parenthesis)
"      () (parenthesis)
"      + (plus sign)
"      CR (Carriage return, ASCII 0x0d)
"      LF (Line feed, ASCII 0x0a)
"      , (comma sign)
"      \ (backslash)


-Input encoding
Input encoding can protect against more than just Cross site scripting attacks. Things like SQL injection and command injection can also be checked prior to storing information in a database

-Output encoding
Developers must perform output encoding potentially many times for reach location the information is outputted

-To fix the <%00script> variant see Microsoft article 821349

-For UTF-7 attacks:
When possible, it is recommended to enforce a specific charset encoding (using 'Content-Type' header or <meta> tag).

-Basically, make sure your web server is up-to-date with latest security fixes/patches.

-Make sure you have filter every user input and output as proper encoding like UTF-8.

- OWASP  is a must

- i use ex. watchfile now IBM aapscan tools http://www-01.ibm.com/software/rational/offerings/websecurity/  to scan all my web application for security issues
0
 
LVL 2

Author Comment

by:pixalax
ID: 34259056
Thank you all for your time and concern.
These are really a lot of information to start with. Protecting database should be more easy.

Only 1 question left actually;
When I check forum scripts or any advanced CMS systems, I see in their member table, they have some cells like login_key, login_hash etc... Some how they connect it with cookies and session information to validate that it is the correct user and no funky things going on.

What is the short logic of this? Could any one show me with a small and short example for me to understand it correctly. I don't understand anything from reading 1000 pages about security and such things till I see the example code.  That's why I will have to search for example codes in all these security topics you gave me but it is a good start.

Thank you once again for your time and concern.
0
 
LVL 2

Author Closing Comment

by:pixalax
ID: 34278942
Thank you for your help. I guess I will have to figure out the rest.
0

Featured Post

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
PHP Curl Problem 10 68
Group By Function Required in PDF Output 21 61
apache does not start on Kali linux 4 87
How would I break down this array? 3 14
Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question