Ravens PHP Scripts: Forums
 

 

View next topic
View previous topic
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> Security - PHP Nuke
Author Message
stoney
New Member
New Member


Joined: Oct 10, 2005
Posts: 20

PostPosted: Mon Oct 10, 2005 3:40 pm Reply with quote

I am hoping some of you could help me with a project I am working on. I would like to write an article for my site on securing 3rd party addons such as modules and blocks, etc. I figured I would throw this out here and try to get as many opinions as possible of what one should look out for as there are quite allot of older and poorly written addons available.

What should every module include to make it secure?

What types of modules should you NEVER run?

What risks do blocks pose?

What types of blocks should you NEVER run?

What should every block include to make it secure?

Any other comments on the subject would be welcome. I think this would be useful to allot of people as well as myself.
 
View user's profile Send private message Visit poster's website
hitwalker
Sells PC To Pay For Divorce


Joined:
Posts: 5661

PostPosted: Mon Oct 10, 2005 4:00 pm Reply with quote

I think this is difficult to answer.
To my knowledge there isnt realy a unsecure block,since it isnt that vunerable and whatever attacker doesnt know how the block is named.
And if the block doesnt have any posting functions.

In the modules case thats different,but if including a simple code to make it safe would be all...then we didnt needed sentinel.

What type not to run ?...blocks or mods...
As you might read here and there using any addons on a site that allows any member or vistor to upload anyhing it can be classified as dangerous.
With that your opening a door to any possible hacking attemt.
That can be prevented (whitch usualy is the case) but there's always a chance they might find an opening.

As for the rest of your questions....well look around and read some... Smile
 
View user's profile Send private message
stoney
PostPosted: Mon Oct 10, 2005 4:16 pm Reply with quote

I have looked around some and many people do things allot of different ways. For instance the opening of every block goes something like:

Code:
if (!defined('MODULE_FILE')) {

   die ("You can't access this file directly...");
}


I have also seen it other ways including:

