Am I under risk of CSRF attacks in a POST form that doesn't require the user to be logged in?
There's means of CSRF whenever malicious HTML or JavaScript which is targeted on your website is been embedded in another HTML page (or an email message) which is been successfully executed.
An example is the following which is been placed in another webpage which innocently asks for your name and age before proceeding:
<form action="http://yoursite.com/transferfunds" method="post">
Your name: <input type="text"><br>
Your age: <input type="text"><br>
<input type="submit">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="toaccount" value="12345678">
</form>
Note that the action points to your website and that the hidden inputs contains the needed POST information. This example will try to transfer a fund of 1000 (in whatever currency) to account number 12345678. If you require a login on your form and also actually checks on that, then the above will of course only be successfully executed if the unaware user has recently logged in your website, but not logged out yet, or the session is not expired yet.
To prevent that to happen, your best bet is to add a request based token to the form and validate it in the server side. I.e. generate a long, unique and impossible-to-guess random string which you store in the session and embed as <input type="hidden">
element of the form. When the form is submitted, compare the submitted token value with the one already in session (and immediately remove the one in session). To go a step further, make use of a CAPTCHA.
In your particular case, I think you're actually more worrying about XSS, which is an opposite of CSRF, but which in turn can also be a source for CSRF. An example of XSS is when the user enters the following in an input field which is going to be redisplayed sooner or later at the same website:
<form name="delete" action="admin/deleteusers" method="post"></form>
<script>document.form.delete.submit();</script>
Whenever you -as being the administrator- views the page with the comment with the (invisible!) form and script inside, then it will be successfully executed.
Preventing XSS is actually quite easy. Just HTML-escape any user-controlled input (i.e. request URL, request headers, request parameters and request body) prior to displaying them at the webpage. In PHP you can use htmlspecialchars()
for this and in Java/JSP the JSTL fn:escapeXml()
. This way under each the <
will be converted to <
and >
to >
which will make that any entered HTML/JS will be displayed literally as-is and thus can't be executed.