 |
|
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

March 10th, 2007, 07:47 AM
|
 |
Banned (not really)
|
|
Join Date: Dec 1999
Location: Brussels, Belgium
|
|
Quote: | Originally Posted by buggedcom To protect your includes from being accessed via the browser why not just put them in a .htaccess protected directory. that way the scripts can still include them and the browser can't see them. |
I'm sure that was mentioned, but it's not an option for everyone. It's hard to require that if you're the designer of a program, too. Not everyone runs Apache, either. But yes, that is one good method.
---John Holmes...
__________________
-- Cigars, whiskey and wild, wild women. --
|

March 11th, 2007, 12:32 PM
|
|
Registered User
|
|
Join Date: Mar 2007
Posts: 17
Time spent in forums: 7 h 21 m 17 sec
Reputation Power: 0
|
|
Tip: use "mysql_real_escape_string()" for SQL statement and not "addslashes()".
Secure GET & POST values:
PHP Code:
<?php
$_GETS = array_map('mysql_real_escape_string', $_GET);
$_POSTS = array_map('mysql_real_escape_string', $_POST);
mysql_query("SELECT * FROM `table` WHERE ".
"`get1` = '".$_GETS['key1']."' AND ".
"`get2` = '".$_GETS['key2']."' AND ".
"`post1` = '".$_POSTS['key1']."' AND ".
"`post2` = '".$_POSTS['key2']."'");
// ... etc ...
?>
and then you dont have to worry about forgetting to do this.
|

March 11th, 2007, 02:15 PM
|
 |
Banned (not really)
|
|
Join Date: Dec 1999
Location: Brussels, Belgium
|
|
Quote: | array_map('stripslashes', $_GET) |
Quote: | array_map('mysql_real_escape_string', $_GET) |
Personal preference here, but I don't think applying functions blindly to the entire $_GET and $_POST arrays is good for efficiency and scalability.
IF I've already validated a string and I KNOW the value is going into a query, then I apply mysql_real_escape_string() to that value only.
Also, I only need to run stripslashes on a value if it's already validated to a string and I KNOW I'm going to turn around and use that value elsewhere.
---John Holmes...
|

March 11th, 2007, 06:28 PM
|
 |
Web Developer/Musician
|
|
Join Date: Nov 2004
Location: Tennessee Mountains
|
|
|
I don't mind doing that with the entire array, if the majority of values are destined for the database. If only 2 or 3 values out of say 20 in a form are not destined for the db it seems to make sense to me to do that. Better to use the pre-written function for that than typing out 17 calls to mysql_real_escape_string, just because not all request varaibles (get or post) are meant for the database.
My db abstraction has it's own escaping method to use with db values and prepared statements, so for inserts and updates I rarely escape out side of the db abstraction, but I have the option to do so If need be.
__________________
Visit my blog PHP && Life for technical articles and technology musings.
Last edited by Hammer65 : March 12th, 2007 at 08:40 AM.
|

