CSRF attack - GET and POST request on same page - html

One web application has a delete button. Once clicked that web application do GET request first which will return POST form with token key.
Asking Yes or No. if yes, resource is deleted.
How I can achieve this for CSRF attack? I can submit first request hidden in iframe but I need that token to submit second POST request.
Ajax fails due to CORS.
So is it even possible on one page
Send GET request
Parse response and get token
Submit POST form with token to trigger CSRF

I think this is essentially the standard protection against CSRF, a token is generated upon page generation (a GET), and it's verified upon submit (POST) that actually changes application state (deletes an object in your case). So conceptually it looks good to me.
The devil is in the details though. How is the token generated (what algorithm and/or random generator is used, how much entropy it has) and how is it then verified? Is it stored somewhere or stateless? When do you generate a new token and when do you reuse an old one? These are some questions that must be taken into account as always when protecting against CSRF.
One special question that comes to mind for your scenario is whether the confirmation page has all the details about what will be done. A simple "Are you sure?" would not be adequate in your case I think.

Related

How to run json API command by clicking a hyperlink?

I am a total newb to API and json so this might be basic. But couldn't find a solution by googling.
I want to change e-shop order status via API by clicking a hyperlink in an e-mail.
I activated an API and managed to change the order status by Postman by following command:
PUT {url}/api/v2/orders HTTP/1.1
Content-Type: application/json
Authorization: Basic {abcdefgh}
{
"orders": [
{
"order_number": "00001",
"status_id": "16",
}
]
}
Is there a way how to run this command by simply clicking a hyperlink?
And should I be concerned about security since the authorisation is hardcoded there?
CHeerS!
Email clients for safety reasons do not support the execution of scripts or anything else other than a GET request. As this would require the use of javascript/jquery to build up a payload and call the API with said payload.
You will need to take the client to a secure page to sign in and manage their order.
The hyperlink can perhaps take them to a sign-in page or register page.
Token authorization might work with email being the verification taking the user to a page to see their orders. But again, you won't be sure an authorized person opens the email.
Regarding hard coding any type of authorization, that is a big no.
Since clicking a hyperlink in an email is the same as typing out the address in the browser bar, you can't make POST requests through it. One way of doing what you want is to generate a onetime-use token, and simply put it in the url. When the user clicks the kyperlink, the GET request to the server will contain the token, which can be used for validation.
Is there a way how to run this command by simply clicking a hyperlink?
Not in general, no. Clicking on a link in an e-mail issues a GET request, which can't contain a body. That is: your "orders" JSON won't be included. It also won't know to include the Authorization header.
As far as I know, no common e-mail clients allow you to issue PUT or POST requests.
So: could you encode the request in the URL, and use a GET request instead? Absolutely you could. Don't do this.
There are several reasons for this. The most important is the one you mention:
And should I be concerned about security since the authorisation is hardcoded there?
Hardcoding authorization is a bad idea in general, but particularly in an email: (1) you can't guarantee that an email is encrypted, which exposes the credentials to anyone who can capture the message; (2) if you forward the email to me, I now have your credentials.
Moreover, if you include the authorization in the URL, that's now in the user's browser history, and if they share the link with anyone ("hey, look at this deal on paperclips!"...), well: same as above.

Support Locating the CSRF Vulnerability

I'm analysing a project that uses Spring Security and AngularJS. I know there is a CSRF vulnerability within a specifc form, but I'm unable to get my head around it.
The server sets a CSFR Token as a cookie (not HTTP only, not Secure) for each session. It remains the same for each session. On form submission, AnagularJS takes this cookie and appends it to a custom HTTP header, as shown below.
My understanding is that this is the best method of protecting a site, double submit. With the assumtion that it's already XSS secure, it will not be possible for another site to set a custom header on a HTTP request?
I've searched many forums and many say this is the best method of using a CSRF token, even better than putting within a hidden field in the form.
I'd like ask if anyone knows why this method isn't secure and if it is vulnerable to CSRF.
Many thanks!
P.S - I should add the CSRF token appears to be a randomly generated value, not linked to the session. If I use burpsuite to edit both the header and cookie, to any value, the server will still accept it.
I'm attempting to locate the CSRF vulnerability and then I can work on repairing it.

