Jump to content

How to Capture $_POST and $_GET


andz

Recommended Posts

Good day everyone.

 

I ave a ready made script that's vulnerable on xss attack.

 

Is there any way for me to create a function() that will capture the $_GET[] and $_POST[] so that I can perform validation on them like applying strip_tags() or htmlentities() or htmlspecialchars()

 

Thanks everyone.

Link to comment
Share on other sites

is this correct???

 

function strip($values) {

  foreach($values as $key => $val) {

      $values[$key] = strip_tags($values[$key]);

  }

}

 

 

calling the script

 

strip($_POST['name']);

 

 

 

or

 

function strip($_POST) {

  foreach ($_POST as $key => $value) {

      $_POST[$key] = strip_tags($_POST[key]);

  }

}

 

calling the script

 

strip($_POST['name']);

 

 

 

which one is the correct implementation? 1st or 2nd?

Link to comment
Share on other sites

Yes, using a function is a good way to reuse that code for any array of variables.

 

Please don't use $_REQUEST. It suffers from some of the same problems that register_globals caused. A hacker can sit there just typing values on the end of the url to set $_REQUEST variables that you are expecting to originate from $_POST or $_COOKIE variables. If you expect a $_POST variable, use $_POST, if you expect a $_GET variable, use $_GET, if you expect a $_COOKIE variable, use $_COOKIE. All of the lazy-way short cuts put into php have been time wasters or insecure.

Link to comment
Share on other sites

I didn't think it would matter for the function he is doing, as he isn't specifically looking for any variables and if they did type things on the end of the url the $_GET in this function would process them anyway. But yes relying on it to get information from $_POST etc could be open to hackers.

 

Also wouldn't passing $_POST to a function be pointless as it's a global var?

Link to comment
Share on other sites

Yeah, it would because it's superglobal :D

 

And yeah, I personally wouldn't do something like this. It's almost as bad as magic quotes. I'd just run the necessary functions on each variable as and when you need it.

Link to comment
Share on other sites

says why here... http://au2.php.net/manual/en/security.magicquotes.whynot.php

 

I quite like darkfreaks function for making user input safe, with my flags implemented.  :D

<?php
function safe_input($data,$flags="abcdef")
{
    if(strpos($flags,"a") == 0) {
    	$data = strip_tags('allowed tags',$data);
    }
    if(strpos($flags,"b")) {
    	$data = trim($data); //trim whitespace
    }
    if(strpos($flags,"c")) {
    	$data = stripslashes($data); //trim backslashes
    }
    if(strpos($flags,"d")) {
    	$data = htmlspecialchars($data,ENT_NOQUOTES);
    }
    if(strpos($flags,"e")) {
	//escaping XSS in PHP 5//
    	$data = filter_var($data,FILTER_SANITIZE_STRING); //works in php5 
    }
    if(strpos($flags,"f")) {
    	$data = mysql_real_escape_string($data); // escape SQL injection
    }
    return $data;
}

// use
safe_input($_POST['text'],"abce");

by doing it this way you can make input safe and use the correct functions just by specifying the flags for whatever functions you wish to use on the data.

Link to comment
Share on other sites

I think it's a stupid function. Not very well designed. I'd do something this if you needed chain filtering:

 

abstract class FilterAbstract
{
private $_options = array();
protected $_value;
private $_rawValue;
private $_filtered = false;

public function __construct($value = null, array $options = array())
{
	$this->setValue($value)->setOptions($options);
}

public function setValue($value)
{
	$this->_value = $this->_rawValue = $value;
	$this->_filtered = false;
	return $this;
}

public function getValue()
{
	if (!$this->_filtered) {
		$this->_filter();
		$this->_filtered = true;
	}

	return $this->_value;
}

public function getRawValue()
{
	return $this->_rawValue;
}

public function setOption($option, $value)
{
	$this->_options[$option] = $value;
	return $this;
}

public function getOption($option, $default = false)
{
	if (!isset($this->_options[$option])) {
		return $default;
	}

	return $this->_options[$option];
}

public function setOptions(array $options)
{
	foreach ($options as $option => $value) {
		$this->setOption($option, $value);
	}
	return $this;
}

public function __toString()
{
	return $this->getValue();
}

public function filter($value)
{
	return $this->setValue($value)->getValue();
}

abstract protected function _filter();
}

class FilterXss extends FilterAbstract
{
protected function _filter()
{
	$this->_value = htmlentities(
		$this->getRawValue(),
		ENT_QUOTES,
		$this->getOption('charset', 'ISO-8859-1')
	);
}
}