Code:
if (!eregi("modules.php", $PHP_SELF)) {

   die ("You can't access this file directly...");


Is there a prefered or more secure way or do they all accomplish the same thing.

Another thing that I noticed, and what actually got me thinking about this, was the change to the index.php in the PHP-Nuke HOWTO. It appears there was some type of risk by not defining what html files were allowed to be called.

I am hoping by this post to gather as many different things to look out for in order to prepare some type of lose guideline to follow when selecting and installing 3rd party stuff to your site. You can add the patched files, install NukeSentinel but one poorly secure module could really mess ya up i believe.
 
hitwalker
PostPosted: Mon Oct 10, 2005 4:29 pm Reply with quote

Well the code you show are for modules and not blocks.
Blocks look like :


Code:
if ( !defined('BLOCK_FILE') ) {

    Header("Location: ../index.php");
    die();



but i suggest you read a litle bit further cause this can be very time consuming.

If you wanna know about the how and the why about nuke stuff i suggest you read phpnuke howto from karakas.
 
stoney
PostPosted: Mon Oct 10, 2005 4:30 pm Reply with quote

You sound like a network administrator Razz
 
hitwalker
PostPosted: Mon Oct 10, 2005 4:32 pm Reply with quote

no im not.. Smile
Im just helping out and if needed pointing people in the right direction...
 
kguske
Site Admin


Joined: Jun 04, 2004
Posts: 6383

PostPosted: Mon Oct 10, 2005 6:32 pm Reply with quote

Chris Karakas' HowTo is a great guide, as hitwalker suggested. You might also want to compare the current patch files to the unpatched version - you can learn much from that. Use a file comparison tool like Beyond Compare or the free tool, WinMerge. These tools are also useful for understanding future changes, patches, tweaks, etc.

_________________
I google, therefore I exist...
Only registered users can see links on this board! Get registered or login!
 
View user's profile Send private message
Raven
Site Admin/Owner


Joined: Aug 27, 2002
Posts: 17086

PostPosted: Tue Oct 11, 2005 7:26 am Reply with quote

I have found that using Chaterv's latest methodology is the most secure way, thus far, to ensure that it is a legitimate block from YOUR site.
Code:
For Modules:

if (!defined('MODULE_FILE')) {
   die ("You can't access this file directly...");
}
and for Blocks:
if (!defined('BLOCK_FILE')) {
   die ("You can't access this file directly...");
}


As to other security measures, well, I would stay away from addons that don't use the $db->sql_query() type calls and directly access MySQL. Not that it is bad or wrong, but it is bypassing the "standard" access layer calls. If we are going to secure the database access then we would want to do it at the db layer level and directly access MySQL will bypass that. The major security risks with any script is XSS and/or critical path disclosure. I will not belabor the subjects here as they are probably some of the most discussed security issues on the 'net. NukeSentinel protects against most XSS attacks, but the answer lies in FIEO (Filter Input, Escape Output). Never trust any input. That is your secret formula. It's not the block or the module that's necessarily the issue, it's the way errors are handles and queries are written.
 
View user's profile Send private message
stoney
PostPosted: Tue Oct 11, 2005 10:16 am Reply with quote

Thanks Raven that gives me a direction to go in. Chatserv is our friend.. input is our enemy.
 
stoney
PostPosted: Tue Oct 11, 2005 4:19 pm Reply with quote

one other question on this topic...


Code:
if (!defined('MODULE_FILE')) { 

   die ("You can't access this file directly...");
}


I understand the basics of this... it is saying if NOT defined as MODULE_FILE die... but how is it defined as a module file?
 
Raven
PostPosted: Tue Oct 11, 2005 6:32 pm Reply with quote

stoney wrote:
one other question on this topic...


Code:
if (!defined('MODULE_FILE')) { 

   die ("You can't access this file directly...");
}


I understand the basics of this... it is saying if NOT defined as MODULE_FILE die... but how is it defined as a module file?
This is all based on Chat's fixes. Look at v3.1 and look in modules.php.
Code:
define('MODULE_FILE', true);
 
stoney
PostPosted: Tue Oct 11, 2005 6:39 pm Reply with quote

Ahh that explains allot... thanks yet again.
 
fkelly
Former Moderator in Good Standing


Joined: Aug 30, 2005
Posts: 3312
Location: near Albany NY

PostPosted: Wed Oct 12, 2005 2:18 pm Reply with quote

I've written what could be considered a couple of third party add ons for my site (a bicycle club site) -- they started as stand alones and then I made them into modules when I found Nuke. Then I found religion about security and I'm trying to understand what exposures there are. The suggestion to compare patched and unpatched code is valuable and I'm doing that. But I'm struggling to understand how the vulnerability for input works as indicated in this quote earlier in the thread:
Quote:
the answer lies in FIEO (Filter Input, Escape Output). Never trust any input. That is your secret formula. It's not the block or the module that's necessarily the issue, it's the way errors are handles and queries are written.


I have some screens where users input data about bike rides they are planning. Most of the data is taken from prescribed values on drop down boxes and I believe that there would be no problem there? Or am I wrong? Then there are one or two text input boxes (some text, some textareas). I guess someone could "inject" something there but I really don't understand the mechanism by which it could do harm.

The input screen is in a PHP function in a long PHP "program" that contains a bunch of functions. When submit is hit and some Javascript edits are satisfied, the form action is a separate PHP program that gets the values. Here's a little sample code:

Code:
$ride_name = $HTTP_POST_VARS['ride_name'];

    $member = $HTTP_POST_VARS['member'];
   $ridecat = $HTTP_POST_VARS['ridecat'];
    $distance = $HTTP_POST_VARS['distance'];
    $ride_description = $HTTP_POST_VARS['ride_description'];


In the example code above the ride name and description are more or less free form while the other values are prescribed by the input form or come from database lookups that the user has no control over.

Once these values (and others) are assembled a function is called to update the database. The call looks like this:

Code:
if(insert_ride($ride_name, $distance, $ride_description, $location_key, $fd_date, $fd_time, $member, $pace, $terrain, $ridecat, $ride_type, $freq, $lday, $lmth, $lyear, $month, $year, $day, $createdate, $mem))

      $ridemsg = 'Ride ' . stripslashes($ride_name) . ' was added to the database.';
    else
      $ridemsg = 'Ride ' . stripslashes($ride_name) . ' could not be added to the database.';
   select_rides_form($ridemsg);


In the insert functions an "addslashes" is done to each of the values and then the database update is done as per:

[code] $query = "insert into ".$user_prefix."_rides (ride_category, ride_type, ride_name, distance, ride_description, location_key, fd_date, fd_time,member, pace, terrain, created, created_by) values ('$ridecat', '$ride_type','$ride_name', '$distance', '$ride_description', '$location_key', '$add_date', '$fd_time', '$member', '$pace', '$terrain', '$createdate', '$mem')";
if( !($result = $db->sql_query($query)) )
{
$error = $db->sql_error();
$msg = $error[code] . ' ' . $error[message];
$msg .= "<br> for the following sql: ".$query."";
die($msg);
} [/code]

Sorry it took so long, but my question is what's the danger here. I have a vague understanding that the hacker could "inject" something nasty into say the $ride_description but I just don't see how or what it would do. If they want to put some obscenity in they could of course but we'd just erase it and ban them. So the only real danger is that they could use this to somehow get control over the system and I guess I just don't understand how this would work. If more filtering of input is required perhaps you could make a suggestion on what or point me to a source of that information. Thanks.
 
View user's profile Send private message Visit poster's website
kguske
PostPosted: Wed Oct 12, 2005 3:08 pm Reply with quote

Quote:

Most of the data is taken from prescribed values on drop down boxes and I believe that there would be no problem there?

Always validate / scrub any input variables. It's very easy to get around drop down boxes.

Having quotes around the variables in the insert / update helps, as does using a standard approach for accessing the database (this lets NukeSentinel do its job). Using $HTTP_POST_VARS limits input to forms (as opposed to changing variables through a URL, but it isn't fool proof.

The other thing you should check is that the text variables don't contain bad HTML - for example, some Javas cript that will be displayed after the record is stored. NukeSentinel will check for this, too, but it's best to only trigger that when it's a true attack. Check the Submit_News module for ideas on how to implement this, but make sure you use something prior to 7.7 since this checking was removed in 7.7 and 7.8 (and maybe 7.9, but I haven't checked).

Finally, if you're expecting an integer (e.g. for a record ID / key), use
Code:
$inputnumber = intval($inputnumber);
to strip out any "extra" stuff that might be in that variable.
 
Raven
PostPosted: Wed Oct 12, 2005 3:25 pm Reply with quote

I could write a quick script to override your form variables by doing a remote post script. There are a couple of ways to prevent that attack. The most assurred way is to basically have a "whitelist" of values. You could perform the check either before the post or before writing the data, depending on how the script is written. Bottom line, on the server side, compare the posted values against the only legitimate values. escaping/adding slashes does no good if the values are not properly cleansed.
 
stoney
PostPosted: Wed Oct 12, 2005 3:44 pm Reply with quote

What can the attacker do if he is able to put anything he wants into a data field. I could see spam to some stupid online poker site or something but are they really able to take control of a site simply by entering some hacker bable into a tables field?
 
Raven
PostPosted: Wed Oct 12, 2005 3:51 pm Reply with quote

I could inject Javascript and/or possible XSS.


Last edited by Raven on Wed Oct 12, 2005 5:00 pm; edited 1 time in total 
stoney
PostPosted: Wed Oct 12, 2005 4:57 pm Reply with quote

Only registered users can see links on this board! Get registered or login! - this is an old article (from 2000) on XSS but it explains it in simple terms that anyone can understand. Kinda funny too
 
Raven
PostPosted: Wed Oct 12, 2005 5:01 pm Reply with quote

Searching Google will reveal many good and current articles that reveal even more ways that this works and what to watch out for.
 
fkelly
PostPosted: Thu Oct 13, 2005 11:20 am Reply with quote

Thank you all for the suggestions. I did my reading thru Google this morning and found this link which gave me good explanations and a script I could try to "exploit" my input form. Only registered users can see links on this board! Get registered or login!
Within 2 hours I had hacked my site and input form. (The test version I run at home of course).

Then I took kguske's suggestion to look at how the submit news module validates input. So, for the two text fields that I have on the form I run them thru the mainfile routines as per:
Code:
$ride_description = $HTTP_POST_VARS['ride_description'];

    $ride_description = FixQuotes(nl2br(htmlspecialchars(check_words($ride_description))));


That seems to eliminate the script vulnerability since the less than sign is replace by &lt and similar with the greater than. The only problem here is that I currently allow people to put a href into the ride description to link to something they may have on their own home page or to a map file. That won't work this way. I was going to put the hrefs into their own input fields anyway and I was wondering if there is any standard way of "filtering" those. I'm guessing that if you let people input href's they could always link to something malicious?

Checking the values that come from drop down boxes is relatively simple and I'll do it but I'm a bit puzzled by Raven's statement:
Quote:
I could write a quick script to override your form variables by doing a remote post script.
in terms of how it would work. I guess I can see that if you knew the form name and the names of all the variables (form elements) you could create a similar form with bogus values for the drop down variables and then submit it to my "insert_ride.php" program but of course you'd need to know what the name of that is too. I'm not saying this is impossible of course, but it does seem a hacker would have to do a lot of work and experimentation to do this. Or, hummm ... could they do a view source and get the names they need? I wonder.

Incidentally, I have Sentinel running and the text that I inserted in my ride description field was:

Quote:
<xxx.script>alert('CSS Vulnerable')</xxx.script>
<img csstest=javascript:alert('CSS Vulnerable')>
&{alert('CSS Vulnerable')};

(I stuck the xxx's in cause sentinel doesn't like the script thing plain vanilla.)

and it was stored in the database. Before I made the changes to use htmlspecialchars() it was stored with the real greater than and less than signs which triggered the alert when I ran a report on that ride and after I made the changes the symbols were changed to their html entitities, thus not triggering the alert. Is Sentinel supposed to stop the first instance? If so I may have to check out how it is set up. I include header.php at the start of the insert_ride.php and that invokes mainfile.php which should in turn kick off sentinel.php if my reading of the code is right.

Thanks again for all your help on this board.
 
Raven
PostPosted: Thu Oct 13, 2005 12:23 pm Reply with quote

It's really very simple. If I am on your site that has the form, all I have to do is View Source and now I know everything about the form, including the Action to take on submission. Now do you see?
 
fkelly
PostPosted: Fri Oct 14, 2005 10:29 am Reply with quote

Quote:
It's really very simple. If I am on your site that has the form, all I have to do is View Source and now I know everything about the form, including the Action to take on submission. Now do you see?

Yes, now I see. Would it be correct to assume that the XSS filters in Sentinel would catch this? I realize that it's important to validate the form anyway and I'm working on it.

In that line, I decided to try to strip out all html tags from two of the "freeform" fields on the form. I looked at the submit_news index.php which appears to have a plaintext option and traced it back to mainfile.php and the check_html function. (This is in Nuke 7.4 with the 3.1 patches). Check_html starts out:
Code:
Function check_html ($str, $strip="") {

       include("config.php");
    if ($strip == "nohtml")
       global $AllowableHTML;
       if (!is_array($AllowableHTML)) $AllowableHTML =array('');


However, after looking at how it works I have concluded that when you say "nohtml" what you are really saying is "nohtml except for the html tags that are specified in config.php in the AllowableHTML array". So there is really no way to use this to prohibit all html from being entered? Is this right? Does anyone know of any functions in PHP or Nuke that will strip out all html tags? [Later edit: htmlentities() will make them "harmless" I guess but doesn't really remove them].

Also, again I'm uncertain about how this works but it appears if you don't pass in the "nohtml" parameter to this function then the AllowableHTML array will be set to null and the edits following:
Code:
if ($a = $AllowableHTML[$tag])

will not be carried out?

Any help interpreting this by someone more expert in PHP than I will be appreciated.
 
Raven
PostPosted: Fri Oct 14, 2005 1:38 pm Reply with quote

Quote:
Would it be correct to assume that the XSS filters in Sentinel would catch this?

Absolutely not. NukeSentinel is not a cure for the common coding mistakes Wink NukeSentinel protects against url cracks as well as a few other things Smile, but there is nothing that prevents the XSS scripting described above except you, the coder, must FIEO..
 
Display posts from previous:       
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> Security - PHP Nuke

View next topic
View previous topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2007 phpBB Group
All times are GMT - 6 Hours
 
Forums ©