Receiving "Disallowed Key Characters" error in CodeIgniter - php

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.

Related

PHP regex not working, despite successfully matching in regex101

I'm having the weirdest issue. I've tried referencing other similar answers here, but none seem to fix my issue.
I have the following regex in PHP
/if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+local\s+arch_text\s+=\s+cfg.messages\['archived'\];(?:(?:\n|.)*?if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+Archived = sepc \.\.)?/im
It's a messy regex I know, it's supposed to parse code from a module of various versions from different location. It works perfectly in regex101, but preg_match returns false, indicating an error occured. The regex you see is pulled straight from a var_dump. Also pulled from the var_dump is the string being tested. I have included the excerpt that is supposed to match it below.
if is_set(ArchiveURL) then
if not is_set(ArchiveDate) then
ArchiveDate = seterror('archive_missing_date');
end
if "no" == DeadURL then
local arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( ```
In the full block of text it takes 81,095 steps to match.
Could it have something to do with that?
Getting a read from preg_last_error(), it returned 6, which maps to the constant PREG_JIT_STACKLIMIT_ERROR.
PHP 7 uses a JIT compiler for preg_match with a small stack size limit. Disabling it allows preg_match to do its job.
This can be done in the php.ini file, or on the fly in the script by using ini_set( 'pcre.jit', false );

Using PHP, Why can I not use $_GET to get a value from a URL if there is a _ in the URL?

I have this in my URL;
?utm_source=John%27s%20Source
I want to get the value using this;
echo rawurlencode(stripslashes($_GET['utm_source']));
That does not return anything. However, if I get rid of the _ on 'utmsource' in both the URL and the _GET, it will return this;
John%27s%20Source
Which is exactly what I am looking for. Why can I not do the same with the underscore?
I solved it.
So it turns out that by defualt WPEngine will not let you use '$GET' with something that starts with "utm". I guess this has to do with it being a Google search term and by default it is turned off. I found this thread and contacted WPEngine like the person in the thread, and now it works just fine.
Thanks for the help guys.
Having "utm_" in the URL string breaks the $_GET variable in Wordpress

PHP variables look the same but are not equal (I'm confused)

OK, so I shave my head, but if I had hair I wouldn't need a razor because I'd have torn it all out tonight. It's gone 3am and what looked like a simple solution at 00:30 has become far from it.
Please see the code extract below..
$psusername = substr($list[$count],16);
if ($psusername == $psu_value){
$answer = "YES";
}
else {
$answer = "NO";
}
$psusername holds the value "normann" which is taken from a URL in a text based file (url.db)
$psu_value also holds the value "normann" which is retrieved from a cookie set on the user's computer (or a parameter in the browser address bar - URL).
However, and I'm sure you can guess my problem, the variable $answer contains "NO" from the test above.
All the PHP I know I've picked up from Google searches and you guys here, so I'm no expert, which is perhaps evident.
Maybe this is a schoolboy error, but I cannot figure out what I'm doing wrong. My assumption is that the data types differ. Ultimately, I want to compare the two variables and have a TRUE result when they contain the same information (i.e normann = normann).
So if you very clever fellows can point out why two variables echo what appears to be the same information but are in fact different, it'd be a very useful lesson for me and make my users very happy.
Do they echo the same thing when you do:
echo gettype($psusername) . '\n' . gettype($psu_value);
Since i can't see what data is stored in the array $list (and the index $count), I cannot suggest a full solution to yuor problem.
But i can suggest you to insert this code right before the if statement:
var_dump($psusername);
var_dump($psu_value);
and see why the two variables are not identical.
The var_dump function will output the content stored in the variable and the type (string, integer, array ec..), so you will figure out why the if statement is returning false
Since it looks like you have non-printable characters in your string, you can strip them out before the comparison. This will remove whatever is not printable in your character set:
$psusername = preg_replace("/[[:^print:]]/", "", $psusername);
0D 0A is a new line. The first is the carriage return (CR) character and the second is the new line (NL) character. They are also known as \r and \n.
You can just trim it off using trim().
$psusername = trim($psusername);
Or if it only occurs at the end of the string then rtrim() would do the job:
$psusername = rtrim($psusername);
If you are getting the values from the file using file() then you can pass FILE_IGNORE_NEW_LINES as the second argument, and that will remove the new line:
$contents = file('url.db', FILE_IGNORE_NEW_LINES);
I just want to thank all who responded. I realised after viewing my logfile the outputs in HEX format that it was the carriage return values causing the variables to mismatch and a I mentioned was able to resolve (trim) with the following code..
$psusername = preg_replace("/[^[:alnum:]]/u", '', $psusername);
I also know that the system within which the profiles and usernames are created allow both upper and lower case values to match, so I took the precaution of building that functionality into my code as an added measure of completeness.
And I'm happy to say, the code functions perfectly now.
Once again, thanks for your responses and suggestions.

PHP (md5) empty result

I have a problem with this code sample, the result is a blank page. I checked mcrypt_ecb function in php, and is available. Then why I got only empty result?
$suma='9990';
$idobj='38';
$cislooz='TEST';
$input=$suma.$idobj.$cislooz;
$key='KEY';
$encrypted_text = mcrypt_ecb(MCRYPT_3DES, $key, substr(sha1($input),0,8), MCRYPT_ENCRYPT,substr(sha1($input),0,8));
echo "<b>INPUT: </b>".$input."<br>";
echo "<b>KEY: </b>".$key."<br>";
echo "<b>Hash sha1: </b>".substr(sha1($input),0,8)."<br>";
echo "<b>Hash to 3DES/ECB/NoPadding:</b> ".( $encrypted_text )."<br>";
echo "<b>to HEX:</b> ".StrToUpper(bin2hex($encrypted_text))."<hr>";
?>
You are probably experiencing a problem somewhere. I tested it on PHP 5.3.0 and it output:
INPUT: 999038TEST
KEY: KEY
Hash sha1: c063a3be
Hash to 3DES/ECB/NoPadding: K\Aj¥íµÉ
to HEX: 4B5C416AA5EDB5C9
You may have a PHP error triggered but the only way to know that is to set:
error_reporting(E_ALL);
ini_set('display_errors',1);
At the top of your script so that you'll be able to see what the error is.
Another explain is that you started an output buffer with ob_start() and you might be managing it wrong.
Or you could have an exit; or die(); somewhere.
As you can see there might be a lot of "because" for your question.
Edit:
Finally, at last we discovered the real problem. The spaces in his code where converted to the wrong invisible character; that's because it was copied from a PDF.
Here you can see: the first lines works fine and the space correspond to . in the script. The other symbol instead (of the commented green lines) was causing the problem.

What is causing the Disallowed Key Characters error?

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.

Categories