class FilterTrim extends FilterAbstract
{
protected function _filter()
{
	$this->_value = trim(
		$this->getRawValue(),
		$this->getOption('charlist', " \t\n\r\0\x0B")
	);
}
}

class FilterChain extends FilterAbstract
{
private $_filters = array();

public function addFilter(FilterAbstract $filter)
{
	$this->_filters[] = $filter;
	return $this;
}

public function addFilters(array $filters)
{
	foreach ($filters as $filter) {
		$this->addFilter($filter);
	}
	return $this;
}

protected function _filter()
{
	$value = $this->getRawValue();
	foreach ($this->_filters as $filter) {
		$value = $filter->filter($value);
	}

	$this->_value = $value;
}
}

$xssFilter = new FilterXss();
echo $xssFilter->filter('<b>Hello</b>') . PHP_EOL . PHP_EOL;

$trimFilter = new FilterTrim();
echo $trimFilter->filter('   test    ') . PHP_EOL . PHP_EOL;

$chainFilter = new FilterChain();
$chainFilter->addFilters(array($xssFilter, $trimFilter));
echo $chainFilter->filter('  <b>hello</b> ');

 

Output:

<b>Hello</b>

test

<b>hello</b>

Link to comment
Share on other sites

Wtf, surely that's a bit excessive? :P

 

I just use something like this:

static function post($str)
{
global $mysql;
if(!isset($mysql))
{
	$mysql = new connection;
	$mysql->connect();
}
if(is_array($str))
{
	foreach($str as $key => $value)
	{
		$str[$key] = $mysql->escape_string(trim($str[$key]));
	}
}
else
{
	$str = $mysql->escape_string(self::prepare($str));
}
return $str;
}
static function prepare($str)
{
return trim($str);
}

Link to comment
Share on other sites

Wtf, surely that's a bit excessive? :P

 

Except it's modular, configurable and can be changed at run time. Yours is implementation specific and is determined at compile time.

 

Imagine you have a class called Form, which has an aggregate of FormElements. You might have this:

 

$form = new Form();

$form->addDefaultFilters(array('Trim'));

$form->addElements(array(
new FormElementText('username', array(
	'label' => 'Username:',
	'validators' => array(
		'length' => array(
			'type' => 'Length',
			'options' => array(
				'max' => 20,
				'min' => 3,
			),
		),
	),
)),
new FormElementText('birthday', array(
	'label' => 'Birthday',
	'filters' => array(
		'date' => array('type' => 'NormalizeDate')
	)
	'validators' => array(
		'date' => array('type' => 'Date'),
	),
)),
new FormElementText('email', array(
	'label' => 'Email',
	'validators' => array(
		'length' => array('type' => 'Email'),
	),
)),
));

 

I introduced validators here as well, and those would be written sort of like the filters. Our Form can make form HTML markup, and it can validate and filter the submitted content.

 

We would have abstract factories for both validators and filters, so calling e.g. FilterAbstract::factory('NormalizeDate') could give us an instance of a class called FilterNormalizeDate, which will convert various types of date input to ISO 8601 format. This would allow our users to enter e.g. "10th of April, 2009" or "April 10, 2009" without being told that they entered an invalid format.

 

Each FormElement would proxy to the set validators, and a Form would be a chain validator for all its FormElements. Same thing for filtering. So we might do $form->setInput($_POST)->isValid(). This would iterate over all the aggregate elements setting the values, filtering it and checking if all the input is valid.

 

Our FormElements and Form might have a method called render(), which would render it to HTML. Calling this on an object would automatically add the FilterXss filter (if it doesn't already exist in the chain) on the elements.

 

You might have a class called DomainObject that represents, well, a domain object. This will map to a table row in a database. This class might have a method like this public function saveFromForm(Form $form). Some DBMS have native support parametrized queries, but others might not. Those database components that do not could ship with a filter for safe insertion, and add that filter to an element's chain when using the saveFromForm() method. Because of the way the filters were designed, a filter will only be run once even if you get the value multiple times, so existing filters wouldn't be applied multiple times.

 

You now have a highly modular implementation for handling user input through a form in a secure manner. Of course because we decided to make a modular implementation, the filters and validators could be used in any arbitrary scenario where it is necessary to validate and/or filter some sort of value.

 

is there any way to setup this filtering of GET and POST using .htaccess or php.ini directly so it will filter any incoming POST or GET

 

Have you read any post in this thread. Filtering like that is not the way to go. Filter values as you need to.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.