Skip to content

Instantly share code, notes, and snippets.

@zeelot
Created August 29, 2012 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeelot/3514945 to your computer and use it in GitHub Desktop.
Save zeelot/3514945 to your computer and use it in GitHub Desktop.
Fix for security issue in Kohana 3.0.8 - 3.2.1
<?php defined('SYSPATH') or die('No direct script access.');
// Just use this file in application/classes/url.php for a fix until 3.2.2 is out
class URL extends Kohana_URL {
/**
* Fetches an absolute site URL based on a URI segment.
*
* echo URL::site('foo/bar');
*
* @param string $uri Site URI to convert
* @param mixed $protocol Protocol string or [Request] class to use protocol from
* @param boolean $index Include the index_page in the URL
* @return string
* @uses URL::base
*/
public static function site($uri = '', $protocol = NULL, $index = TRUE)
{
// Chop off possible scheme, host, port, user and pass parts
$path = preg_replace('~^[-a-z0-9+.]++://[^/]++/?~', '', trim($uri, '/'));
if ( ! UTF8::is_ascii($path))
{
// Encode all non-ASCII characters, as per RFC 1738
$path = preg_replace_callback('~([^/]+)~', 'URL::_rawurlencode_callback', $path);
}
// Concat the URL
return URL::base($protocol, $index).$path;
}
/**
* Callback used for encoding all non-ASCII characters, as per RFC 1738
* Used by URL::site()
*
* @param array $matches Array of matches from preg_replace_callback()
* @return string Encoded string
*/
protected static function _rawurlencode_callback($matches)
{
return rawurlencode($matches[0]);
}
}
@bobeagan
Copy link

The issue starts in 3.0.9, not 3.0.8 I believe. Also, for 3.0.x that is affected I think the site function should look like this:

    /**
     * Fetches an absolute site URL based on a URI segment.
     *
     *     echo URL::site('foo/bar');
     *
     * @param   string  site URI to convert
     * @param   mixed   protocol string or boolean, add protocol and domain?
     * @return  string
     * @uses    URL::base
     */
    public static function site($uri = '', $protocol = FALSE)
    {
        // Chop off possible scheme, host, port, user and pass parts
        $path = preg_replace('~^[-a-z0-9+.]++://[^/]++/?~', '', trim($uri, '/'));

        if ( ! UTF8::is_ascii($path))
        {
            // Encode all non-ASCII characters, as per RFC 1738
            $path = preg_replace('~([^/]+)~e', 'rawurlencode("$1")', $path);
        }

        // Concat the URL
        return URL::base(TRUE, $protocol).$path;
    }

@bobeagan
Copy link

So I apparently can't comment on gists but I pasted the function that was the original and not the modified. Just need to swap out the preg_replace line with the ~e for the preg_replace_callback line from above.

Change this:

$path = preg_replace('~([^/]+)~e', 'rawurlencode("$1")', $path);

To this:

$path = preg_replace_callback('~([^/]+)~', 'URL::_rawurlencode_callback', $path);

@daGrevis
Copy link

How is this a security issue? Can you please provide some real life example when something can go wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment