Welcome Guest, Not a member yet? Register   Sign In
Unload some autoloaded helpers for certain URLS
#1

[eluser]lifewithryan[/eluser]
Okay,
I am messing with a few things on a project and we have gloabl XSS filtering turned on. However, there are a couple URLs where this is actually hindering us. (POSTing some XML data via curl). However, using $this->input->post('xml); is doing what it should which is cleansing that data, however...since this is XML data we don't want all the symbols used in the body of the XML to be converted.

Is there anyway to disable the XSS filter for certain functions? I've tried using $this->input->post('xml', false); but that seems to still be escaping everything. I also tried doing an end-around on CI and just use $_POST['xml'] but thats seems to not find the xml variable being sent in my post request.

(The post isn't coming from a form, but from curl in the request-body...think restful web-services).

Any ideas?
#2

[eluser]xwero[/eluser]
[removed] ( i should read posts more thorough)
#3

[eluser]xwero[/eluser]
I just checked the input class and in the constructor it checks if the xss cleaning config is set to true. So when you get the item the $_POST value is already cleaned.

I guess the only way to not xss clean is to add true to all post items that need cleaning. Or you could hack the input class
Code:
function _sanitize_globals()
    {
        // Would kind of be "wrong" to unset any of these GLOBALS
        $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
                            'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN');
        
        // Unset globals for security.
        // This is effectively the same as register_globals = off
        foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global)
        {
            if ( ! is_array($global))
            {
                if ( ! in_array($global, $protected))
                {
                    unset($GLOBALS[$global]);
                }
            }
            else
            {
                foreach ($global as $key => $val)
                {
                    if ( ! in_array($key, $protected))
                    {
                        unset($GLOBALS[$key]);
                    }
                    
                    if (is_array($val))
                    {
                        foreach($val as $k => $v)
                        {
                            if ( ! in_array($k, $protected))
                            {
                                unset($GLOBALS[$k]);
                            }
                        }
                    }
                }    
            }
        }

        // Is $_GET data allowed? If not we'll set the $_GET to an empty array
        if ($this->allow_get_array == FALSE)
        {
            $_GET = array();
        }
        else
        {
            if (is_array($_GET) AND count($_GET) > 0)
            {
                foreach($_GET as $key => $val)
                {
                    $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
                }
            }
        }
        
        // Clean $_POST Data changed
        /*if (is_array($_POST) AND count($_POST) > 0)
        {
            foreach($_POST as $key => $val)
            {                
                $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
            }            
        }*/
    
        // Clean $_COOKIE Data
        if (is_array($_COOKIE) AND count($_COOKIE) > 0)
        {
            foreach($_COOKIE as $key => $val)
            {            
                $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
            }    
        }
        
        log_message('debug', "Global POST and COOKIE data sanitized");
    }

function post($index = '', $xss_clean = NULL)
    {        
        if ( ! isset($_POST[$index]))
        {
            return FALSE;
        }
        
        if ($xss_clean === TRUE || ($this->use_xss_clean === TRUE && $xss_clean !== FALSE)) // changed
        {
            if (is_array($_POST[$index]))
            {
                foreach($_POST[$index] as $key => $val)
                {                    
                    $_POST[$index][$key] = $this->xss_clean($val);
                }
            }
            else
            {
                return $this->xss_clean($_POST[$index]);
            }
        }

        return $_POST[$index];
    }

update : changed $CFG->item('global_xss_filtering') to the class variable $this->use_xss_clean in the post method

update 2 : void

update 3 : changed NULL to FALSE to make it more human Smile prevent xss cleaning despite true config setting;
Code:
$this->input->post('key',FALSE);
#4

[eluser]xwero[/eluser]
It was sunday. Coding is bad then Smile I've added the hack to the wiki: MY_Input.

The code has addition to the post en cookie methods. The possibility to set a default value instead of returning only false if the key isn't present in the post array.

For your problem the code is now
Code:
$this->input->post('key',FALSE,FALSE);

If you don't remove the extra argument of course. If you do don't forget to set the return to FALSE instead of $default.
#5

