/    Sign up×
Community /Pin to ProfileBookmark

Preventing PHP injection

Does anyone know what the best way is to prevent php injection on a website? I’ve seen a few possibilities, such as using a validation token, using a regular expression in a while loop, but not sure which one to go with. Any help would be much appreciated and possibly some sample code to go with it so i can get a better idea

to post a comment
PHP

14 Comments(s)

Copy linkTweet thisAlerts:
@NogDogSep 26.2007 — Can you define what you mean by "PHP injection"? Are you talking about user-uploaded files that contain PHP code, or what?
Copy linkTweet thisAlerts:
@schnookieauthorSep 26.2007 — sorry about that, by PHP injection I mean, attackers being able to enter PHP code to be able to include fatal files, or remove files etc from the server either by entering it into the url or which ever way they normally go about doing it
Copy linkTweet thisAlerts:
@JoeHoldcroftSep 26.2007 — Ah, I think you mean by changing GET variables in the URL, right? Specifically those that are used in includes? So for example, you have $_GET['page'], and later on in the script, you run something like include($_GET['page'].'.php');, and theoretically, a user could enter a URL in the GET variable, to make it include something possibly malicious.

Well, to prevent this, I'd do something like this for your variable:
[code=php]$_GET['page'] = str_replace(array('.', '/'), '', $_GET['page']);[/code]
Of course, you will need to change $_GET['page'] to whatever your variable is.

Or, if you want to do it for all GET variables, do the following:
[code=php]
foreach($_GET as $var => $val) {
$_GET[$var] = str_replace(array('.', '/'), '', $_GET[$var]);
}
[/code]


This will remove any dots or slashes from the variable, meaning that no URLs will work as the 'hacker' would want them to.
Copy linkTweet thisAlerts:
@NogDogSep 26.2007 — As far as I know, the only way a hacker could get a PHP script to run on your site would be to actually put a PHP file on your site. This would mean that either they cracked your site's login and/or FTP user-name and password, or that they were able to upload a file via some existing script on your site. The former must be dealt with by using strong passwords and keeping them private, and possibly also by other site security measures such as restricting what IP address(es) can log in to your site, disabling login accounts after X number of failed login attempts, etc.

As far as files being uploaded via file upload pages on your site, you need to ensure that no uploaded file can be executed as a PHP page (or other server-side script or CGI page). One way would be to always save uploaded files to a directory outside of your web document root directory hierarchy, then providing a PHP script to serve that file. Alternatively, you could save it to a web directory and make sure that it does not have any file suffix that would cause the web server to send it to the PHP parser (ie: not ".php", ".php3", or any other suffix your site treats as a PHP file).
Copy linkTweet thisAlerts:
@NogDogSep 26.2007 — Ah, I think you mean by changing GET variables in the URL, right? Specifically those that are used in includes? So for example, you have $_GET['page'], and later on in the script, you run something like include($_GET['page'].'.php');, and theoretically, a user could enter a URL in the GET variable, to make it include something possibly malicious.

Well, to prevent this, I'd do something like this for your variable:
[code=php]$_GET['page'] = str_replace(array('.', '/'), '', $_GET['page']);[/code]
Of course, you will need to change $_GET['page'] to whatever your variable is.

Or, if you want to do it for all GET variables, do the following:
[code=php]
foreach($_GET as $var => $val) {
$_GET[$var] = str_replace(array('.', '/'), '', $_GET[$var]);
}
[/code]


This will remove any dots or slashes from the variable, meaning that no URLs will work as the 'hacker' would want them to.[/QUOTE]

Good point.

What I normally do is use the basename() function to just get the filename with no directory info:
[code=php]
$file = basename($_GET['file']);
[/code]

Then I can use the value of $file with the desired directory path with confidence that it will only look for that file name in the directory I specify in my script.
Copy linkTweet thisAlerts:
@schnookieauthorSep 26.2007 — ummm.... actually i didn't use $GET to include files.. i just used include to add the ones i wanted, and REQUEST to define the URLs.... this is my code:
[code=php]<?php

$value = $_REQUEST ['page'];
$crumbs = $value;
$label = $_REQUEST ['desc'];

if (! isset ($value) || !eregi("^(index|([0-9]{4}-[0-9]{2}-[0-9]{2}))/[a-z0-9]+$", $value)|| ! file_exists($value . '.html'))

{
$value= 'index/index.html';
$label='Latest Scripts';
$crumbs='index/index';

}
else
{
$value = $value . '.html';


}

?>[/code]



{ my html code in here}

and then....

<div class = "sidebar1" id = "sidebar1">
[code=php]<?php
include ("feeds.html");
?>[/code]

</div>

<div class = "mainContent" id = "mainContent">
[code=php]<?php
$file = file_get_contents($value);

print ($file);
?>[/code]

</div>


sidebar1 and maincontent are the left hand navigation and main body respectively and are both dynamic...... so i want to stop people from being able to use include to add dangerous files to the server.
Copy linkTweet thisAlerts:
@NogDogSep 26.2007 — $_REQUEST is just an ambiguous way of accessing user-supplied data. It is a super-set of $_GET, $_POST, and $_COOKIE super-global arrays, with duplicate indexes amongst those sources being resolved according to the [url=http://www.php.net/manual/en/ini.core.php#ini.variables-order]variables_order[/url] configuration parameter. Your scripts will be more robust if you use the specific super-global array based on the expected data source rather than the general $_REQUEST array.

But in any case, you can use [b]basename($_REQUEST['page'])[/b] to get just the name without any path info just as you could with $_GET.
Copy linkTweet thisAlerts:
@schnookieauthorSep 26.2007 — ok, i used basename($_REQUEST ['page']) instead of just $_REQUEST.... do you know how I can test it to see if it works? maybe like an example of code to add an include to the server.... basically php code injection....
Copy linkTweet thisAlerts:
@schnookieauthorSep 26.2007 — actually before you answer that... my links that are being dynamically generated don't work anymore.... those in mainContent and sidebar1.... i think that might be because the path info is necessary to create the links in the first place because its coming from the server...... (this is getting confusing)
Copy linkTweet thisAlerts:
@schnookieauthorSep 27.2007 — thanks a lot JoeHoldcroft. It worked perfectly.
Copy linkTweet thisAlerts:
@schnookieauthorSep 27.2007 — any idea how i can test it to make sure its actually doin what it's supposed to?
Copy linkTweet thisAlerts:
@TJ111Sep 27.2007 — If you use firefox, download the "hackbar" extension. Its designed to test malicious code in $_GET variables. I use it alot when using anything that involves $_GET, throwing different things at it to see what happens.
Copy linkTweet thisAlerts:
@LeeUSep 28.2007 — If you use firefox, download the "hackbar" extension. Its designed to test malicious code in $_GET variables. I use it alot when using anything that involves $_GET, throwing different things at it to see what happens.[/QUOTE]
Do you have the URL for that extension?
Copy linkTweet thisAlerts:
@TJ111Oct 01.2007 — Here is the link to the addon. It's a basic addon, and I keep it hidden by default, but very nice for testing how code can react to malicious script.

https://addons.mozilla.org/en-US/firefox/addon/3899
×

Success!

Help @schnookie spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.20,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...