perlquestion
Anonymous Monk
<p>I've been tasked with updating a website that was developed in 2003-2004 before Cross-Site Request Forgery (CSRF or XSRF) was really well known to be an issue. The system is currently built on mod_perl2 and HTML::Mason (Mason 1, not 2), and it uses [mod://Apache2::AuthCookieDBI] for user authentication. I'm sure it was state-of-the-art back in 2003-2004, but the basic building blocks haven't been updated since then. A recent security audit revealed that most of this site's CGIs are vulnerable to CSRF, and I need to fix it.</p>
<p>Switching to a completely different framework/middleware like CGI::Application, Dancer, Catalyst, or Plack would take too much effort, I think. And everyone is happy with how the site works currently, so avoiding any user-visible changes would be preferable.</p>
<p>So what's the best way to incorporate CSRF protection into a site that uses mod_perl, Mason, and [mod://Apache2::AuthCookieDBI] (or [mod://Apache::AuthCookie] in general)? Has anyone done anything like this?</p>
<readmore><p>[mod://MasonX::Request::WithApacheSession] looks promising, but [mod://Apache::Session] doesn't appear to be updated as frequently as [mod://CGI::Session] or as well regarded, I think. There's also [mod://Apache::SessionManager], but it hasn't been updated since 2004. A lot of these modules seem to overlap conceptually with [mod://Apache::AuthCookie]. It appears I'd be almost generating two session IDs if I go with one of these approaches in addition to using Apache::AuthCookieDBI. Can I reuse the AuthCookieDBI ticket as the session ID with any of these modules?</p>
<p>Or should I just roll my own class to generate a random, one-time-use-only, expirable token, stick it in just the forms that have consequences as a hidden parameter, and store the token in the server-side database? I don't want to reinvent the wheel, but there is similar code already in this project for handling password resets which I could potentially generalize and refactor, so I'm very tempted to go this route. The problem with that is that it's not a comprehensive solution, so it would require identification and modification of the vulnerable forms that modify the database and there's always the possibility I could miss a form. Even if I don't, some future web developer might add a new form without thinking it through.</p>
<p>Thanks for any advice!</p></readmore>
10