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