[eluser]lifewithryan[/eluser]
What I ended up trying...was doing this before I call this->input->post() --
Code:
$this->input->use_xss_clean = 0;
$this->input->post('xml');

However, I've been unable to figure out if that had any effect at all, (short of print_r(this->input) and verifying that xss_clean was indeed set to 0.

The BIG issue I'm having is this:
The following is in my controller:
Code:
function autoPost($key=null) {
   $this->input->use_xss_clean = 0;
   $xml = $this->input->post('xml');
   print "THIS IS THE XML\n" . $xml . "\n";
   $pxml = simplexml_load_string($xml);
   /* MORE STUFF HERE but DIES beforehand */
}

The above code is expecting to find a variable called 'xml' in the request. This request is being built via curl as it is running via a command-line php script that looks like this:
Code:
$rs = "http://myserver/service/autoPost";
$xml = $post->__toXml();
$postargs = "xml=$xml";
//$str = str_replace(" ", " ", $str);
//$str = str_replace(":", ":", $str);
//$str = str_replace(",", ",", $str);
//$str = rawurlencode($str);

$cobj = curl_init($rs);
curl_setopt($cobj, CURLOPT_POST, true);
//curl_setopt($cobj, CURLOPT_HTTPHEADER, array("Content-Type" => "text/xml"));
curl_setopt($cobj, CURLOPT_POSTFIELDS, $postargs);
curl_setopt($cobj, CURLOPT_HEADER, false);
curl_setopt($cobj, CURLOPT_RETURNTRANSFER, true);
$retval = curl_exec($cobj);
curl_close($cobj);
print "$retval\n";

What seems to be happening is that the $postargs = "xml=" isn't getting sent because when I'm printing the $xml post variable to the screen, its blank. Now I remember at one point, I was getting things sent, but somewhere along the line I broke it because SimpleXML was telling me that it couldn't be parsed as XML. I believe at the time as well is was barfing because CI was changing the <?xml blah to <xml blah etc...that's why I was asking about turning off the xss_clean stuff.

Anyway, I've been working on this for days and its kicking my butt all over the place. As mentioned, I can't even get back to the point where the xml=$xml stuff is actually getting passed. *ugh*
#6

[eluser]lifewithryan[/eluser]
Now this is interesting:

If i send the following xml in my curl post:
Code:
&lt;?xml version=\"1.0\"?&gt;<test><stuff>data</stuff></test>

My controller spits the following out:
Code:
&lt;?xml version="1.0"?&gt;<test><stuff>data</stuff></test>
Except that the wrapping "<>" characters on the xml tag are html entities, but the remaining "<>" characters on the other tags are left alone.

Now, I can understand that I'm seeing the html-safe versions of the "<>" characters, but why just those first two? Is it because they're either followed by or preceded by the "?" characters?

How do I tell my code not to do that!?! lol....i can't believe how this is kicking me in the jellies...

Man...this is driving me nuts
#7

[eluser]xwero[/eluser]
try it with the short tags not parsed in CI or in the php ini. I don't know where it's enabled.

I don't think your are going to have any effect setting use_xss_clean to 0 because the input is cleand as soon as the input library kicks in. But if it works it would be a much nicer solution.
#8

[eluser]lifewithryan[/eluser]
Okay, what was causing my issue, (it appears) that is was really puking on my CDATA elements that I was wrapping around some PHP code...$this->title for instance. Once I removed the CDATA stuff, the post variable was making it across and I could pull back some of the data.

The problem however then became that since I was also parsin URLs etc...the SimpleXML then started griping about incorrect formats etc...

I've finally abandoned the XML for now and am using an array of php variables in the post and that seems to work without issue. Its fine for now because I plan on fully locking down this web-service so really our admin geeks will be the only ones using it.

However, this poses a HUGE problem if you ever want to open up some web services and post xml...I suppose that is why it was called "SimpleXMLElement"...

Overall though, it should affect me that much since most of the web-service we plan on publishing will be simple RESTful request where we only passing back data and not looking to parse XML. Perhaps I'll look at a JSON library or something instead and see how that works some other time.




Theme © iAndrew 2016 - Forum software by © MyBB