Can a malicious user submit data if there is no form?

In my site, users can only modify their personal information only once a day. Script-side, I determine if they are allowed to (i.e. check with the database if it's been 24 hours since the last modification) and whether or not to display the form.
My question is, could a malicious user manage to submit information if there's no form? In other words, if there is no FORM element no data should be submitted by the user's browser, right?
What I'm afraid of is that if someone manages to send the data, the script would still process it and change the personal information when it shouldn't.
Of course - this would be a kind of replay attack. So long as your resource endpoint will handle a malicious POST request, regardless of the content of the preceding GET then you're vulnerable.
Remember: never trust the client. Provided that you do authentication and authorization checks before handling a POST request then you'll be fine.
Yes, a malicious user can still send data even without the form, if he knows the url of the page which accepts the data and their corresponding attributes it expects. He can then easily create a form with that info and submit the data.
So you basically need to validate the data at the server-side.
YES
For example someone could use curl.
curl -d profile=value http://www.yoursite.com/profile
You could prevent such attacks with a CSRF token you send along with your form.
See this article for more background http://shiflett.org/articles/cross-site-request-forgeries.

Is there any way of sending on POST data with a Redirect in an MVC3 controller?

I have a form which is posted to an MVC3 controller that then has to be POSTED to an external URL. The browser need to go to the URL permanently so I thought a permanent redirect would be perfect.
However, how do I send the form POST data with the redirect?
I don't really want to send another page down to the browser to do it.
Thanks
A redirect will always to be a GET, not a POST.
If the 2nd POST doesn't need to come from the client, you can make the POST using HttpWebRequest from the server. Beware the secondary POST may hold up the return of the client request if the external server is down or running slowly.
A permanent redirect is wholly inappropriate here. First, it will not cause form values to be resubmitted. Second, the semantics are all wrong - you would be telling the browser "do not request this url again. instead, go here". However, you do want future submissions to go to your same url.
Gaz's idea could work. It involves your server, only.
Alternatively, send a form with the same submitted values and the external URL, and use client-side code to automatically submit it.

Best way to hide a form input field from being accessed using firebug?

I have a form which is posted to an external API. There is a parameter called customer_token which is passed as an input field. It is used for authentication by the API and every customer is assigned one token. The input field is visible in Firefox's Firebug (even though it is a hidden field).
How do I hide it?
Options
Using javascript as I thought initially
I think using javascript to create that input field at the run time before submitting the form and immediately removing the field will work but still the field will appear momentarily. So, even if a person can't manually get it, I am afraid that a crawler or spider (I don't know the exact term - but some automated script) may get the customer token. Is there a better solution for this? After form submission, the same form remains displayed.
Using one-time token concept as suggested by Ikke
I am not sure how it will work? The API needs the correct customer token value to process any request. So, even to generate a one-time token and return, a request with the customer token has to be sent. This way anyone is able to see my customer token value and they can also send a request to get a one-time token and use it. So how does it solve the problem?
Resolved
Check How to post form to my server and then to API, instead of posting directly(for security reasons)?
Thanks,
Sandeepan
This is not possible. Firebug just reads the DOM in it's actual state, so even if it's added in a later stage, it can still be retrieved.
This way of security is called Security through obscurity and is a kind of non-security. You would have to solve it another way, like letting the server do the request in stead.
You let the user submit the form to the server. Then with curl, you make the call to the webservice with the correct user code.
I don't think this is possible I'm afraid.
Firebug will still see the element if it's inserted via Javascript, as it watches the DOM tree. If this input exposes a security vulnerability then it's the job of your server-side code to validate/fix it.
More details on the API might help somebody answer this question in more detail.
I hope this helps