Faking a post variable......is it possible?
Moderator: General Moderators
-
malcolmboston
- DevNet Resident
- Posts: 1826
- Joined: Tue Nov 18, 2003 1:09 pm
- Location: Middlesbrough, UK
Faking a post variable......is it possible?
Its not for my use, but rather defending my application.
is there anyway (even if its not perfectly feasible) for an EU to fake a post variable?
is there anyway (even if its not perfectly feasible) for an EU to fake a post variable?
-
malcolmboston
- DevNet Resident
- Posts: 1826
- Joined: Tue Nov 18, 2003 1:09 pm
- Location: Middlesbrough, UK
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
You can try to force the user to use your own forms.
To be honest your application should not care how a user chooses to send input. So long as it filtered effectively they can fake all the POST requests they want... As a quick rule - if a URI on your app does not expect any POST data, then your input filter should simply discard any such data immediately.
To be honest your application should not care how a user chooses to send input. So long as it filtered effectively they can fake all the POST requests they want... As a quick rule - if a URI on your app does not expect any POST data, then your input filter should simply discard any such data immediately.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
You can also write a function that collects post data into variables for you, in the expected formats. You tell it at the start of the script you're expecting 'foo' from POST and that it should be an integer. If it's not an integer it gets dropped. This is also a great way to prevent SQL injection.Maugrim_The_Reaper wrote:You can try to force the user to use your own forms.
To be honest your application should not care how a user chooses to send input. So long as it filtered effectively they can fake all the POST requests they want... As a quick rule - if a URI on your app does not expect any POST data, then your input filter should simply discard any such data immediately.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Here's a little class I just made up that would do some filtering of data coming in from any of the superglobals.
Bear in mind that POST and GET send strings almost all the time so a '42' wouldn't validate as is_int() but rather is_numeric(). The use of the PCRE match will be a big help.
If any of the expected variables are not found they are nulled, if they don't satisfy the level of sanity you set they are nulled, if they look ok, they are stored.
EDIT | Changed isset() to !empty() for the optional params.
Bear in mind that POST and GET send strings almost all the time so a '42' wouldn't validate as is_int() but rather is_numeric(). The use of the PCRE match will be a big help.
If any of the expected variables are not found they are nulled, if they don't satisfy the level of sanity you set they are nulled, if they look ok, they are stored.
Code: Select all
<?php
/*
A basic class for sanitizing data being received over HTTP
in PHP Super Globals.
Author: d11wtq (Chris Corbyn)
Date: 2006-04-19
License: none.. Just use it
*/
class htDataHandler
{
private
$htVars = array(),
$expectVars = array(), //Variable names
$expectLocs = array(), //POST, GET, COOKIE, REQUEST, SESSION
$expectTypes = array(), //Data types
$expectMatches = array(); //PCRE
public function __construct()
{
//
}
public function expectData($array)
{
foreach ($array as $k => $a)
{
if (is_array($a) && sizeof($a) >= 2)
{
$params = array_values($a);
$this->addVar($params, $k);
$this->addLoc($params, $k);
$this->addMatch($params, $k);
$this->addType($params, $k);
}
}
$this->validate();
}
public function getVar($v)
{
if (isset($this->htVars[$v])) return $this->htVars[$v];
}
private function validate()
{
foreach ($this->expectVars as $k => $v)
{
//It seems this is needed for variable variable in the superglobal scope
global ${$this->expectLocs[$k]};
if (isset(${$this->expectLocs[$k]}[$v]))
{
$tmp = ${$this->expectLocs[$k]}[$v]; //Read it but don't use it yet
if ($this->expectTypes[$k] && !$this->checkType($tmp, $this->expectTypes[$k])) $tmp = null;
if ($this->expectMatches[$k] && !$this->checkMatch($tmp, $this->expectMatches[$k])) $tmp = null;
$this->htVars[$v] = $tmp;
}
else $this->htVars[$v] = null;
}
}
private function checkType($v, $type)
{
switch (strtolower($type))
{
case 'str':
case 'string': return is_string($v);
case 'int':
case 'integer': return is_int($v);
case 'float': return is_float($v);
case 'double': return is_double($v);
case 'array': return is_array($v);
case 'object': return is_object($v);
case 'numeric': return is_numeric($v);
}
return false;
}
private function checkMatch($v, $pattern)
{
if (preg_match($pattern, $v)) return true;
else return false;
}
private function addVar($a, $k)
{
if (isset($a[0])) $this->expectVars[$k] = $a[0];
else $this->expectVars[$k] = null;
}
private function addType($a, $k)
{
if (isset($a[1])) $this->expectTypes[$k] = $a[1];
else $this->expectTypes[$k] = null;
}
private function addMatch($a, $k)
{
if (!empty($a[2])) $this->expectMatches[$k] = $a[2];
else $this->expectMatches[$k] = null;
}
private function addLoc($a, $k)
{
if (!empty($a[3])) $this->expectLocs[$k] = $this->getLocation($a[3]);
else $this->expectLocs[$k] = $this->getLocation(0);
}
private function getLocation($loc)
{
switch (strtolower($loc))
{
case 'get':
case '$_get':
case '_get': return '_GET';
//
case 'post':
case '$_post':
case '_post': return '_POST';
//
case 'cookie':
case '$_cookie':
case '_cookie': return '_COOKIE';
//
case 'session':
case '$_session':
case '_session': return '_SESSION';
//
case 'request':
case '$_request':
case '_request':
default: return '_REQUEST';
}
}
}
?>Code: Select all
/*
array (
array( string varName, string varType [, string match [, string requestLocation] ] )
)
*/
$a = array(
array('foo', 'string', '/^foo\d{2}$/i', 'get'),
array('bar', 'numeric')
);
$handler = new htDataHandler;
$handler->expectData($a);
echo $handler->getVar('foo');
echo $handler->getVar('bar');
Last edited by Chris Corbyn on Wed Apr 19, 2006 12:54 pm, edited 1 time in total.
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
Shiftlett some input on the matter
viewtopic.php?p=252019#252019
Hey Chris, going a bit off topic here, but instead only nulling the invalid values, perhaps check them in a garbage variables, which can be access via $this->_getRaw() or something..
viewtopic.php?p=252019#252019
Hey Chris, going a bit off topic here, but instead only nulling the invalid values, perhaps check them in a garbage variables, which can be access via $this->_getRaw() or something..
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Yeah I guess you could do that. I just knocked it up as a rough example.Jcart wrote:Shiftlett some input on the matter
viewtopic.php?p=252019#252019
Hey Chris, going a bit off topic here, but instead only nulling the invalid values, perhaps check them in a garbage variables, which can be access via $this->_getRaw() or something..
Part of the reason it's done like that is so that the logic reads nicely when checking it was validated ok.
Code: Select all
if ($obj->getVar('foo') !== null) echo $obj->getVar('foo');- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
I meant you do assign them null, but before you do
then
This would be useful for error reporting and such, although I usually do throw my getRaw functions through some sort of minimal filtering to prevent XSS attacks and such aswell
Talk to you on msn about this furtur, as we (or I
) sorta have hijacked the thread 
Code: Select all
$this->raw['variable'] = $variable;
// if is invalid
$variable = null;Code: Select all
public function getRaw($key) {
return $this->raw[$key];
}Talk to you on msn about this furtur, as we (or I
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Ah gotcha. Good point since if the data didn't validate you may still want to use it but do soemthing else with it.Jcart wrote:I meant you do assign them null, but before you dothenCode: Select all
$this->raw['variable'] = $variable; // if is invalid $variable = null;
This would be useful for error reporting and such, although I usually do throw my getRaw functions through some sort of minimal filtering to prevent XSS attacks and such aswellCode: Select all
public function getRaw($key) { return $this->raw[$key]; }
Talk to you on msn about this furtur, as we (or I) sorta have hijacked the thread
/me steers thread back on topic
No, you don't have to.R4000 wrote:yup it is possible, but you have to use sockets ect. and build your own fake http client as such.
Open socket, send headers (not hard to work out), ignore all output untill a blank newline (unless you want to parse return headers), then print everything after..
There are plugins for Firefox that allow you to modify forms realtime, there are proxies that let you do so, and more.
It is trivial - not nearly as complicated as you are implying it to be.
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
you can easily send post headers in a couple lines of code.. cURL
Your application should validate all the data on the server side to make sure the data is what it should be (ie accessory methods). Then you should not need to worry about a fake post. One of the weakness of javascript is since the validation is done on the client it can be bypassed and then a person could theoretically inject harmful code that could mess up your form/site/application.
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Most anything you would use to uniquely indentify a user is most likley easily spoofed...a94060 wrote:could you possibly check the URl that the data is coming from? use like a strpos or something?
You have no choice but to sanitize data...
You could possibly make sure that data was sent by a unique person as opposed to abot of some sort by using CAPTCHA, which would require human intervention...
But that POST could have come from anywhere, including there own web site, etc...allowing them to spoof all the headers they want...