PDA

View Full Version : Using the vBulletin Input Cleaner


Alan @ CIT
22 Jun 2006, 20:35
Note: This article assumes that you are familier with PHP, and will introduce you to input filtering using vBulletin

Using the vBulletin Input Cleaner Class

Introduction

Most scripts will require data from a user at some point. When using this data, you should never assume that it is "clean" data. With XSS (Cross-Site Scripting) and SQL exploits being identified in scripts on a daily basis, you should do everything you can to ensure that all data coming from the user has been cleaned ("sanatized").

vBulletin provides us with the vB_Input_Cleaner class to do just this.
The vBulletin Input Cleaner class is setup when the page loads, and can be accessed as $vbulletin->input,

Data Types

When you accept data from the user, you should know what type of data you are expecting to receive. the vBulletin Input Cleaner allows the following types of data to be cleaned:

TYPE_NOCLEAN
Will not be cleaned
TYPE_BOOL
Will check it is either true or false
TYPE_INT
Will check that it is an integer
TYPE_UINT
Will check that it is an unsigned integer
TYPE_NUM
Will check that it is a number
TYPE_UNUM
Will check that it is an unsigned number
TYPE_UNIXTIME
Will check that it is a unix-style timestamp (unsigned int)
TYPE_STR
Will check that it is a string, and runs trim() on it
TYPE_NOTRIM
Will check that it is a string and will not run trim() on it
TYPE_NOHTML
WIll check that it is a string and run htmlspecialchars_uni() and trim() on it
TYPE_ARRAY
WIll check that it is an array
TYPE_FILE
Will check that it is a file (ie, uploaded by the user)You can also clean arrays of these types by using TYPE_ARRAY_<type>. For example, if you had an array of numbers, you could use TYPE_ARRAY_INT, or TYPE_ARRAY_NUM.

Cleaning Functions

The input cleaner class provides a number of useful functions that we can use to clean our data, depending on what data you wish to clean.

Cleaning Superglobal Arrays

By Superglobal, I mean $_POST, $_GET, $_REQUEST and so on. These arrays are created automaticly by PHP and contain the user-sent input. They are referenced in the vBulletin Input Cleaner by nice short single letter names. These are:

p - $_POST
g - $_GET
r - $_REQUEST
s - $_SERVER
e - $_ENV
c - $_COOKIE
f - $_FILESThe vBulletin Input Cleaner class provides the clean_array_gpc() function which allows us to clean data in these Superglobal arrays in one hit, without having to clean every individual variable in them.

Example:
$vbulletin->input->clean_array_gpc('p', array(
'name' => TYPE_NOHTML,
'age' => TYPE_UINT,
'usepm' => TYPE_BOOL
));

As you can see from this example, clean_array_gpc() takes 2 paramaters. The first paramater specifies which Superglobal array you wish to clean, and the second is an array of variables and their types.

So, in the example above, we are telling clean_array_gpc() that we wish to clean the $_POST array, and that $_POST contains 3 variables, 'name', 'age', and 'usepm', and that we wish to clean them as TYPE_NOHTML, TYPE_UINT and TYPE_BOOL respectivly.

Once cleaned, the new (clean) variables will be available in the $vbulletin->GPC array. So, to follow on from our previous example, we would use something like:

echo 'Your name is ' . $vbulletin->GPC['name'] . '<br />';
echo 'Your age is ' . $vbulletin->GPC['age'] . '<br />;
// etc...

Cleaning a Single Superglobal Variable

If you have a single variable that you wish to clean, use the clean_gpc() function. This function allows you to specify a single variable in any of the Superglobal arrays, and it's type.

Example:
$vbulletin->input->clean_gpc('g', 'age', TYPE_UINT);
echo 'Your age is: ' . $vbulletin->GPC['age'];

In this example, the 'age' variable in the $_GET Superglobal array will be cleaned to make sure it is an unsigned integer.

Cleaning a Single Variable

If you wish to clean a single variable that is not in one of the Superglobal arrays, you should use the clean() function.

Example:
$cleaned_var = $vbulletin->input->clean($dirty_var, TYPE_NOHTML);

