Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: a blog post about securing Spock apps #103

Open
soupi opened this issue Jan 17, 2017 · 8 comments
Open

Request: a blog post about securing Spock apps #103

soupi opened this issue Jan 17, 2017 · 8 comments

Comments

@soupi
Copy link
Contributor

soupi commented Jan 17, 2017

Hello!

I've been writing Haskell for some time now but I'm still a webdev beginner. For the last few weeks I've been working on gathering which is my first real attempt at building a complete website, and of course I chose Spock :)

First I'd like to say thank you for Spock, I enjoy working with it and for the most part I experienced very little friction using it.

However, one thing that bothers me about webdev is how easy it is to introduce vulnerabilities to your users if you don't know what you are doing, and I know I don't know what I'm doing.

So I'd really appreciate some expert advice on how to secure websites written in Spock. A blog post would be even better!
(Also I'd really appreciate any review I can get on gathering. I think it can also help highlight common security pifalls as I'm sure I introduced some unintentionally)

Thanks again!

@agrafix
Copy link
Owner

agrafix commented Jan 17, 2017

Nice, thanks for the feedback! 👍

I'm pretty busy atm, but I took a quick look at your project. Note that this might not be exhaustive. From a security perspective, you should always include a CSRF protection in forms etc., which is possible in Spock using getCsrfToken. Read more about CSRF attacks: OWASP CSRF. Also, after a successful login, call sessionRegenerateId to prevent session fixation attacks. The database looks good since you are using prepared statements, although there's a race-condition in your newUser function as it's not a transaction and thus (although highly unlikely) someone could create a new account with the same name between your check and your insert-statement. Use hasql-transaction instead and don't prewrap all your statements with query for flexibility.

Hope that helps!

Speeking of a blog post - I really like the idea and hope to find time for it ... If any one else would like to write something please let me know I'd be happy to help.

@soupi
Copy link
Contributor Author

soupi commented Jan 17, 2017

Thank you very much for the feedback and help! I will read up and work on fixing those issues.

@soupi
Copy link
Contributor Author

soupi commented Jan 17, 2017

Hello again, I looked around but could not find any explanation or example on how to protect against CSRF attacks in Spock or how to use getCsrfToken.

I tried to enable csrf protection in the SpockConfig

  spockCfg <- (\cfg -> cfg { spc_csrfProtection = True })
          <$> defaultSpockCfg EmptySession (PCConn $ hasqlPool connstr) state

And then do the following before displaying a form to the use:

  csrfToken <- getCsrfToken
  setHeader "spc_csrfHeaderName" csrfToken

But I still get the following when submitting a form:

Broken/Missing CSRF Token

Also, anything related to csrf points for more information in
spc_csrfHeaderName spc_csrfPostName but they aren't very helpful...

I'm probably missing something pretty simple and fundamental, but I've search a lot and couldn't find anything on the subject.

Thanks Again,
Gil

@codygman
Copy link

codygman commented Jan 17, 2017 via email

@soupi
Copy link
Contributor Author

soupi commented Jan 17, 2017

@codygman can you elaborate please? I'm not sure what you're suggesting I should do.

@agrafix
Copy link
Owner

agrafix commented Jan 17, 2017

You have to include the csrfToken from getCsrfToken in your form as hidden input named __csrf_token (you can changes the name of the field in the configuration).

@soupi
Copy link
Contributor Author

soupi commented Jan 17, 2017

@agrafix thanks! this seems to have fixed the issue.

I did however had to fix the path for all runForm calls (example) because each field in it gets a prefix according to the form path and that was the only way i could think of to get a fixed name for the csrf input field consistently across all forms. This is an ok workaround for me, but I have to wonder if there's a better way.

@agrafix
Copy link
Owner

agrafix commented Jan 18, 2017

I'd move the CSRF token handling out of the digestive functor machinery, that way you don't need to do this. Just statically add the mentioned hidden input field to all forms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants