Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
This is about a kind of XSS security hole betterworld and I detected recently.
It's described at http://en.wikipedia.org/wiki/Cross-site_request_forgery.

Example

You have a webapp at yourdomain.example. Let's say you have a profile settings site where you can set your realname, for example (harmless example though).

The user is authenticated by a session cookie.
The form looks like this:

<form action="http://yourdomain.example/script" method="POST"> <input type="text" name="realname"> <input type="submit" name="submit.save_realname" value="Save"> </form>
The code looks like:
if ($cgi->param('submit.save_realname')) { my $name = $cgi->param('realname'); # do some checks on $name $user->realname($name); $user->update; }

Looks fine, doesn't it?

Missed something?

The form-method is POST. Why is it POST and why don't you care in the script if it really was sent by POST?
Consider some bad hacker creates a website on http://somewhere.example/bad.html:
<img src="http://yourdomain.example/script?submit.save_realname=1;real +name=owned" height="0" width="0" alt=""> or even: <meta http-equiv="refresh" content="0; URL=http://yourdomain.example/s +cript?submit.save_realname=1;realname=owned">
Now if you are logged in at your website (have a cookie) and somehow go to the bad website, your realname will be set automatically, and you canot do anything to prevent this. You don't even need Javascript.

An easy solution for this is to check for POST in your application.
if ($cgi->request_method() eq 'post')
(Bad thing is, there are a lot of websites out there that don't check, and while you can make your own applications safe, you can't do this for other sites you visit)

Still not safe?

Well, consider you have Javascript on. The bad website could look like this:
<body onLoad="document.forms[0].submit()"> <form action="http://yourdomain.example/script" method="POST"> <input type="text" name="realname"> <input type="submit" name="submit.save_realname" value="Save"> </form>
Here checking for POST will not help you (as a user). The only thing that helps is to have Javascript off for unknown websites (Site preferences in Opera, NoScript in FF). And hope that the bad html-form is not on a website where you have Javascript on.

Use Tokens

A lot of websites do this already; create a token (that expires like a session-id), and that must be a parameter in the form:
<input type="hidden" name="t" value="123abc...">
So every action of the script that changes data should require such a token. That makes your script pretty safe.

Couldn't browsers help me to surf more secure?

Well, if the scripts are programmed badly, why should browser vendors care?
Because they can.

In Opera you can say that you just want get cookies from the current site. Unfortunatley Opera still sends cookies from domain A to an embedded image of domain B.
In Firefox you can say "Privacy - Cookies - from original site only", which will prevent receiving and sending cookies.
But even the Firefox preference does not prevent doing a meta-refresh.

Also, there is no possibility to say "Warn me before a site does a form.submit() to a different domain". All these things could be implemented.

So, while you can do some things to make your own scripts safe, do you also think, browsers should take care of these issues? Here is a posting on Bugzilla https://bugzilla.mozilla.org/show_bug.cgi?id=375238 about this.

Update 2008-04-17: In Opera 9.5 the option "only send cookies to the site I visit" works reliably. In Firefox, the extension CookieSafe (and the option originalOnly) doesn't work reliably. So if you wanna be safe from CSRF, try Opera 9.5. But make sure you deactivate this option for OpenID sites.


In reply to Is your web application really secure? ("CSRF") by tinita

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others cooling their heels in the Monastery: (7)
    As of 2014-12-21 12:20 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Is guessing a good strategy for surviving in the IT business?





      Results (104 votes), past polls