is it possible to foreach $this->input->post(); in codeigniter? - php

I am writing a library for CI and I have a method I call to gather all possible post variables. I would somehow like to leverage the xss and security classes built into the codeigniter input class.
Is that possible?
Here is the working method without any use of the CI input class.
private function parse_options()
{
foreach($_POST as $key => $val)
{
$options[$key] = $val;
}
return $options;
}

Why not then:
private function parse_options()
{
foreach($_POST as $key => $val)
{
$options[$key] = $this->input->post($key);
}
return $options;
}

Some 8 years later..
The documentation (https://www.codeigniter.com/user_guide/libraries/input.html) says this:
$this->input->post(NULL, TRUE); // returns all POST items with XSS filter
$this->input->post(NULL, FALSE); // returns all POST items without XSS filter
The reason for trying to only do it the ci-way and not bypassing ci is to keep things uniform. Likely.

Related

How can you apply xss filters in laravel 4 framework?

How do you think about security in laravel 4 ? I mean how laravel is managing xss attacks ?
In codeigniter you have someting like xss_clean($_GET['yourValue']) to clean user input fom xss code.
How laravel manage those kind of problems ? You get user values using Input::get('yourValue') but how do you apply an xss filter to it ? It comes with this functionality out of the box or what ?
You can use App::before event to filter all of your inputs like this
App::before(function($request)
{
Input::merge(array_strip_tags(Input::all()));
}
The array_strip_tags function is given below, I've put it in a helper file to call it directly, you may use it as a helper function or as a library but it's easy to use it as a helper function, just create a helper file inside app/start/ folder and give it a name, for example custom_helper.php and include it inside global.php file like this
require '/custom_helpers.php';
Function array_strip_tags
function array_strip_tags($array)
{
$result = array();
foreach ($array as $key => $value) {
$key = strip_tags($key);
if (is_array($value)) {
$result[$key] = array_strip_tags($value);
}
else {
$result[$key] = strip_tags($value);
}
}
return $result;
}
This is copied from an working project of mine.
In laravel templates, any data that comes form user input should be enclosed in three curly braces to sanitize it:
<h1>{{{ $input }}}</h1>
There's no native xss clean function in Laravel, but if you're desparate for one there is a port of the codeigniter security library available here:
http://packalyst.com/packages/package/gvlatko/laravel-xss
Here is how I solved this. Inspired on #the-alpha's solution. I'm using Laravel 4.2.
app/start/global.php:
function array_strip_tags($array)
{
$result = array();
foreach ($array as $key => $value) {
$key = strip_tags($key);
if (is_array($value)) {
$result[$key] = array_strip_tags($value);
}
else {
$result[$key] = strip_tags($value);
}
}
return $result;
}
app/filters.php:
Route::filter('strip_tags', function()
{
Input::merge(array_strip_tags(Input::all()));
});
app/routes.php:
Route::group(array('before' => 'strip_tags'), function(){
// all routes under this route group will get all their inputs passed through the strip_tags php's function
Route::any('/', ['as' => 'home', 'uses' => 'PageController#anyHome']);
Route::any('/some-page', ['as' => 'some-page', 'uses' => 'PageController#anySomePage']);
}
Create a new Helper file and put these two methods in you helper.
public static function globalXssClean()
{
// Recursive cleaning for array [] inputs, not just strings.
$sanitized = static::arrayStripTags(Input::get());
Input::merge($sanitized);
}
public static function arrayStripTags($array)
{
$result = array();
foreach ($array as $key => $value) {
// Don't allow tags on key either, maybe useful for dynamic forms.
$key = strip_tags($key);
// If the value is an array, we will just recurse back into the
// function to keep stripping the tags out of the array,
// otherwise we will set the stripped value.
if (is_array($value)) {
$result[$key] = static::arrayStripTags($value);
} else {
// I am using strip_tags(), you may use htmlentities(),
// also I am doing trim() here, you may remove it, if you wish.
$result[$key] = trim(strip_tags($value));
}
}
return $result;
}
Then put this code in the beginning of your before filter (in Laravel 4 it should be in app/filters.php).
App::before(function($request)
{
Helper::globalXssClean();
});
I believe Laravel doesn't, unfortunately, have a built-in XSS Filter. However, there's a package you can try laravel-xss and it's easy to use, you just need to do something like: $user->about = Xss::clean(Input::get('about'); and you're set to go!
There is also another package for XSS filter for laravel which can be downloaded here
Usage Example:
Simple form code snippet
{{Form::open(['route' => 'posts.store'])}}
{{Form::text('title')}}
{{Form::textarea('body')}}
{{Form::submit('Post')}}
{{Form::close()}}
Filter package usage
$rules = ['title' => 'required|min:13', 'body' => 'required|min:150'];
$validator = Validator(Input::all(), $rules);
if($validator->passes()){
$xss = new XSS;
$xss->clean(Input::all());
$input = $xss->get();
$post = new Post;
$post->title = $input->title;
$post->body = $input->body;
// to test the results you can dd($input); & happy coding everyone!
}
I examined the Laravel's protection {{{...}}} against xss attack. It just uses the htmlentities() function in the way like this: htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false); This protects you against xss only if you use it properly means dont use it in certain HTML tags because it will result in XSS attack possibility. For example:
$a = htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false);
echo 'link';
In this case, your code is vulnerable to xss.

How to addslashes automatically using Codeigniter?

I want to apply addslashes() to all the post elements got through
$this->input->post('my_var');
How can I do that ? Is there any feature like filters under wordpress for this ?
I think you want something global. My idea is to edit the global post function in the codeigniter to use addslashes on everything. You can find that function in:
/yourfolder/system/core/Input.php
You can escape it by setting it global.
function post($index = NULL, $xss_clean = FALSE)
{
// Check if a field has been provided
if ($index === NULL AND ! empty($_POST))
{
$post = array();
// Loop through the full _POST array and return it
foreach (array_keys($_POST) as $key)
{
$post[$key] = addslashes($this->_fetch_from_array($_POST, $key, $xss_clean));
}
return $post;
}
return addslashes($this->_fetch_from_array($_POST, $index, $xss_clean));
}
Although I don't really find it as good solution to modify the global functions this should do the trick in your case.
Edit: I see that input->post already does that and you would not need to add that function additionally.

filter get and post values

I call my main page framework_ui.php in it I require auth.php where I have a filter function.
function filter($data)
{
// normalize $data because of get_magic_quotes_gpc
$dataNeedsStripSlashes = get_magic_quotes_gpc();
if ($dataNeedsStripSlashes) {
$data = stripslashes($data);
}
// normalize $data because of whitespace on beginning and end
$data = trim($data);
// strip tags
$data = strip_tags($data);
// replace characters with their HTML entitites
$data = htmlentities($data);
// mysql escape string
$data = mysql_real_escape_string($data);
return $data;
}
and on every page with get and post variables I do a: (and call my framework.php)
// filter GET values
foreach ($_GET as $key => $value) {
$get[$key] = filter($value);
}
// filter post
foreach ($_POST as $key => $value) {
$post[$key] = filter($value);
}
Will the function still operate properly if I make the above a function and call that instead on every page?
function filter_all() {
// filter GET values
foreach ($_GET as $key => $value) {
$get[$key] = filter($value);
}
// filter post
foreach ($_POST as $key => $value) {
$post[$key] = filter($value);
}
}
I understand this is not the most secure way, however I was wondering if this sort of thing was possible and wouldn't negatively effect my code.
Your filter_all() function returns nothing and it does not modify the $_GET and $_POST globals so after your function finishes to run those original variables your foreach looping through will be effectively the same. You should either manipulate $_GET/$_POST directly or global $get/$post if you plan on using them or return some combination of the two. Other than that there's nothing necessarily negative about what your planning to do.
If you are going to be doing this every time might as well not make a function and just include a file (like your framework_ui.php) which just does the loopage and filters the variables.
zerkms is correct though your filter function is not ideal in that it is not secure and in fact that mysql_real_escape_string will cause issues if you plan on re-displaying user submitted info back (among many other things).
To quote the OWASP ESAPI project page:
Don't write your own security controls! Reinventing the wheel when it comes to developing security controls for every web application or web service leads to wasted time and massive security holes. The OWASP Enterprise Security API (ESAPI) Toolkits help software developers guard against security‐related design and implementation flaws. http://code.google.com/p/owasp-esapi-php/
You just have to make some tweaks to ensure the 'filtered' values are available to the rest of your code. There are a couple of ways to do it, marking them as global or returning them; probly the second option is generally considered cleaner. Here's an example:
function filter_all() {
$get = array();
$post = array();
// filter GET values
foreach ($_GET as $key => $value) {
$get[$key] = filter($value);
}
// filter post
foreach ($_POST as $key => $value) {
$post[$key] = filter($value);
}
return array(
'get' => $get,
'post' => $post);
}
$aFilteredInput = filter_all();
$get = $aFilteredInput['post'];
$post = $aFilteredInput['post'];

PHP: Class property chaining in variable variables

So, I have a object with structure similar to below, all of which are returned to me as stdClass objects
$person->contact->phone;
$person->contact->email;
$person->contact->address->line_1;
$person->contact->address->line_2;
$person->dob->day;
$person->dob->month;
$person->dob->year;
$album->name;
$album->image->height;
$album->image->width;
$album->artist->name;
$album->artist->id;
etc... (note these examples are not linked together).
Is it possible to use variable variables to call contact->phone as a direct property of $person?
For example:
$property = 'contact->phone';
echo $person->$property;
This will not work as is and throws a E_NOTICE so I am trying to work out an alternative method to achieve this.
Any ideas?
In response to answers relating to proxy methods:
And I would except this object is from a library and am using it to populate a new object with an array map as follows:
array(
'contactPhone' => 'contact->phone',
'contactEmail' => 'contact->email'
);
and then foreaching through the map to populate the new object. I guess I could envole the mapper instead...
If i was you I would create a simple method ->property(); that returns $this->contact->phone
Is it possible to use variable variables to call contact->phone as a direct property of $person?
It's not possible to use expressions as variable variable names.
But you can always cheat:
class xyz {
function __get($name) {
if (strpos($name, "->")) {
foreach (explode("->", $name) as $name) {
$var = isset($var) ? $var->$name : $this->$name;
}
return $var;
}
else return $this->$name;
}
}
try this code
$property = $contact->phone;
echo $person->$property;
I think this is a bad thing to to as it leads to unreadable code is is plain wrong on other levels too, but in general if you need to include variables in the object syntax you should wrap it in braces so that it gets parsed first.
For example:
$property = 'contact->phone';
echo $person->{$property};
The same applies if you need to access an object that has disalowed characters in the name which can happen with SimpleXML objects regularly.
$xml->{a-disallowed-field}
If it is legal it does not mean it is also moral. And this is the main issue with PHP, yes, you can do almost whatever you can think of, but that does not make it right. Take a look at the law of demeter:
Law of Demeter
try this if you really really want to:
json_decode(json_encode($person),true);
you will be able to parse it as an array not an object but it does your job for the getting not for the setting.
EDIT:
class Adapter {
public static function adapt($data,$type) {
$vars = get_class_vars($type);
if(class_exists($type)) {
$adaptedData = new $type();
} else {
print_R($data);
throw new Exception("Class ".$type." does not exist for data ".$data);
}
$vars = array_keys($vars);
foreach($vars as $v) {
if($v) {
if(is_object($data->$v)) {
// I store the $type inside the object
$adaptedData->$v = Adapter::adapt($data->$v,$data->$v->type);
} else {
$adaptedData->$v = $data->$v;
}
}
}
return $adaptedData;
}
}
OOP is much about shielding the object's internals from the outside world. What you try to do here is provide a way to publicize the innards of the phone through the person interface. That's not nice.
If you want a convenient way to get "all" the properties, you may want to write an explicit set of convenience functions for that, maybe wrapped in another class if you like. That way you can evolve the supported utilities without having to touch (and possibly break) the core data structures:
class conv {
static function phone( $person ) {
return $person->contact->phone;
}
}
// imagine getting a Person from db
$person = getpersonfromDB();
print conv::phone( $p );
If ever you need a more specialized function, you add it to the utilities. This is imho the nices solution: separate the convenience from the core to decrease complexity, and increase maintainability/understandability.
Another way is to 'extend' the Person class with conveniences, built around the core class' innards:
class ConvPerson extends Person {
function __construct( $person ) {
Person::__construct( $person->contact, $person->name, ... );
}
function phone() { return $this->contact->phone; }
}
// imagine getting a Person from db
$person = getpersonfromDB();
$p=new ConvPerson( $person );
print $p->phone();
You could use type casting to change the object to an array.
$person = (array) $person;
echo $person['contact']['phone'];
In most cases where you have nested internal objects, it might be a good time to re-evaluate your data structures.
In the example above, person has contact and dob. The contact also contains address. Trying to access the data from the uppermost level is not uncommon when writing complex database applications. However, you might find your the best solution to this is to consolidate data up into the person class instead of trying to essentially "mine" into the internal objects.
As much as I hate saying it, you could do an eval :
foreach ($properties as $property) {
echo eval("return \$person->$property;");
}
Besides making function getPhone(){return $this->contact->phone;} you could make a magic method that would look through internal objects for requested field. Do remember that magic methods are somewhat slow though.
class Person {
private $fields = array();
//...
public function __get($name) {
if (empty($this->fields)) {
$this->fields = get_class_vars(__CLASS__);
}
//Cycle through properties and see if one of them contains requested field:
foreach ($this->fields as $propName => $default) {
if (is_object($this->$propName) && isset($this->$propName->$name)) {
return $this->$propName->$name;
}
}
return NULL;
//Or any other error handling
}
}
I have decided to scrap this whole approach and go with a more long-winded but cleaner and most probably more efficient. I wasn't too keen on this idea in the first place, and the majority has spoken on here to make my mind up for me. Thank for you for your answers.
Edit:
If you are interested:
public function __construct($data)
{
$this->_raw = $data;
}
public function getContactPhone()
{
return $this->contact->phone;
}
public function __get($name)
{
if (isset($this->$name)) {
return $this->$name;
}
if (isset($this->_raw->$name)) {
return $this->_raw->$name;
}
return null;
}
In case you use your object in a struct-like way, you can model a 'path' to the requested node explicitly. You can then 'decorate' your objects with the same retrieval code.
An example of 'retrieval only' decoration code:
function retrieve( $obj, $path ) {
$element=$obj;
foreach( $path as $step ) {
$element=$element[$step];
}
return $element;
}
function decorate( $decos, &$object ) {
foreach( $decos as $name=>$path ) {
$object[$name]=retrieve($object,$path);
}
}
$o=array(
"id"=>array("name"=>"Ben","surname"=>"Taylor"),
"contact"=>array( "phone"=>"0101010" )
);
$decorations=array(
"phone"=>array("contact","phone"),
"name"=>array("id","name")
);
// this is where the action is
decorate( $decorations, &$o);
print $o->name;
print $o->phone;
(find it on codepad)
If you know the two function's names, could you do this? (not tested)
$a = [
'contactPhone' => 'contact->phone',
'contactEmail' => 'contact->email'
];
foreach ($a as $name => $chain) {
$std = new stdClass();
list($f1, $f2) = explode('->', $chain);
echo $std->{$f1}()->{$f2}(); // This works
}
If it's not always two functions, you could hack it more to make it work. Point is, you can call chained functions using variable variables, as long as you use the bracket format.
Simplest and cleanest way I know of.
function getValueByPath($obj,$path) {
return eval('return $obj->'.$path.';');
}
Usage
echo getValueByPath($person,'contact->email');
// Returns the value of that object path

Defining a function with name from a variable?

I need to create a column-system for Wordpress with shortcodes, which is not a problem, but I'm trying to make it with less code.
I have an array with the data needed, I loop through it, create a unique-named function and set it as shortcode-function. The third step is a mystery. How can I create a function from a variable.
Here's an example, how it should be done:
$data[] = "first";
$data[] = "second";
foreach($data as $key => $value) {
function $value($atts,$content) {
return '<div class="'.$value.'">'.$content.'</div>';
}
add_shortcode($value,$value);
}
However, it seems that it's not possible to make it work like that in PHP. Is there any way to make this work, as I would not want to write all the (identical) functions separated. I could make the shortcode something like [col first]text[/col] but the client wants to have different names for every one of them.
you can use the double dollar syntax to use the value of a variable as a variable identifier,
Example:
$variable = "test";
$$variable = "value of test"
echo $test; //or echo $$variable;
I have never tried but you way want to try:
foreach($data as $key => $value)
{
function $$value($atts,$content)
{
}
add_shortcode($value,$value);
}
or a function like create_function
if your using PHP 5.3 or greater then you can do something like so:
$$value = function()
{
}
which should work fine
I'm not sure how WP invocates the functions, but if it uses call_user_func then you might cheat by using an object with virtual methods:
class fake_functions {
function __call($name, $params) {
return '<div class="'.$name.'">'.$params[1].'</div>';
}
}
$obj = new fake_functions();
foreach ($data as $value) {
add_shortcode($value, array($obj,$value));
}

Categories