Good Morning,
I just wanted to ask if there was ever a decision made that said tainted
mode will go into PHP mainstream.
Currently there are two implementations available:
GRASP by Coresecurity
- pro: byte level tainting which actually works
- negativ: slow
PHP Taint mode by Wietse Venema/IBM
- pro: faster
- negativ: broken design+insecure
It is no secret that I don't like the idea of a taint mode in PHP
because it cannot be made secure and fast at the same time.
Coresecurity's GRASP is the best example for this it uses a secure
design and is therefore slow. On the other hand it
seems some people want the fast implementation of Wietse in the core
which would be bad, because it is based on
wrong assumptions and uses an insecure design that does only give a
false sense of security.
Examples for the wrong assumptions in PHP Taintmode:
- _SERVER['PHP_SELF'] is not safe and allows XSS (and more) in many
applications - Using mysql_real_escape_string() on user input does not make it safe
for SQL. It only makes SQL strings safe.
Example: "SELECT * FROM table WHERE id=".mysql_real_escape_string($id)
is NOT secure but will result in no taint warning - Using
htmlentities()
on usr input does not make it safe for HTML
output. It only makes it safe in some situations.
Example: echo '....<sometag style="some-attribute: ',htmlentities($user_input),'">'. Will allow XSS through the style
attribute without a taint warning
Example2: echo '....<img src="',htmlentities($user_input),'">'. Will
allow XSS through javascript: URL (f.e. in Opera) without a taint warning
Yours,
Stefan Esser
I just wanted to ask if there was ever a decision made that said tainted
mode will go into PHP mainstream.
no, there was no decision yet.
It is no secret that I don't like the idea of a taint mode in PHP
because it cannot be made secure and fast at the same time.
/me too. Although I can't argue about those two implementations because I
haven't looked at them yet, I think we shouldn't include neither of them in
the core. At most we could introduce some hooks in the engine to allow these
kind of extensions to be self-contained and distributed by 3rd parties
without much trouble.
Also I don't know how GRASP works, but it's very difficult (if not
impossible) to provide good analysis..
Nuno
Also I don't know how GRASP works, but it's very difficult (if not
impossible) to provide good analysis..
The difference between GRASP and PHP Taint Mode is that GRASP tracks
taintedness on a byte level
(it really tracks that e.g. byte 4, 7 and 8-20 of a variable are tainted
and the others not) and Venema's
implementation only tracks on a per variable level.
It is therefore obvious that the GRASP way cannot be made fast and that
Venema's implementation will always be faster.
The other difference is that Venema's implementation assumes that
functions exist that make a variable safe for usage in SQL, HTML, ...
When such a function is used the variable is marked as not tainted... In
the previous mail I showed examples why this is not secure.
GRASP on the other hand hooks the SQL/output functions and parses the
SQL query/output and catches tainted bytes in places where they could be
dangerous.
The only problems here are how slow this is and that the parsers need to
be compatible.
Stefan Esser
The other difference is that Venema's implementation assumes that
functions exist that make a variable safe for usage in SQL, HTML, ...
When such a function is used the variable is marked as not tainted... In
the previous mail I showed examples why this is not secure.GRASP on the other hand hooks the SQL/output functions and parses the
SQL query/output and catches tainted bytes in places where they could be
dangerous.
The only problems here are how slow this is and that the parsers need to
be compatible.
BTW, have you already been able to found real-world exploitable bugs with
GRASP?
Nuno
Hi Stefan,
It is therefore obvious that the GRASP way cannot be made fast and
that
Venema's implementation will always be faster.
I wonder how other languages solve this dilemma? Like how does Ruby's
taint model work? What are the experience there? Are there any other
languages that have a taint model?
regards.
Lukas
I wonder how other languages solve this dilemma? Like how does Ruby's
taint model work? What are the experience there? Are there any other
languages that have a taint model?
Perl has. AFAIK it's variable-based.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hello Lukas,
I wonder how other languages solve this dilemma? Like how does Ruby's
taint model work? What are the experience there? Are there any other
languages that have a taint model?
I don't know exactly what they do, but if I am not completely mistaken
the difference is simple.
AFAIK perl has variable level tainting, but does not have implicit
untainting.
That means the developer has to use something like untaint($variable)
whenever he wants to use tainted input.
This means the developer can only use tainted input when he THINKS and
explicitly untaint()s it. He is
responsible for bad decisions like using the wrong escaping function and
telling perl that he untaint()ed the input.
This is different from the implicit untainting through htmlentities()
and mysql_real_escape_string() because there
are obviously cases where these functions are the WRONG functions and
the developer will never realise this
because he was not taught to untaint() himself only when he is sure...
Stefan Esser
This is different from the implicit untainting through
htmlentities()
and mysql_real_escape_string() because there
are obviously cases where these functions are the WRONG functions and
the developer will never realise this
because he was not taught to untaint() himself only when he is sure...
Ok, I guess this is a fundamental difference that we should probably
take note if before we make any decision. Should it be a tool that
one can just enable when one cares or should we require that
developers actually code towards the taint model?
I personally think that library developers could be expected to
actually make explicit untaint() calls and bytecode caches could be
made smart enough to strip these out for the people that do not care
about the added security (which one might not need in production).
However for the final glue that needs to be written to put all the
libraries to work, I think its fairly unrealistic. Then again maybe
the people that do care enough (because they are working for a bank)
would still have the necessary time to add all the relevant untaint()
calls. The rest would probably appreciate a tool that helps them
getting closed to that magical 100% secure mark.
regards,
Lukas
AFAIK perl has variable level tainting, but does not have implicit
untainting.
Applying any regexp to tainted variable produces untainted results in Perl.
--
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi Stefan,
I just wanted to ask if there was ever a decision made that said tainted
mode will go into PHP mainstream.
No decision as such - I believe Wietse is doing his best to find out exactly
how viable it is, no?
it seems some people want the fast implementation of Wietse in the core
which would be bad, because it is based on
wrong assumptions and uses an insecure design that does only give a
false sense of security.
In a preliminary release for feedback purposes you talk about wrong
assumptions? Surely this is the whole point of having a preliminary release
for feedback :)
Examples for the wrong assumptions in PHP Taintmode:
- _SERVER['PHP_SELF'] is not safe and allows XSS (and more) in many
applications- Using mysql_real_escape_string() on user input does not make it safe
for SQL. It only makes SQL strings safe.
Example: "SELECT * FROM table WHERE id=".mysql_real_escape_string($id)
is NOT secure but will result in no taint warning- Using
htmlentities()
on usr input does not make it safe for HTML
output. It only makes it safe in some situations.
Example: echo '....<sometag style="some-attribute: ',htmlentities($user_input),'">'. Will allow XSS through the style
attribute without a taint warning
Example2: echo '....<img src="',htmlentities($user_input),'">'. Will
allow XSS through javascript: URL (f.e. in Opera) without a taint warning
Now, yes. Since these are all things that 'every fule know', isn't it more
than likely that they'll be addressed before taint mode ever sees the light
of day?
I think it's probably worth giving Wietse as much help as you can at this
stage to make it better, since the thing's fast and since you know where to
find the problem areas better than anyone. That said - I don't know if it's
possible to have an extension/hooks approach without losing speed, but if it
is I'd personally vote for taking that approach.
- Steph
Hi Steph,
In a preliminary release for feedback purposes you talk about wrong
assumptions? Surely this is the whole point of having a preliminary
release for feedback :)
yes of course it is preliminary. But the whole idea is flawed. It is
assumed that a single function exists that makes user input secure for
HTML or for SQL. But infact there is not.
There exists a wide number of possible contexts like
- SQL: Inside a SQL string
- SQL: Inside a SQL table name
- SQL: Inside a SQL field name (uncommon)
- SQL: Inside a SQL comment
- SQL: Where a numerical id is expected
- ... possible others
All these different contexts need another way of preparation/escaping.
What kind of handling is actually needed can only be found out by
parsing the query and knowing what bytes are tained.
This cannot be done if you only use variable level tainting.
If you look at HTML it gets even more complicated because you have many
more possibilities like
- HTML: Outside of a TAG
- HTML: Inside a TAG
- HTML: Inside an attribut of a style tag
- HTML: Dangerous URLs in attributes
- HTML: JavaScript between <script> tags
- HTML: JavaScript inside a JS String
- ....
That said the implicit untainting by use of mysql_real_escape_string()
and htmlentities()
is simply not feasible.
Stefan Esser
Good Morning,
I just wanted to ask if there was ever a decision made that said tainted
mode will go into PHP mainstream.Currently there are two implementations available:
GRASP by Coresecurity
- pro: byte level tainting which actually works
- negativ: slow
PHP Taint mode by Wietse Venema/IBM
- pro: faster
- negativ: broken design+insecure
It is no secret that I don't like the idea of a taint mode in PHP
because it cannot be made secure and fast at the same time.
Coresecurity's GRASP is the best example for this it uses a secure
design and is therefore slow. On the other hand it
seems some people want the fast implementation of Wietse in the core
which would be bad, because it is based on
wrong assumptions and uses an insecure design that does only give a
false sense of security.Examples for the wrong assumptions in PHP Taintmode:
- _SERVER['PHP_SELF'] is not safe and allows XSS (and more) in many
applications- Using mysql_real_escape_string() on user input does not make it safe
for SQL. It only makes SQL strings safe.
Example: "SELECT * FROM table WHERE id=".mysql_real_escape_string($id)
is NOT secure but will result in no taint warning- Using
htmlentities()
on usr input does not make it safe for HTML
output. It only makes it safe in some situations.
Example: echo '....<sometag style="some-attribute: ',htmlentities($user_input),'">'. Will allow XSS through the style
attribute without a taint warning
Example2: echo '....<img src="',htmlentities($user_input),'">'. Will
allow XSS through javascript: URL (f.e. in Opera) without a taint warning
I believe the primary use case for taint mode would be to use it in
development: taint mode is a mode which can be turned on to give you
an idea of where your application may have exposed some
vulnerabilities; let you fix those identified vulnerabilities; then
turn off for production purposes. The speed of the implementation, if
this is indeed the intention for taint mode, would therefore be
irrelevant.
http://devzone.zend.com/node/view/id/1526#Heading3 suggests that we've
had this discussion before and almost came to agreement that taint
mode would be used as a development tool.
--
Dan Scott
Laurentian University
Hi Dan,
I believe the primary use case for taint mode would be to use it in
development: taint mode is a mode which can be turned on to give you
an idea of where your application may have exposed some
vulnerabilities; let you fix those identified vulnerabilities; then
turn off for production purposes. The speed of the implementation, if
this is indeed the intention for taint mode, would therefore be
irrelevant.
The problem here is that both approaches fail to be completely secure
even when your test environment
has 100% code coverage. And I am speaking of real 100% ... Currently
there is no tool that can
ensure that. All PHP CC tools I know of so far will for example not
handle the ternary operator correctly.
The reason why both taint mode implementations fail are simple. Take the
following statement.
$sql['id'] = mysql_real_escape_string($_GET['id']);
$query = "SELECT * FROM table WHERE id=".$sql['id'];
Wietse's taint mode will consider this statement safe and never cry.
GRASP on the other hand will see that there is user supplied data in the
SQL query, but will ignore it
because it is a number. It will only react if $sql['id'] contains a
string. Atleast the very first version did
this.
This means currently both approaches would tell the developer that they
are safe, while they are in fact not.
Stefan Esser
Hi Dan,
I believe the primary use case for taint mode would be to use it in
development: taint mode is a mode which can be turned on to give you
an idea of where your application may have exposed some
vulnerabilities; let you fix those identified vulnerabilities; then
turn off for production purposes. The speed of the implementation, if
this is indeed the intention for taint mode, would therefore be
irrelevant.
The problem here is that both approaches fail to be completely secure
even when your test environment
has 100% code coverage. And I am speaking of real 100% ... Currently
there is no tool that can
ensure that. All PHP CC tools I know of so far will for example not
handle the ternary operator correctly.
Stefan so what is your point then? Since neither can be 100% secure,
do not use any? Or just do not bundle either? There is nothing like
100% secure for anything that allows user access (and of course I am
not telling you any news with this).
I like the "its a development tool" kind of thinking that Dan brought
to the table. From what I understand the heavy duty approach could be
a very good tool to check for security risks and would just be one
tool in the shed along with suhoshin, xss scanner and not forget
common sense and security audits. Now if the two proposed solutions
are ready yet is another question (where I do trust your expertise -
and hopefully also of other security experts - to give us a good
basis for judgement).
regards,
Lukas
Am 18.11.2007 um 22:53 schrieb Lukas Kahwe Smith:
Stefan so what is your point then? Since neither can be 100% secure,
do not use any? Or just do not bundle either?
Yes, that is exactly the way to go. To quote Yoda (and he would know):
"Do, or do not. There is no try.". Or, in contemporary words: do
things 100% properly, but if that is not possible, take a step back
and spare the world some half arsed attempt.
David
Am 18.11.2007 um 22:53 schrieb Lukas Kahwe Smith:
Stefan so what is your point then? Since neither can be 100%
secure, do not use any? Or just do not bundle either?Yes, that is exactly the way to go. To quote Yoda (and he would
know): "Do, or do not. There is no try.". Or, in contemporary
words: do things 100% properly, but if that is not possible, take a
step back and spare the world some half arsed attempt.
This makes no sense to me. There is nothing like 100% secure as long
as you dont pull the plug on the entire application. The only secure
application is one that hasnt been deployed anywhere. So the question
boils down to more "does this increase security sufficiently to make
the draw backs acceptable".
regards,
Lukas
Yes, that is exactly the way to go. To quote Yoda (and he would
know): "Do, or do not. There is no try.". Or, in contemporary
words: do things 100% properly, but if that is not possible, take a
step back and spare the world some half arsed attempt.This makes no sense to me. There is nothing like 100% secure as long
as you dont pull the plug on the entire application. The only secure
application is one that hasnt been deployed anywhere. So the
question boils down to more "does this increase security
sufficiently to make the draw backs acceptable".
And the answer is "no" ;) That's my point! Because one of the
drawbacks is that it won't cut down the number of dumb ignorants who
don't care about that stuff. Why would they, "teh PHP is making things
hax0r proof now" after all.
David
"Do, or do not. There is no try.". Or, in contemporary words: do things
100% properly, but if that is not possible, take a step back and spare
the world some half arsed attempt.
It sounds nice, but from the practical point of view you can't make sure
code is 100% tested and 100% secure. There always will be combinations
of data, algorithm and state of the environment that you didn't think of
and didn't test for. By your logic, thus all security solutions and all
testing are useless. Obviously it is not so, and the reason for that is
that every tol that allows us to cover more security "territory" and
test for more problems is useful, even if it doesn't make your
application never fail.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
"Do, or do not. There is no try.". Or, in contemporary words: do
things 100% properly, but if that is not possible, take a step back
and spare the world some half arsed attempt.It sounds nice, but from the practical point of view you can't make
sure code is 100% tested and 100% secure. There always will be
combinations of data, algorithm and state of the environment that
you didn't think of and didn't test for. By your logic, thus all
security solutions and all testing are useless. Obviously it is not
so, and the reason for that is that every tol that allows us to
cover more security "territory" and test for more problems is
useful, even if it doesn't make your application never fail.
I didn't mean that any kind of testing is useless :)
The thing is, however, that a taint mode feature could not possibly
cover all potential security issues, and would therefor give those
users that do not have the slightest clue about security anyway a
false feeling of safety. We've had that before with magic quotes and
the like and it didn't work. Just look at the discussions here. If my
neighbor's squirrel farts in the wrong direction, and I ate cornflakes
less than an hour ago, there's a 23 percent chance that the untainting
done by htmlentities()
won't be enough. That is just not going to cut
it.
An untaint() approach - all for it (yes, the noobs that don't give a
damn are going to use it because "it just works", but no, that
shouldn't bother us, at least they have been warned). But some
implicit guessing magic that, once again, means people are gonna
switch their brains off - please not.
- David
Hey David,
David Zülke schrieb:
bother us, at least they have been warned). But some implicit guessing
magic that, once again, means people are gonna switch their brains off -
please not.
Frankly, I don't care about people that switch their brains off. If one
doesn't care about security, or doesn't understand the related problems,
they'll always be able to write crappy code, no matter what.
I'd love to see a taint mode in PHP because it would help me make stuff
I use and work on (at least) a little more secure - without a lot of effort.
Regards,
Stefan
--
e-novative> - We make IT work for you.
e-novative GmbH - HR: Amtsgericht München HRB 139407
Sitz: Wolfratshausen - GF: Dipl. Inform. Stefan Priebsch
http://www.e-novative.de - GnuPG Key: 0x7DB67F7F
The problem here is that both approaches fail to be completely secure
even when your test environment
I don't think taint mode can be truly considered as security feature.
It's rather a feature that would remind the developer he needs to think
about security. Just as an alarm clock can wake you up, but can't ensure
you actually will go to work and do something productive there, tainting
can tell you that you need to take care of the variable, but can't
ensure the care was right. While I agree with you on the analysis of the
escaping security, I do not think that this necessarily makes the whole
idea of tainting worthless.
has 100% code coverage. And I am speaking of real 100% ... Currently
there is no tool that can
ensure that. All PHP CC tools I know of so far will for example not
handle the ternary operator correctly.
Most CC tools I know work on line-level, which makes quite hard for them
to report on same-line branches, such as ternary operator. Of course
they could report on opcode-level, but that'd be hard to read for the
user :) So I believe most tools actually know about ternary operators,
but can't report about them.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Stefan Esser wrote:
Hi Dan,
I believe the primary use case for taint mode would be to use it in
development: taint mode is a mode which can be turned on to give you
an idea of where your application may have exposed some
vulnerabilities; let you fix those identified vulnerabilities; then
turn off for production purposes. The speed of the implementation, if
this is indeed the intention for taint mode, would therefore be
irrelevant.
The problem here is that both approaches fail to be completely secure
even when your test environment
has 100% code coverage. And I am speaking of real 100% ... Currently
there is no tool that can
ensure that. All PHP CC tools I know of so far will for example not
handle the ternary operator correctly.The reason why both taint mode implementations fail are simple. Take the
following statement.$sql['id'] = mysql_real_escape_string($_GET['id']);
$query = "SELECT * FROM table WHERE id=".$sql['id'];Wietse's taint mode will consider this statement safe and never cry.
GRASP on the other hand will see that there is user supplied data in the
SQL query, but will ignore it
because it is a number. It will only react if $sql['id'] contains a
string. Atleast the very first version did
this.This means currently both approaches would tell the developer that they
are safe, while they are in fact not.Stefan Esser
Hi all, I'm one of CORE GRASP's developers. GRASP was designed to be
used in production stage and hence it is unacceptable to have false
positive and false negative alarms.
As GRASP's objective is to enhance protection in run-time it was only
designed to block on-going attacks and not to warn the developer about
insecure coding habits. We think that Venema's Taint mode is a lot more
helpful in this task.
Going back to Stefan's example:
$sql['id'] = mysql_real_escape_string($_GET['id']);
$query = "SELECT * FROM table WHERE id=".$sql['id']
It is true that GRASP won't raise an alarm unless $sql['id'] has
non-numeric characters. This was a design decision since our description
of an attack does not include this example. After analyzing this
example, we cannot see how an attacker could perform a SQL-Injection
attack only with numeric characters; that's why GRASP will not detect
this as an attack.
Ezequiel Gutesman
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
Ezequiel Gutesman wrote:
Going back to Stefan's example:
$sql['id'] = mysql_real_escape_string($_GET['id']);
$query = "SELECT * FROM table WHERE id=".$sql['id']It is true that GRASP won't raise an alarm unless $sql['id'] has
non-numeric characters. This was a design decision since our description
of an attack does not include this example. After analyzing this
example, we cannot see how an attacker could perform a SQL-Injection
attack only with numeric characters; that's why GRASP will not detect
this as an attack.
Unless I'm missing something, in this example I don't see anything
forcing 'id' to be actually numerical. Unless forced to be numerical,
see http://webappsec.org/projects/articles/091007.shtml#p4 for an
example how to exploit it; even with mysql_real_escape_string().
-
- Markus
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
- Markus
iD8DBQFHQg8s1nS0RcInK9ARAhPRAJ9qtqG1bMMCoVfTM3A3j2pidt1KVgCeI2Lv
pYcNBRegKEvqjArXkWJmtco=
=vQdC
-----END PGP SIGNATURE
Stefan Esser:
- Using mysql_real_escape_string() on user input does not make it safe
for SQL. It only makes SQL strings safe.
Example: "SELECT * FROM table WHERE id=".mysql_real_escape_string($id)
is NOT secure but will result in no taint warning
Can you give a specific example? I'd like to know how likely such
things would be in real code.
- Using
htmlentities()
on usr input does not make it safe for HTML
output. It only makes it safe in some situations.
Example: echo '....<sometag style="some-attribute: ',htmlentities($user_input),'">'. Will allow XSS through the style
attribute without a taint warning
Example2: echo '....<img src="',htmlentities($user_input),'">'. Will
allow XSS through javascript: URL (f.e. in Opera) without a taint warning
Or they could encrypt the entire URL and include a decryptor
(javascript or some other language) in the HTML text. Detecting
threats that involve script/applet/etc execution requires the
ability to realistically simulate every browser. I haven't
solved that one yet.
That doesn't mean that I should give up trying to warn people about
known-to-be-bad coding practices. I just can't warn them about all
possible ways to screw up.
Wietse
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Stefan,
Stefan Esser wrote:
GRASP by Coresecurity
- pro: byte level tainting which actually works
- negativ: slow
PHP Taint mode by Wietse Venema/IBM
- pro: faster
- negativ: broken design+insecure
I don't see a big problem with having a slow but working taint mode in
development environments while not having a taint mode in production
environments. The question - as always - is, how big the performance
impact really is.
-
- Sebastian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
- Sebastian
iD8DBQFHQTsxsvwfldR9VeARAj0dAJ9KGDy0g92AK0sB+kpWxGn3k52NjACgnbt8
3J6K0b7bOuIXWrH3F5ylnHs=
=kb6h
-----END PGP SIGNATURE