How to protect cross site form submit - webforms

Does anyone know how to protect cross site form submit? For example if I have register page and user have to enter there own email and password and I do not want anyone submit email and password value from other site to myweb site.

Store secret randomly generated key inside users session. When user will open page with form put inside form hidden input with that value. Check if both match while validating received data after form is submitted.

If you mean you don't want people to be able to submit data in a form hosting on another website to your server one way of preventing that would be to check the Referrer HTTP header however this is not going to work all of the time as it relies on data being sent by the browser and is easily faked.
You would also end up causing hassle to those who turn off HTTP Referrer sending.
Another way to get this to work might be sending an <input type="hidden" value="dsahdbashdbhas[keyboard mash]" /> which will have a value you generate (when the user requests the page) based on their IP address. Then when you process the form you can check for this value and if it isn't correct you can drop the request.
If this is to prevent automated form filling then you should use CAPTCHA

In the web security world, this is a vulnerability known as Cross-site Request Forgery (CSRF). You should be sure to read the Cross-Site Request Forgery Prevention Cheat-Sheet --and other pages-- at OWASP

Related

Passing a CSRF token

I'm trying to pass a CSRF token in a form that is submitted via a javascript (not jquery) AJAX function. The accepted wisdom appears to be to include the token as a hidden input in the actual form. As I see it the problem with this is that the contents of a hidden input can easily be seen using a browsers inspect facility. So is there a more secure way to pass the token?
It's not an issue that the CSRF token is accessible in the source code because it's not meant to be hidden to the client browser. And when I say "hidden" here I am not talking about the HTML property "hidden" of a form, but the disclosure of the token, should it be by analyzing page source, script execution or network traffic (really hidden).
You must understand why CSRF tokens are useful. If an attacker creates a malicious webpage, hosted under an external domain, which POST or GET to your website, then he can expect an authenticated user (a victim - with an open session and sesion ID in cookie) to perform the POST/GET: the victim's browser will detect the target URL, add the cookies/session ID to the GET/POST headers, and perform the action on behalf of the authenticated user (eg: "destroy my account").
If you create a random CSRF token in the source, the attacker cannot read it (because he cannot load the page on behalf of the victim's browser and read its content, thanks to Cross-Domain content segregation) and hence cannot build a malicious page which will perform a GET or POST.
As for other methods, other websites use a unique static CSRF token (generated per user on session init), which is saved in cookies and included in the forms of the sites through JS. The result is the same, the token will be part of the form submit (and so accessible to the client's browser). You just avoid producing CSRF tokens for each form and the server can easily compare the token with the client's session data rather than performing side-channel token management.

Cross site forgery on AJAX service

I'm a little confused as to how to prevent cross site forgeries. Still. I know there is a wealth of information out there, but I'm confused.
In Steven Anderson's post he describes a form like this:
<body onload="document.getElementById('fm1').submit()">
<form id="fm1" action="http://yoursite/UserProfile/SubmitUpdate" method="post">
<input name="email" value="hacker#somewhere.evil" />
<input name="hobby" value="Defacing websites" />
</form>
</body>
On someone else's site.
The solution given is a "anti-forgery" token, generated by the server, that is POST-ed back to with any requests in a hidden form. That's cool, but what is to stop the hacker just downloading the form page, extracting the token and POSTing it?
My application for this is: On the sign-up for to my website I'd like a AJAX function that sends the currently entered Username to the server which should respond "True/False" if it is available or not. This happens onKey so the user can pick a username that has not been used already. The Submit button will enable when all the conditions for "new user" are met.
Clearly this is an opportunity for a hacker to use the service to "test" lots of usernames to see if they available - I know it's not exactly internet-banking level sort of risk, but I'd still like to service only requests from my application, not a hacker.
Any ideas how about these queries?
UPDATE:
So in my scenario. I generate a Token (say some hashed value of the client's IP address) and the service expects to receive this back if it is give the information about whether the username is available or not.
-- The problem remains, someone off domain simply calls the service e.g. /generateToken This looks at the client's IP... could be a hacker who knows.
Returns
{ token: 4uru32br }
Which is then submitted to the /isUsernameAvailable?token=4uru32br&partialUsername=usernam
Where does that get me?
what is to stop the hacker just downloading the form page, extracting the token and POSTing it?
The same-origin policy, that's what.
I'd like a AJAX function that sends the currently entered Username to the server which should respond "True/False" if it is available or not.
That's a user-enumeration vulnerability right there.
Any ideas how about these queries?
Here's your new process:
Use email addresses for usernames.
Use CAPTCHA to prevent automation on registration forms.
Email username does not exist:
Show "success" message. Send email to address with one-time link. Register user after returns to your site with that link.
Email username does exist:
Show "success" message. Send email to that address with message saying "someone is trying to create an account with this address but it already exists".
You're mixing up CSRF and user enumeration.
The solution given is a "anti-forgery" token, generated by the server,
that is POST-ed back to with any requests in a hidden form. That's
cool, but what is to stop the hacker just downloading the form page,
extracting the token and POSTing it?
Say Bob is a normal user on your site.
Chuck is an evil attacker.
Bob goes on your site and submits the comments form (in your code example). If there is CSRF protection, a token is included in this form too:
<input type="hidden" name="csrf_token" value="zxcvbnnmm1235152" />
Bob's session has token zxcvbnnmm1235152 stored for him server-side.
Chuck also has a login to your site because he has registered.
However, when he goes to this page he gets this token instead:
<input type="hidden" name="csrf_token" value="lklkljlk898977" />
If Chuck downloads the page, gets Bob somehow (e.g. sends him an email) to access this page on Chuck's server, because the csrf_token doesn't match Bob's, Chuck can't post the message as Bob.
Bob can continue just fine, because the token in the form matches the one associated with his session.
CSRF is about stopping Chuck from submitting stuff as Bob, using Bob's browsing session.
My application for this is: On the sign-up for to my website I'd like
a AJAX function that sends the currently entered Username to the
server which should respond "True/False" if it is available or not.
This happens onKey so the user can pick a username that has not been
used already. The Submit button will enable when all the conditions
for "new user" are met.
Clearly this is an opportunity for a hacker to use the service to
"test" lots of usernames to see if they available - I know it's not
exactly internet-banking level sort of risk, but I'd still like to
service only requests from my application, not a hacker.
Yes, this is your user enumeration vulnerability.
Have username as email, and follow this answer on how to make this secure.
The anti-forgery token is not a random code. Nor a reused token for several requests.
Rather, the server couples the token with the callers ip-address or session, for example by encrypting the ip+salt with a server-key.
Thus, if the attacker tries to download the token from your site, it won't be usable by the real client

CSRF risk in Ajax

I'm using Symfony2 and protecting my forms with a CSRF token.
I have a comments system based on Ajax calls. If a user wants to edit his comment, here's what's happening:
A user hits the edit button.
A "fresh" comment edit form is loaded via ajax.
The user edit and submit the form via ajax.
The edited comment is sent back in response.
Is loading the "fresh" edit form via ajax a security risk?
If the form were already in the loaded page and couldn't be requested via ajax, an attacker could not guess the CSRF Token, but since he can request the form he can get his hands on the Token..
Couldn't he..?
Maybe an example will make it clearer:
Dave is an innocent registered user in my site (www.acme.com).
Dave logged in my site and then visited www.evil.com. He doesn't know that, but when he visited evil.com a script was executed.
The script sent an ajax request to www.acme.com/comments/123/edit and got the edit form in response.
It then filled in that form with it's malicious content and submitted that form (again, with ajax).
Will evil's evil plan work?
As far as i understand, there is no risk if your form contains CSRF token field. Default Symfony2 CSRF token depends on session which is not availiable for the attacker (and also on intention). So when the attacker requests the form there is attacker's (not user's) session id used.

submitting a form with ajax and retaining session

I have a page on domain A which includes a javascript from from domain B. The script loads a form from domain A with Ajax and posts it back to A.
The form got rejected by Yesod because of missing session variable which resides in a cookie and isn't transmitted on Ajax request because of that.
Can Yesod's session mechanism be made work in such a situation?
I was given an answer by Michael Shoyman, the author of Yesod. The easiest way in my case is to disable CSRF protection for that particular form. There is an api function for that.
http://hackage.haskell.org/packages/archive/yesod-form/1.1.4.1/doc/html/Yesod-Form-Functions.html#v:runFormPostNoToken

Ajax Request for same domain only. Restrict Cross domain ajax

I am new for jquery with limited knowledge.
I am doing ajax request to fetch much imp information to display into the page without reloading the page.
It is done.
But i am worried about. Any can do the call from other server to that php file to get information details.
My Question is that How i can restrict the others to access that file using ajax or directly putting the file path in browser address bar?
Please Help in it.
Thanks in advance.
An ajax request is like any other http request.So you can add the security layer on your server using session-cookies, which will work only if user is logged-in(or you can create dummy sessions for pages that don't expect user to be logged in)
You'll need to include a CSRF token in all your AJAX calls. This prevents CSRF attacks since the attacker cannot put the right token in its submissions.

Resources