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