March 26th, 2007, 03:16 PM
|
|
Registered User
|
|
Join Date: Mar 2007
Location: Ontario, Canada
|
|
|
PHP Session Hijacking
Greetings,
Great information and and resources for the newbie PHP developer. I have noticed one security issue that has not been addressed. PHP Session Hijacking.
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 (and I stress again that it's best just to avoid this), 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.
PHP Code:
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:
PHP Code:
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.
Another solution to help prevent Session Hijacking is to handle sessions with custom handlers. This allows you to store the session information in a database (encrypted form of course). A little trick to help validate sessions is to assign the user agent to the session entry in the database. When you verify a users session id, you should also compare the user agent.
In conclusion, you cannot prevent session hijacking completely, but you can take measure to minimize the damage and information that can be stolen.
Smart programming and proper security implementations.
Cheers!
|

March 28th, 2007, 09:46 AM
|
 |
Rocking my php-ness
|
|
Join Date: Dec 2004
Location: Boston, MA
|
|
I have some code I use as part of a session class to create / use 1 time session IDs that regenerate on each request. Here is the code put together into one easy to use function:
PHP Code:
/*
Starts a session, regenerates an id and destroys the old session to
help prevent session hijacking
*/
function safer_session_start()
{
// Start the session
session_start();
// Assign current contents to a temp var
$s = $_SESSION;
// Get rid of $_SESSION
$_SESSION = null;
unset($_SESSION);
// Get current session id
$old_id = session_id();
// Make a new session id
session_regenerate_id();
// Get the new session id
$new_id = session_id();
// Tell php we want to use the old session
session_id($old_id);
// Buh bye old session!!! Ohh NOES!!
session_destroy();
// Tell php it's back to the new session!
session_id($new_id);
// Start it up proper!
session_start();
// Put back our session var(s)
$_SESSION = $s;
}
Last edited by J_Tree : March 28th, 2007 at 09:47 AM.
Reason: funny spacing
|

March 28th, 2007, 10:06 AM
|
 |
Banned (not really)
|
|
Join Date: Dec 1999
Location: Brussels, Belgium
|
|
Quote: | Originally Posted by J_Tree I have some code I use as part of a session class to create / use 1 time session IDs that regenerate on each request. Here is the code put together into one easy to use function | WTH would you go through all of that instead of just calling session_regenerate_id() by itself? Kind of seems like a waste. :shrug:
|

March 28th, 2007, 02:03 PM
|
 |
Rocking my php-ness
|
|
Join Date: Dec 2004
Location: Boston, MA
|
|
|
Well . . .
In my testing using php 4, session_regenerate_id() doesn't seem to remove old session data, it just starts a new session with a new id. This means that if someone were to capture my previous ID they could have access to my session data even though I was using a new copy. Who cares who is using which copy if my credit card or social security number is stored in there. The method I posted above explicitly clears my old session data assigned with my previous ID and moves it to my new session. For all intents and purposes, it creates a 1 time 1 use Session ID.
The manual for this function makes it seem as if all that is needed is session_regenerate_id(), but real life testing shows differently.
EDIT: Reading the manual now shows an optional argument for this function as of php 5.1 that seems to address the issue my function solves. So I guess if you have php < 5.1, My function would be a replacement.
Last edited by J_Tree : March 28th, 2007 at 02:06 PM.
|

March 28th, 2007, 03:13 PM
|
|
Registered User
|
|
Join Date: Mar 2007
Location: Ontario, Canada
|
|
|
J_Tree,
I see where you are coming from, and I agree with you. I have not developed with PHP 4 in some time now, but I do remember having to write a similar function as your safer_session_start( ).
They have come a long way with PHP 5, but in reality, PHP 4 is still widely used - so its good to know the issues and security vulnerabilities.
Good post.
|

February 6th, 2008, 11:46 AM
|
 |
PHP is my Love!
|
|
Join Date: Jul 2003
Location: Kafr Sakr, Egypt
Posts: 87
Time spent in forums: 12 h 13 m 5 sec
Reputation Power: 10
|
|
|
Don't allow user to upload php files
I think it is important, in the case of having file upload related to user, to check the file type that is going to be uploaded to prevent any upload php file .i.e with .php extension.
|

February 6th, 2008, 01:09 PM
|
 |
Web Developer/Musician
|
|
Join Date: Nov 2004
Location: Tennessee Mountains
|
|
Quote: | Originally Posted by saidbakr Don't allow user to upload php files
I think it is important, in the case of having file upload related to user, to check the file type that is going to be uploaded to prevent any upload php file .i.e with .php extension. |
Always a good idea, however you should also ensure that you are correctly detecting the file extension.
Some upload scripts detect any instance of "gif" or "jpg" in a file name after A dot, not the correct dot but any dot. This is vulnerable to attacks through file names like
nasty.gif.php
It looks like a gif to the code but it's ACTUAL file extension is php. It may even be a gif file, but by embedding PHP code in an area of the file that is reserved for metadata or comments, once in a publicly available upload directory, it can be executed just as any PHP file can be. The binary gif code is simply interpreted the same way anything out side of <?php ?> is interpreted.
Don't rely on the mime type as reported by the browser, as this may be subject to spoofing.
|

February 6th, 2008, 11:38 PM
|
|
Registered User
|
|
Join Date: Feb 2008
Posts: 3
Time spent in forums: 18 m 51 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by JeffCT Ok, thanks. I am glad you brought that up and clarified, I was worried you were posting a "this topic sucks because it doesn't cover what I wanted".. kind of thing.
I'll have to look more into that, I admit I know very little (if anything) about "internal" PHP security. I don't know how exploitable it is but I did want to cover the common programming mistakes that leave your site so wide open that any 12 year old "hacker" could exploit it.
Hey - since you know more about that sort of thing than I do, maybe you could post the next topic? What do you say  |
I think it's a good posting. Security in PHP is very often disregarded...
|

April 28th, 2008, 09:54 AM
|
 |
Web Developer/Musician
|
|
Join Date: Nov 2004
Location: Tennessee Mountains
|
|
|
If you have been on this board for a while, you know that you see the same insecure code over and over. Some of this stuff comes from out of date books. A lot of it comes from online tutorials. The sad thing is, those tutorials aren't necessarily old ones. I see new scripts posted every day that come from tutorial sites, that are vulnerable to all manner of things we hit over and over here.
In addition to you yourself coding securely, if someone posts what looks like, or they have told you is, a pre-written script that is insecure, find out what site it's on, and raise hell with the author.
We are almost at PHP v 6.x and yet we still see 98% use of the OLD MySQL extension, mail forms that are major spammer bait and more XSS vulnerabilities then you shake 100 sticks at. It's bad for the language, bad for the livelihood of those that code it for a living, and it puts the security of anybody that uses the internet, including us at risk.
|

May 15th, 2008, 12:16 AM
|
 |
Wiser? Not exactly.
|
|
Join Date: May 2001
Location: Bonita Springs, FL
|
|
A lot of scripts handle access by including a 'secure.php' file which validates the user by session/posted username/passwords, and in the case of a login failure redirects to the login page.
Remember to always do this redirect in such a way that the rest of the script is not executed after the redirect. The easiest way to do this is using exit; after the redirect.
Example:
I've been recently looking over code for a company to identify security holes and they were doing this for their authentication. they had code which boils down to something like this:
Code:
secure.php
<?php
if (isset($_COOKIE['username']) && isset($_COOKIE['userpass'])){
$rs = mysql_query('SELECT password FROM users WHERE username="'.$_COOKIE['username'].'"');
if (mysql_num_rows($rs) == 0){
header('Location: login.php');
}
else {
$securepass=mysql_result($rs, 0, 0);
if (base64_decode($_COOKIE['userpass']) != $securepass){
header('location: login.php');
}
}
}
That file is used in an admin file as so:
Code:
edit.php
<?php
//Validate login, redirect to login page if incorrect.
include('secure.php');
$action = $_GET['action'];
if ($action == 'delete'){
mysql_query('DELETE FROM entries WHERE entry_id='.$_GET['id']);
echo 'Entry deleted';
}
?>
Now. Aside from the glaring SQL Injection problems, it is also possible for a completely unauthenticated user to delete stuff because they do not prevent the rest of the script from running.
A request to the URL http://www.site.com/admin/edit.php?action=delete&id=1
will generate a response like so:
Code:
HTTP/1.1 200 Ok
Location: login.php
Entry Deleted
The browser will happily redirect you to login.php and it looks like your code works, but if you look at the DB you'll be quick to notice entry_id #1 is no longer there because the delete was executed when the script finished up. The fix? Just exit after a redirect.
Code:
header('Location: login.php');
exit;
|

August 5th, 2008, 12:45 AM
|
 |
hanibal hector
|
|
|
|
Great tips, just found a small mistake on top of your post:
PHP Code:
$pages = array('index.html', 'page2.html', 'page3.html');
if( in_array($page, $pages) )
{
include($page);
{
else
{
die("Nice Try.");
}
The if bracket should be other direction
Cheers
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|