Re: Post/Get collection 'collapse'

Paul Wallingford <[email protected]>
Newsgroups gmane.comp.web.mason.user
Message-ID <[email protected]>
On 3/3/2012 6:18 AM, [email protected] wrote:
> On Sat, 3 Mar 2012 12:17:58 +0000
> Pedro Melo<[email protected]>  wrote:
>
>> CRSF attacks are dangerous but the solution is making sure the
>> attacker lacks a piece of information that the real user has. When
>> generating a form for the real client to submit, add a hidden
>> parameter with a cryptographic secure one-use-only token, and stash
>> the same token in the user session, server-side. All form submissions
>> must include that parameter, and it must match the token in the
>> session.
>
> This is the best advice on the thread, and in fact the only real
> solution to CSRF proposed so far. The security tokens need not to be in
> every form, but they are critical in the forms whose submission takes
> some sort of action (deletes user account, submits an order, sells
> stocks, sends an e-mail, etc)
>
> However, judging from the security-scanning tool's description, it
> might still complain about the same thing even if you fix it this way.
> The GET/POST thing indeed has nothing to do with CSRF:
>
> https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Prevention_Measures_That_Do_NOT_Work


The security token does not solve the problem.

"The GET/POST thing indeed has nothing to do with CSRF:"

Yes it does and please do not spread bad information, particularly when 
it comes to security.


If you have your form submit by POST, but the attacker can add the same 
argument via GET, then you need to know if the framework will take the 
POST value, the GET value, or somehow combine the two.  If the GET 
parameter takes precedence and is returned to the application, then you 
will still have: 1) a parameter handed to you by the attacker, 2) an 
apache request object that claims the overall data comes from a POST, 
and 3) you will still get your security token, so your software thinks 
everything is ok - which it most certainly is not.  The security token 
does nothing more than validate the blank form came from the server at 
some time in the past, not that the contents have not been tampered 
with.  Also, your handling of the token may or may not make you 
vulnerable to replay attacks or denial of service attacks.

A man in the middle attack is simple to do since: 1) public WiFi is so 
prevalent, 2) WiFi amplifiers are easily available that extend the range 
the attacker can use to access your wireless network - even if it is a 
private network, and 3) since most web accesses are not SSL encrypted. 
Just one request, either way that is unencrypted, provides the attacker 
with the cookie data and thus the session key, for man in the middle or 
session hijack attacks.  WPA/WPA2 has been partially broken, so it no 
longer provides the level of security once thought.


The more I look into this GET/POST/XSS issue, the more I realize the 
scanning tool's objections are valid.


So, where does the XSS / CRSF part come in?  The examples I and others 
have provided just use simple values, like "a".  But what if, instead of 
"a", it is javascript like <script language=javascript>{code that does 
some nasty stuff></script>.  Often, GETs are returned as part of the 
page, even if the page is an error page from the server.  Or, the 
application may take that data and incorporate it into the new page that 
gets sent.  When that happens, the javascript gets executed and nasty 
stuff ensues.

Sanitizing input includes all of the following:
- Filtering bad characters (by only keeping known good characters)
- Filtering sources of parameters (GET, POST, cookie, etc)
- Filtering parameters based on their relationship to the state of the 
session.

Many web apps have a central controller that acts on the parameters, 
without knowledge of the state of the system.

You might have a "cmd=new" parameter that allows the user to set up a 
new account.  However, once that account is valid, the new parameter 
should no longer be a valid command.  An attacker that inserts "cmd=new" 
on the GET part of a POST could cause the customer's account to get 
wiped, causing a denial of service attack.  In this case, filtering 
based on source and system state would have defended against the attack. 
  1) This command is not from a POST so we discard it and 2) the "new" 
command can only be invoked for sessions that do not have a valid 
account, so we reject the transaction.


Security is hard - much harder than most people, particularly 
programmers, realize.  Programmers work by starting with a problem to 
solve and having a solution pop into their head that seems to solve the 
problem.  They code it then test and debug until it works for a 
reasonable set of sane test examples.  With security, this process is 
dangerous and does not work.  It is only possible to prove that 
something is *NOT* secure.  You cannot prove that something is secure 
because there is always the possibility that there is some set of 
circumstances that was not thought of that could compromise the system.



Bottom line for this problem:

1) It is ok to take data from POSTs and GETs, although POST is preferred 
since it does not get stored in a web server's logs and is not visible 
via the URL bar in the browser.  Preferring POST over GET does not 
increase security in any way as it relates to an attacker who can inject 
malicious parameters or javascript.

2) It is ok to have the same parameter used multiple times through 
whatever mechanism (POST, GET, cookie, etc).

3) You and your framework *MUST* keep all of these separate and tag them 
in some way with their source, so that your application can determine:
   a) For example, that parameter "size" can have multiple copies, but 
can only legitimately come from a POST so we ignore or discard versions 
of it that come from a GET, the cookie, etc.
   b) For example, that parameter "sess" is the session id and should 
only come from the cookie, so discard any copies that come from POST or 
GET, etc.
   c) For example, that parameter "client_id" should be from a POST and 
must only appear once, so if we have multiple copies, the best thing to 
do is assume hacking and reject the transaction.

4) You and / or your framework *MUST* sanitize all input from an any 
source, be that GET, POST, cookie, etc.  Anything that comes in via the 
network is to be assumed untrustworthy.  You can never assume that the 
client's computer does not have a virus, software defects, or that the 
client knows about and/or intended to send the request you are now 
processing.  Enable Perl's taint mode and you are probably half way 
there.  In this case, sanitizing involves not just looking for and 
keeping good characters, but also good sources of that data and sane 
session state.


Good luck.

Paul Wallingford

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.