[BlueOnyx:18527] Re: Password characters

Michael Stauber mstauber at blueonyx.it
Sat Oct 17 15:00:22 -05 2015


Hi Dan,

> I understood that Linux allows all printable characters for a password and
> there is no limitation in length.
> [...]
>
> It appears that BlueOnyx must have some limitations as to what characters
> it allows within a password because a password that contained the "&"
> character was accepted at the command line but caused BlueOnyx to reject
> when trying the web interface.   Does anyone know specifically which
> characters are not permitted in a password and if there is any length
> limitation?

Yeah, I'll explain that one: As you know, the web facing part of the GUI
is a large number of PHP scripts that are (on the new GUI) powered by
the framework CodeIgniter. Like any other PHP code we need to be
*really* careful with any user supplied input. Because it could be
potentially malicious and could trick our code into doing things that we
really don't want to happen.

A lot of bad PHP scripts can be exploited this way, as they don't
sanitize user input - or don't sanitize it enough. For us that means
that we need to filter anything we receive via URL strings such as ...

http(s)://<server>:<port>/base/<module>/<script>?var1=val1&var2=val2

... and naturally also all POST requests that contain form data. To a
lesser degree we also need to sanitize all files on the server that the
GUI opens for reading. Especially if an unprivileged user had the
ability to create or modify the file that the GUI wants to read.

That's our first and foremost line of defense against common web
exploits and Cross Site Scripting attacks.

To give you an example check this code:

http://devel.blueonyx.it/trac/browser/BlueOnyx/5209R/ui/base-vsite.mod/ui/chorizo/web/controllers/vsiteAdd.php

Line 107 has this:

$attributes = GetFormAttributes($i18n, $form_data, $required_keys,
$ignore_attributes, $i18n);

The function GetFormAttributes() sanitizes the POST data.

The actual function is this one:

http://devel.blueonyx.it/trac/browser/BlueOnyx/5209R/platform/alpine.mod/ci/application/helpers/blueonyx_helper.php

GetFormAttributes() starts at line 77 and goes to line 204. When you
look at the code you can see that we use some built in CodeIgniter
functions to trim unwanted characters and do some XSS cleaning. But
additionally we also need to urldecode() various characters as anything
non-ASCII probably got URL-encoded during the form submission.

Generally the function GetFormAttributes() does a stellar job of
providing us with sane and safe input.

But as you might start to grasp: Passwords are a different matter, as
they might contain a lot of special characters. All (except for the
basic ASCII-stuff such as the punctuations ".,;" and math symbols) cause
us some grief. It starts with single or double quotation marks. As they
might be our string terminators. We also don't like ampersand ("&"), as
that is our scalar separator (in array form) or a variable separator in
URL form.

So during a submit of the password "pass."123&;" the actual string
content that gets to the GUI page is this:

pass."123&;

GetFormAttributes() then would turn that into the equivalent of this:

$attributes["newPass"] = "pass."123&;";

You see the problem: The double quotation mark within. When we try to
send that on to CODB for processing, it would result into either an
error. Or worse: It could try to set "pass." as password. And we don't
want partial passwords there.

So we need to deal with passwords in a more comprehensive way than we do
for some other form fields. Which usually do not take such a diverse
range of characters to begin with anyway.

Therefore our UIFC class CCE.php has some extra provisions in it:

See:
http://devel.blueonyx.it/trac/browser/BlueOnyx/5209R/platform/alpine.mod/ci/application/libraries/CCE.php

In the function _escape() from line 941 to line 984 we check if anything
that we send to CODB is "sane". If the "payload" we want to send to CODB
just contains letters and numbers, then line 950-952 pass it right along
without a more thorough check. Because that subset of characters is safe.

But if the "payload" contains anything else, we run a rigorous search
and replace over it in line 955. For passwords we take the XSS cleaned
GetFormAttributes() results and then replace the URL-encoded "stuff"
with "good" equivalents.

For example the "\" (\\) gets double escaped as "\\\\" for CODB. Or
" gets passed on as \" in order to escape it in a form that CODB
won't choke on it. As the password might as well be any UTF-8 character
(including Kanji) we're most certainly not covering all our bases there
as good as we should. But we at least strip anything malicious out,
which is the main part. And CODB also does some converting, which deals
with the UTF-8 side of things such as Kanji or Umlauts.

As far as your "&" in the password goes: This function will see it as
& and turns it into "\&", but apparently that's not what it should
be. Could as well be that CODB wants to see it as "&" instead.

But here is the catch: Like I said earlier the ampersand ("&") is a
special case for us. When we store an array in CODB the ampersand is our
separator.

So an array like this ...

$values = ("1", "2", "3");

... gets stored like this:

$values = "&1&2&3&";

Plus the _escape() function is used to pass on both arrays and strings
to CODB. Lastly, when the payload hits CODB it is transformed yet again.
The end result *should* be exactly what you typed in.

But there are some cases where we might not have managed to cover all
our bases. Or where things simply get lost in translation. I will see if
we can allow the ampersand in passwords. But for now it doesn't seem
like that part is working.

-- 
With best regards

Michael Stauber



More information about the Blueonyx mailing list