| Newsgroups |
gmane.comp.web.mason.user |
| Message-ID |
<[email protected]> |
First of all, I think you make a number of good points, but you are
muddying the CSRF problem with a number of unrelated security problems.
On Sun, 04 Mar 2012 19:02:49 -0800
Paul Wallingford <[email protected]> wrote:
> 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.
With all due respect, if you do know better, please visit the OWASP wiki
I linked people to and fix its errors.
> 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 attacker can modify the request, it _does not matter_ whether it
is a GET or a POST request.
Pedro's point was (which I concurred with): creating a POST request
(which was suggested earlier on in this thread as the sole fix) makes
the attacker have to jump through perhaps one more hoop. It is not
difficult to fake.
FWIW, I define CSRF as: A user's browser, while logged onto a web site,
is tricked into making a request that does something on the web site.
This is usually achieved by getting the user visit a third-party site
or by posting some content (javascript, link, image) on the web site
that causes the user's browser to make the request.
> 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.
The (session-dependent, one-time, expiring) security token validates
that the form page was loaded from the server before it was submitted.
This mitigates attacks where the user is tricked into submitting a form
through a third-party server.
> 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.
You, as a web site author, cannot control the environment the user
accesses the site from. If there is an attacker in that environment, it
is largely the user's fault for connecting through from there. If your
web site is confidential enough, you must use SSL to connect to it and
hope that the user has seen your SSL certificate in a trusted
environment previously (so that it is cached by your browser).
(I am thinking this from a self-signed certificate perspective -- a cert
issued by the major players that your browser automatically trusts
would perhaps be a bit more secure, but I would not count on it given
the recent breaches)
> The more I look into this GET/POST/XSS issue, the more I realize the
> scanning tool's objections are valid.
"Some web frameworks collapse the POST and GET parameters into a single
collection. This is a flawed design pattern from a security standpoint.
If a page accepts POST parameters as GET parameters an attacker would be
able to effect change on websites through Cross-Site Request Forgery or
leverage this design flaw with other vulnerabilities to attack the
system hosting the web application."
I'm reading that as "if a form submission handler accepts its
parametres through GET, it is easy for the attacker to submit that
form." If the form in question does something that is not read-only, it
certainly should restrict its HTTP method into POST (which is not the
solution to CSRF.)
> 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.
You are conflating this with an unrelated vulnerability, cross-site
scripting. It is easily mitigated if you dutifully HTML-escape every
input coming from the database, user, or elsewhere.
(However, an XSS vulnerability makes CSRF much easier)
> 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.
I think that would be a major logic error on the part of the person
coding the web site.
> 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.
The second one is a basic check that should be done in all code. Again,
this is not CSRF.
As for the first one -- the code that handles the form submission
definitely should check that the request in question was a POST, and if
it is sensitive enough, it should also check the CSRF token (or
similar) is present, as suggested on the OWASP link.
> Security is hard - much harder than most people, particularly
> programmers, realize.
My personal view regarding common web-based vulnerabilities is: for all
web apps, it is of critical importance to fend off SQL injection and
HTML injection (XSS). CSRF prevention comes a fairly distant second to
those two, and the need for it largely depends on the "value" of the
site in question and the security habits of its users (are they likely
to get social-engineered to another web page when logged in?)
Quoting from the OWASP page: "The impact of a successful cross-site
request forgery attack is limited to the capabilities exposed by the
vulnerable application."
> 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.
Is that not the "bad information" I spread in the first place?
> 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:
I think it should keep cookies and parametres separate, but I still
don't see what makes GET and POST parametres different enough for it to
be a security faux pas to collapse them into a single hash.
That being said, I tested HTML::Mason and it does parse the parametres
from the URL even when the request was a POST. In the case where a
POST/GET parametres collided, the %ARGS hash returned an arrayref with
both. Should it not do that? I don't know.
> 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 must sanitise all input-that-becomes-output to prevent injections,
and, where possible, validate input. Nor trust the user.
------------------------------------------------------------------------------
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