CodeIgniter is giving me a Disallowed Key Characters error. I've narrowed it down to the name attribute of a form field: name='prod[50-4121.5]' but I'm not sure what to do about it.
- 1,726
- 3
- 17
- 41
- 995
- 2
- 10
- 20
-
Can you post code? Is it from a form? – Tilman Koester Nov 16 '10 at 19:22
-
This also may affect Expression Engine < 2, and may be caused by browser toolbars. Just found this out when a "MindSpark" toolbar (whatever that is) was setting it's own cookies on a user's computer. Moral of the story: Don't install third-party toolbars. – Jared Farrish Aug 24 '12 at 18:19
-
whether 50-4121.5 is a field name – Visakh B Sujathan May 30 '15 at 11:54
21 Answers
The problem is you are using characters not included in the standard Regex. Use this:
!preg_match("/^[a-z0-9\x{4e00}-\x{9fa5}\:\;\.\,\?\!\@\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str)
As per the comments (and personal experience) you should not modify they Input.php file — rather, you should create/use your own MY_Input.php as follows:
<?php
class MY_Input extends CI_Input {
/**
* Clean Keys
*
* This is a helper function. To prevent malicious users
* from trying to exploit keys we make sure that keys are
* only named with alpha-numeric text and a few other items.
*
* Extended to allow:
* - '.' (dot),
* - '[' (open bracket),
* - ']' (close bracket)
*
* @access private
* @param string
* @return string
*/
function _clean_input_keys($str) {
// UPDATE: Now includes comprehensive Regex that can process escaped JSON
if (!preg_match("/^[a-z0-9\:\;\.\,\?\!\@\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str)) {
/**
* Check for Development enviroment - Non-descriptive
* error so show me the string that caused the problem
*/
if (getenv('ENVIRONMENT') && getenv('ENVIRONMENT') == 'DEVELOPMENT') {
var_dump($str);
}
exit('Disallowed Key Characters.');
}
// Clean UTF-8 if supported
if (UTF8_ENABLED === TRUE) {
$str = $this->uni->clean_string($str);
}
return $str;
}
}
// /?/> /* Should never close php file - if you have a space after code, it can mess your life up */
++Chinese Character Support
// NOTE: \x{4e00}-\x{9fa5} = allow chinese characters
// NOTE: 'i' — case insensitive
// NOTE: 'u' — UTF-8 mode
if (!preg_match("/^[a-z0-9\x{4e00}-\x{9fa5}\:\;\.\,\?\!\@\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str) { ... }
// NOTE: When Chinese characters are provided in a URL, they are not 'really' there; the browser/OS
// handles the copy/paste -> unicode conversion, eg:
// 一二三 --> xn--4gqsa60b
// 'punycode' converts these codes according to RFC 3492 and RFC 5891.
// https://github.com/bestiejs/punycode.js --- $ bower install punycode
- 3,747
- 7
- 37
- 52
-
1Upvoting the more elegant solution. Or you can remove the `preg_match` entirely. I'm not aware of any inherent security vulnerabilities that this might open. – Jonah Aug 28 '14 at 18:25
-
-
You should be able to create a `MY_Input.php` file in a Core Folder (or wherever your `My_*` files are - I have modified my Codeigniter Instance for security purposes.) – Tyler Wall Dec 09 '14 at 18:18
-
Ok, so I manage to override the function '_clean_input_keys($str)' placing the file MY_Input.php into application/core/, however I can't go thru when I'm processing the form. @Wallter, the format of my fields are name[number], because I can change de amount of fields dynamically. Do I need to do something else? Thanks! – Lvkz Dec 29 '14 at 15:59
-
Open libraries/Input.php (system/core/Input.php in CI version 2.0+) and locate function _clean_input_keys($str){, The whole block should look like so:
function _clean_input_keys($str)
{
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
exit('Disallowed Key Characters.');
}
return $str;
}
Modify the PCRE sot that it allows the new chars.
Please not that the char thats missing is the .(dot) and you should always escape the .(dot) in Regular Expressions as they will otherwise allow any single char.
/^[a-z0-9:_\/-\.]+$/i
- 101,186
- 37
- 194
- 228
- 56,863
- 21
- 114
- 161
-
-
1The line in the config/config.php file relates to characters permitted in a url. – John Rand Nov 17 '10 at 00:21
-
`permitted_uri_chars` has nothing to do with this, so I've removed that piece from your answer since it was confusing other people. – Wesley Murch Dec 05 '12 at 14:06
-
-
I did what you said now there is Disallowed Key Characters all over my site... need help – Kevin Florenz Daus Mar 18 '13 at 06:47
-
7Remember to create MY_Input class to extend CI_Input class. DON'T hardcode anything there. [Read this](http://ellislab.com/codeigniter/user-guide/general/core_classes.html). – machineaddict Jun 12 '13 at 08:17
-
@machineaddict OK, but _clean_input_keys is a private method, how can I override a private method on my own MY_Input? – rubdottocom Nov 27 '13 at 08:46
-
3@rubdottocom: as I see in CodeIgniter 2.1.3, the method `_clean_input_keys` is not declared as private in `CI_Input` class and therefore you can extend this method in `MY_Input` without any problems. – machineaddict Nov 28 '13 at 10:20
To use CodeIgniter with jQuery Ajax, use "Object" as data instead of Query string as below:
$.ajax({
url: site_url + "ajax/signup",
data: ({'email': email, 'password': password}), //<--- Use Object
type: "post",
success: function(response, textStatus, jqXHR){
$('#sign-up').html(response);
},
error: function(jqXHR, textStatus, errorThrown){
console.log("The following error occured: "+
textStatus, errorThrown);
}
});
- 307
- 4
- 3
-
I've been searching for hours trying to find why my posted data wouldn't return any of the PHP headers. Thank you for this answer. – Matthew Jul 25 '17 at 23:30
function _clean_input_keys($str)
{
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
exit('Disallowed Key Characters.');
}
return $str;
}
Please add .$str to exit('Disallowed Key Characters.'); Like: exit('Disallowed Key Characters. '.$str);
to help you in your search for rogue errors.
- 506
- 1
- 6
- 21
I had the same error after I posted a form of mine. I simply missed the opening quote in one of my input name attributes. I had:
<input name=first_name">
Fixing that got rid of the error.
- 351
- 3
- 3
Step1. Search for function _clean_input_keys on /system/core/Input.php
Step2. Modify this line
exit(‘Disallowed Key Characters.’);
to
exit(‘Disallowed Key Characters.’ . $str);
Step3. Refresh page to see the characters which generate the error
Step4. If you need to add those characters into the exception list, just add to this line
if ( ! preg_match(“/^[a-z0-9:_/-]+$|/i”, $str))
I add | (pipe) character on the example above
- 541
- 2
- 10
- 28
I got this error when sending data from a rich text editor where I had included an ampersand. Replacing the ampersand with %26 - the URL encoding of ampersand - solved the problem. I also found that a jQuery ajax request configured like this magically solves the problem:
request = $.ajax({
"url": url,
type: "PUT",
dataType: "json",
data: json
});
where the object json is, surprise, surprise, a JSON object containing a property with a value that contains an ampersand.
- 2,838
- 4
- 31
- 48
-
Thank you!, i was working with curl and adding `curl_setopt($ch, CURLOPT_HTTPHEADER,array("Content-Type: application/json"));` , which is the equivalent of `dataType:"json"`, solve my problem. – bistoco Oct 26 '16 at 01:21
Open libraries/Input.php (system/core/Input.php in CI version 2.0+) and locate function _clean_input_keys($str){,
Modify if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) to if ( ! preg_match("/^[a-z0-9:_\-|]+$/i", $str))
- 1,552
- 3
- 18
- 40
I had the same problem thanks to french specials characters. Here is my class in case anybody needs it. It has to be saved here : /application/core/MY_Input.php
(also this extension will report witch character is not allowed in the future)
class MY_Input extends CI_Input {
function __construct()
{
parent::__construct();
}
/**
* Clean Keys
*
* This is a helper function. To prevent malicious users
* from trying to exploit keys we make sure that keys are
* only named with alpha-numeric text and a few other items.
*
* @access private
* @param string
* @return string
*/
function _clean_input_keys($str)
{
if ( ! preg_match("/^[a-z0-9:_\/-àâçéèêëîôùû]+$/i", $str))
{
exit('Disallowed Key Characters : '.$str);
}
// Clean UTF-8 if supported
if (UTF8_ENABLED === TRUE)
{
$str = $this->uni->clean_string($str);
}
return $str;
}
}
Read The Friendly Manual about core classes extension : http://ellislab.com/codeigniter/user-guide/general/core_classes.html
- 1,694
- 2
- 18
- 18
I had the same error after I posted a form of mine. they have a space in to my input name attributes. input name=' first_name'
Fixing that got rid of the error.
- 21
- 1
Php will evaluate what you wrote between the [] brackets.
$foo = array('eins', 'zwei', 'apples', 'oranges');
var_dump($foo[3-1]);
Will produce string(6) "apples", because it returns $foo[2].
If you want that as a string, put inverted commas around it.
- 1,739
- 2
- 11
- 25
-
Codeigniter filters the URI for a specific traditional set of characters, you have to 'permit' now chars if you want them to be passed, and the the `QUERY_STRING` is not the same as `GPC` so there parsed differently. – RobertPitt Nov 16 '10 at 20:19
-
-
1when you go `http://site.com/controller/[a][b]` it strikes an error because CI found a `[` and `]` which are not permitted by default :) – RobertPitt Nov 16 '10 at 20:26
-
@RobertPitt Oh, I get your comment, just didn't think the question had anything to do with URIs ;) But then again the question was a bit short anyways. – Tilman Koester Nov 16 '10 at 21:00
In my case, i was serializing an input form using jquery serialize() and then urlencoding it using encodeURIComponent().
var datas = form.serialize();
encodeURIComponent(datas);
$.getJSON(url,datas,function(){});
and codeigniter was giving the disallowed character error.
i figured the issue here was, jquery serialize gives an encoded output and i was again encoding it with the encodeURIcomponent which was unnecessary, and when codeingiter decoded it it was not getting the actual string as some part was encoded twice. i will explain it with an example.
string: quantity[]=1&option=sell
urlencoded while serializing: quantity%5B%5D%3D1%26option%3Dsell
again urlencoded with encodedURICompontent(): quantity%255B%255D%253D1%2526option%253Dsell
---at codeigntier
urldecode: quantity%5B%5D=1&option=sell
which has disallowed charecters as per the input class regex.
note: this is not an answer to this question, but would help to check if one is encountering this error...thanks.
- 1,250
- 12
- 16
In Ubuntu, you can solve the problem by clearing the cookies of your browser. I had the same problem and solved it this way.
- 7,639
- 2
- 28
- 27
-
if one is using http://localhost, and switching between several frameworks/languages locally, then this should be the first thing to check. – Kinjal Dixit May 26 '14 at 04:52
Took a while to figure this one out. Seems most of us missed the obvious error…the last “-” is not escaped.
Adding the . and | as I’ve seen other suggest may work for you, but the regex was supposed to be:
if ( ! preg_match("/^[a-z0-9:_\/\-\.|]+$/i", $str))
- 39
- 4
i saw this error when i was trying to send a form, and in one of the fields' names, i let the word "endereço".
echo form_input(array('class' => 'form-control', 'name' => 'endereco', 'placeholder' => 'Endereço', 'value' => set_value('endereco')));
When i changed 'ç' for 'c', the error was gone.
- 384
- 7
- 16
I had this issue but my problem was that I by mistake added a space before the name of the input like so:
<input type="text" name=" evening_time_phone">
When it shpuld be like this:
<input type="text" name="evening_time_phone">
- 9,741
- 8
- 65
- 103
I have the same problem and I've found it is in domain name of the email address which is somehow changed from . to _ like: name@domain_com instead name@domain.com
- 59,234
- 49
- 233
- 358
- 13
- 5
In my experience, it could be caused by uncompleted syntax, like :
$('#teks').val
instead of
$('#teks').val()
- 12,648
- 10
- 46
- 77
- 31
- 6
The error I referenced was generated in system/libraries/Input.php (about line 215 - look for function _clean_input_keys($str).
The regex there does not allow for the dot character in an index. I changed it so it would.
- 995
- 2
- 10
- 20
Replace the below Code in the _clean_input_keys function
if ( ! preg_match("/^[a-z0-9:_\/-]+$|/i", $str))
{
exit('Disallowed Key Characters.\n');
}
if (UTF8_ENABLED === TRUE)
{
$str = $this->uni->clean_string($str);
}
return $str;
- 1
- 2
In most of the cases when you have a existing software and you are trying to deploy in a new enviroment this kind of error should be caused by the PHP property
short_open_tag
Check if you have enabled in your new enviroment. In other words PHP couldn't read the tags in your code.
- 1
- 2