2

There are already some posts about disallowed key characters but this one has different question. I want to know how risky is if I leave $config['permitted_uri_chars'] empty. What can happen? The reason? I need to have enable_query_strings FALSE and I use Arabic words in

URL:

www.mydomain.com/%D8%A7%D9%84%D8%B3%D9%84%D8%A7%D8%B7%D8%A9-%D8%A7%D9%84%D9%8A%D9%88%D9%86%D8%A7%D9%86%D9%8A`

I never rely on value from URL, I always do some cleaning before. But I am not sure how Codeigniter handles routes and how it includes files. Do they rely on this single permitted_uri_chars rule?

tereško
  • 58,060
  • 25
  • 98
  • 150
user1324762
  • 765
  • 4
  • 7
  • 24

1 Answers1

2

If you want to include only Arabic characters you can include unicode ranges in premitted_uri_chars regexp. Using this wikipedia site we can try to construct regexp:

a-z 0-9~%.:_\- \x0600-\x06FF

Unfortunately for our case CodeIgniter doesn't use the u modifier (used for unicode) in preg_match. So in order for this to work you would need to modify source code file system/core/URI.php, line 257 line, and change it to:

if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|iu", $str))

In the above code I've added only the u modifier to preg_match. Alternatively you can extend URI class as desribed in documentation, which is a better choice.

(I didn't test this)

To answer the question why it is bad to allow all characters: I can only think of SQL Injection problems or other kinds of injections.

Edit: for example if you use url index.php/main/get_pdf?filename=awesome.pdf to download pdf files from ./pdf/awesome.pdf if you don't treat (i.e. validate) your input correctly malicious user could do something like this: index.php/main/get_pdf?filename=../secure_files/nuclear_launch_codes.pdf ;).

Edit2: Well, above example is a not an example of bad use of permitted_uri_chars because AFAIK CodeIgniter allows this kind of url variables, so you need to validate this stuff your self. I'll check all of this stuff when I get home.

Edit3: I fixed regexp, but it seems that this is not the way to enable Arabic characters so I crossed out this part of the answer.

I played with CodeIgniter a little. I don't know if this stuff will work on other system. It works on my Windows XP, PHP 5.3. This is what I found:

  • In PHP you can use UTF-8 characters as function and class identifiers, but it is not officialy supported (see this for further info).
  • In CodeIgniter the controller/method part of the URL is url encoded (e.g. ـج‎‎ is converted to %D9%80%D8%AC%E2%80%8E). If you want to use Arabic in controller or method names you have two options:

    1. In application/config/routes.php add url encoded route pointing to real route which could contain Arabic characters (as mentioned above, you can use UTF-8 characters in PHP identifiers). E.g.: $route['welcome/%D8%A3'] = 'welcome/أ'; will enable user to go to example.com/index.php/welcome/أ which will call أ method (defined as function أ() { ... }) in welcome controller. Of course you can map arabic url encoded urls to normal ASCII names.
    2. Extend system/core/Router.php class so that fetch_method and fetch_class return url decoded names. I don't know what security implications are when you do this. Probably it is better to validate if input characters are indeed Arabic (i.e. you can check char ranges supplied here). Example of modified fetch_class:

      function fetch_class()
      {
          return urldecode($this->class);
      }
      
  • If you need to use Arabic characters in parameters of controller methods you just need to urldecode these parameters. E.g.:

    class Welcome extends CI_Controller
    {
        public function index($param)
        {
            $this->output->set_content_type("text/plain; charset=utf-8");
            echo urldecode($param);
        }
    }
    
  • If you need to use these characters in query string it just works. E.g.

    class Welcome extends CI_Controller
    {
        public function index()
        {
            $this->output->set_content_type("text/plain; charset=utf-8");
            echo $this->input->get('arabic');
        }
    }
    

    Going to example.com/index.php/welcome/index?arabic=ابتثجحخدذرزسشصضطظعغفقكلمنهوي will print out ابتثجحخدذرزسشصضطظعغفقكلمنهوي.

Edit4: If you have $config['uri_protocol'] = 'PATH_INFO' then:

  1. In config set $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-\x{0600}-\x{06FF}';
  2. Extend URI class in system/core/URI.php so that in method _filter_uri line with preg_match is:

    if ( ! preg_match("|^[".str_replace(array('\\-', '\-', '\{', '\}', '\\\\x'), array('-', '-', '{', '}', '\x'), preg_quote($this->config->item('permitted_uri_chars')))."]+$|ui", $str))
    
Community
  • 1
  • 1
Jan Święcki
  • 1,611
  • 2
  • 16
  • 28
  • Thank you, but it still doesn't work. I get php warning: "Message: preg_match() [function.preg-match]: Compilation failed: range out of order in character class at offset 32". – user1324762 Mar 20 '13 at 12:21
  • 1
    @user1324762 I'll debug this when I get home in the evening – Jan Święcki Mar 20 '13 at 12:46
  • @user1324762 I reread your question and I'm confused. Do you want to use arabic chars as controller or method names? I've managed to send arabic characters via `$_GET` (e.g. `www.example.com/index.php/welcome/index?arabic=ابتثجحخدذرزسشصضطظعغفقكلمنهوي`) on CodeIgniter 2.1.3 on default settings. Do you have problem with sending via `$_GET` or you want to use arabic in controller/method names? – Jan Święcki Mar 20 '13 at 20:02
  • PS I've managed to use arabic chars in controller / method names without changing `permitted_uri_chars` with little hacking. Let me know if this is what you want and I'll edit my answer. Edit: Which PHP version are you using? – Jan Święcki Mar 20 '13 at 20:20
  • I use php v 5.3.13. I want to pass it as parameter. I modified htaccess RewriteRule ^([^/.]+)$ /index.php/posts/show/$1 [L]. So for better illustration index.php/posts/show/ابتثجحخدذرزسشصضطظعغفقكلمنهوي – user1324762 Mar 20 '13 at 20:43
  • And you get `The URI you submitted has disallowed characters` after using this kind of url? – Jan Święcki Mar 20 '13 at 21:17
  • I could use this URL without an error. I `urldecode`d parameter and I got arabic. – Jan Święcki Mar 20 '13 at 23:38
  • @user1324762 I've edited my answer. Check it out and let me know if it works. – Jan Święcki Mar 21 '13 at 19:39
  • Tnx again for your help but in my case index.php/posts/show/ابتثجحخدذرزسشصضطظعغفقكلمنهوي throws `The URI you submitted has disallowed characters` if I have `enable_query_strings` **FALSE**. I think that I will just leave permitted_uri_chars and validate it only when needed inside my methods. – user1324762 Mar 21 '13 at 19:46
  • @user1324762 I have `enable_query_strings` set to `FALSE` which is default value. Do you have default `permitted_uri_chars`? There should be percent sign `%` in there, i.e. I have `$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';`. – Jan Święcki Mar 21 '13 at 19:53
  • The same. Probably it is because of `$config['uri_protocol'] = 'PATH_INFO'` – user1324762 Mar 21 '13 at 20:24
  • 1
    @user1324762 Indeed. I managed to get it working on `PATH_INFO`. It looks like that the regexp was valid. 1. Set `$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-\x{0600}-\x{06FF}';`. 2. Again we need to change the line with `preg_match` in `system/core/URI.php` in `_filter_uri` method. Try putting this code there: `if ( ! preg_match("|^[".str_replace(array('\\-', '\-', '\{', '\}', '\\\\x'), array('-', '-', '{', '}', '\x'), preg_quote($this->config->item('permitted_uri_chars')))."]+$|ui", $str))` (`preg_quote` was escaping `\x`, `{` and `}`). – Jan Święcki Mar 21 '13 at 21:42
  • I'm very glad it works for you :). I've edited my answer (Edit4) so it includes `PATH_INFO` option. – Jan Święcki Mar 22 '13 at 20:30