From this example you can see that clean() takes 2 paramaters. The first is the variable that you wish to clean and the second is its type. Unlike the last 2 functions, clean() returns the variable directly.

Cleaning an Array of Variables

For times when you wish to clean an array of variables of mixed types, vBulletin provides the clean_array() function. The clean_array() function takes 2 paramaters. The first is the array to be cleaned, and the second is an array of variable names, and their types.

This function works exactly the same as clean_array_gpc(), except instead of specifying which Superglobal array to clean, you specify your own array.

Conclusion

So, to sum up - always run all input from the user through the vBulletin Input Cleaner! As well as being a good coding practice, this will drasticly decrease the chances of someone exploiting your script using an XSS or SQL attack.

Good luck using your new found knowledge of the vBulletin Input Cleaner class, and remember: If you get stuck, just ask! Knowledge sharing is what vBulletin.org is all about!

(Note: If you want to reproduce this article anywhere, I have no objections, but I do request that you give me credit for writing it, and a PM letting me know would be appreciated :))

noppid
22 Jun 2006, 20:40
Another fine article. Good work.

-=Sniper=-
22 Jun 2006, 20:56
very nice. thanks dude

Antivirus
28 Jun 2006, 22:49
Thanks Alan, i have been trying to use the cleaners as opposed to $_GET, $_POST, etc... this should help me well.

markp_2000
17 Jul 2006, 05:10
This is great. One question for a novice hack. How do we know there as something wrong? If I wanted a number and the user input a letter how would I know there was an error?

Do I need to further determine the cleaned variable is a number?

Mark

harmor19
17 Jul 2006, 17:53
You'd use
if(!is_numeric($vbulletin->GPC['age']))

Alan @ CIT
17 Jul 2006, 18:11
For reference, when checking numbers, if vBulletin doesn't find a number, it will return 0 instead. (when using TYPE_INT or TYPE_UINT)

The types and what it will return if it can't find what you are asking for is below:


TYPE_INT and TYPE_UINT: 0

TYPE_NUM and TYPE_UNUM: 0 (if you give it a value of "3 thousand", it will return 3)

TYPE_STR, TYPE_NOTRIM and TYPE_NOHTML: The data represented as a string

TYPE_BOOL: If it finds '1', 'true', 'y', 'yes', it will return 1 - anything else, it will return 0

TYPE_ARRAY: An empty array

TYPE_FILE: An empty files array with the size property set to '4' (indicates that it isn't a file)

TYPE_UNIXTIME: 0


Thanks,
Alan.

markp_2000
18 Jul 2006, 04:13
Thanks for the information. So I'm thinking I need to check the variables even before it posts with javascript or with php.

Danny.VBT
19 Jul 2006, 09:19
You can always do:


if ($vbulletin->GPC['foo'] == 0)
{
// Handle not expected type
}


If the value of 0 isn't a possibility.

Antivirus
08 Nov 2006, 15:57
how would you go about cleaning $_SESSION arrays? I have been cleaning the vars before placing them into $_SESSION but I wonder if there's some way to clean the $_SESSION afterwards.?

Billspaintball
22 Jan 2007, 05:44
Ohhh just what I was looking for.

Thanks Alan, its all clear now :D

ccasselman
14 Feb 2007, 16:33
Is there anyway I can use this class for an external script?

How would I approach that?

chad

Adrian.
24 Feb 2007, 16:53
Does this work on vB 3.0.x?

I can't seem to get it working. :(

adhari_com
07 Apr 2007, 08:54
Thank you so much for the great useful info, but I need to ask the TYPE_NOHTML does get rid of the <script> entry?

cashpath
23 Apr 2007, 22:45
Does this still work?

I put this..

$vbulletin->input->clean_array_gpc
('g', array(
'year' => TYPE_UINT,
'week' => TYPE_UINT,
'teamid' => TYPE_UNIT,
'team_ident' => TYPE_UNIT,
'pid' => TYPE_UINT,
'page' => TYPE_NOHTML));
$team_ident=$vbulletin->GPC['team_ident'];


And when I pass {url}?team_ident=thisisatest

I get a mysql error Invalid SQL:
SELECT * FROM table_teams WHERE id=thisisatest

foxfirediego
01 Oct 2007, 11:55
Does this still work?

I put this..

$vbulletin->input->clean_array_gpc
('g', array(
'year' => TYPE_UINT,
'week' => TYPE_UINT,
'teamid' => TYPE_UNIT,
'team_ident' => TYPE_UNIT,
'pid' => TYPE_UINT,
'page' => TYPE_NOHTML));
$team_ident=$vbulletin->GPC['team_ident'];


And when I pass {url}?team_ident=thisisatest

I get a mysql error Invalid SQL:
SELECT * FROM table_teams WHERE id=thisisatest

a lil too late :p
yes, works!
try this out:
$vbulletin->input->clean_array_gpc('g', array(
'year' => TYPE_INT,
'week' => TYPE_INT,
'teamid' => TYPE_INT,
'team_ident' => TYPE_INT,
'pid' => TYPE_INT,
'page' => TYPE_NOHTML));

$team_ident = $vbulletin->GPC['team_ident'];

{url}?team_ident=$team_ident
OR
{url}?team_ident=$vbulletin->GPC['team_ident']

also, escape ur mysql statement:
SELECT * FROM table_teams WHERE id = " . $db->escape_string($vbulletin->GPC['team_ident']) . "

Blaine0002
30 Nov 2007, 23:10
Can you define the maxes for both int and num?

Im using num for a post
When i enter 9999999999999 it passes -15304950.76
When i enter 999999999999 it passes 2764471.32
When i enter 99999999999 it passes 13161348.12
When i enter 9999999999 it passes -7273800.68
When i enter 999999999 it passes 12157520.92
When i enter 99999999 it passes 14100653.08
When i enter 9999999 it finally passes 9999999

Whats going on here??

NOTE: before it is displayed it is passed thru this. (truncates the number to 2 decimals without rounding.

function truncate($number, $places){
return intval($mynumber * pow(10,$places))/pow(10,$places);
}
$vbulletin->GPC['num'] = truncate($vbulletin->GPC['num'], 2);


--------------- Added 1196465816 at 1196465816 ---------------

Seems my Truncate function was causing it, But now it passes numbers like
1.0E+17

How do i restrict it from doing this and just passing the number?

ForgotenDynasty
19 Nov 2008, 23:38
How can I use a cleaned variable in a template

Jafo232
10 Dec 2008, 20:36
Does TYPE_NOHTML really clean HTML? I mean, take out script tags, etc?

Adem GENĒ
08 Mar 2009, 03:39
Hello,
I could not understand the full

Options delete:
checkbox = submit OR Delete text link


Code safe deleted for?

("DELETE FROM " . TABLE_PREFIX . "table_name
WHERE xxx_id = '".$_GET['id_delete']."'");

Thanks

Come2Daddy
22 May 2009, 21:06
Wow, exactly what I was looking for

thanks a lot, buddy

1Unreal
01 Aug 2009, 12:50
If Im using isset($_GET['foo']) will isset($vbulletin->GPC['foo']) work in the same way?

Sergio68
05 Sep 2009, 17:36
If Im using isset($_GET['foo']) will isset($vbulletin->GPC['foo']) work in the same way?
Same problem me, I don't understand if I can use this function or I have to use.
I inserted some code into the vbulletin and all the variables, cookies and sessions were deleted.

Antivirus
06 Sep 2009, 17:32
If Im using isset($_GET['foo']) will isset($vbulletin->GPC['foo']) work in the same way?

isset($vbulletin->GPC['foo']) will only return true if you are using the vbulletin input cleaner to clean your variables.

zero477
23 Nov 2012, 19:59
Excelent article!

stangger5
25 Sep 2014, 17:56
Does all vb versions use the same Input Cleaner ?
vb3 to vb4 ?

$vbulletin->input->clean_array_gpc

$vbulletin->input->clean_gpc

Thanks,, Great Article!

Dave
25 Sep 2014, 18:09
Does all vb versions use the same Input Cleaner ?
vb3 to vb4 ?

$vbulletin->input->clean_array_gpc

$vbulletin->input->clean_gpc

Thanks,, Great Article!


Take a look at http://www.vbulletin.com/docs/html/codestandards_gpc
Both will work, depending on what you do and need.