Is CSRF a threat if not using cookies? - ajax

My Flask app is AJAX-heavy, but does not use any cookies. Is CSRF still a threat or is it safe to deploy the app as of now?
I have already looked at this SO question but my situation is slightly different, since I do not have to worry about user's credentials.
I tried an AJAX call from Chrome DevTools (using $.ajax()) to my server which was running on localhost (Flask development server) and I got an error saying
XMLHttpRequest cannot load http://localhost:5000/_ajax. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'chrome://newtab' is therefore not allowed access.
Does this mean I am safe, or is it possible that a hacker could circumvent this and still make AJAX calls to my server?

CSRF isn't just protection against CORS AJAX. I could make a form on my site, and set the action to http://yoursite.com/account/delete. If a user submits my form, without CSRF on your site, the action would succeed. Or if you have things change on GET requests (shouldn't do that anyway), I could add this to my site:
<img src="http://yoursite.com/account/delete" />
and the action would happen when my page loads.
Check out Flask-WTF or this snippet: http://flask.pocoo.org/snippets/3/
EDIT
From your comment:
Change the action of that page to a POST, and have it be accessed through a form instead of a link. If your link was:
<a href="{{ url_for('my_page') }}">Click Here</>
Your form could be (using Flask-WTF, which you would need):
<form action="{{ url_for('my_page') }}" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="submit" value="Click Here" />
</form>

Related

Laravel 7 Auto logout when session expired

I would like to logout the page and redirected to the login page when the session expires in Laravel 7. Can any one please help me to do this? Thank you
There is normally this functionality implemented in Laravel. You need a POST request to the '/logout' route with (and therefore a csrf field in your request).
Usually you have in your blade a hidden form for that and a button or a link (it depends on what you use) that activates the sending of the form (with javascript).
For example, in the basic template of laravel we have this:
The form that is hidden:
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
The link used here to allow the user to log out:
<a href="#" onclick="event.preventDefault(); document.querySelector('#logout-form').submit();">

Export Excel with Laravel, VueJS and Inertiajs

I'm trying to build and application on Laravel, VueJS and inertiajs.
I'm using maatwebsite/excel to export my data into excel format.
I've a vue component which has a normal HTML form
home.vue
<form action="/project-profile" target="_blank" method="POST" enctype="multipart/form-data">
<input type="hidden" name="_token" :value="csrf.content" />
<input type="hidden" name="slug" :value="JSON.stringify(generalDetails.slug)" />
<button class="font-medium tracking-wide">Download Profile</button>
</form>
And on mounted method I'm just placing my csrf token.
mounted() {
this.csrf = document.head.querySelector('meta[name="csrf-token"]');
}
In Laravel part I made a route in web.php file
Route::post('project-profile','ProjectProfileExportController#ProjectProfile');
Whenever I try to export or submit the form, I get page expired error, I followed few guide and it says there is issue with csrf_token but while inspecting the form I can see token is placed appropriately.
I tried doing the same by making this as api, api.php:
Route::post('project-profile', 'ProjectProfileExportController#ProjectProfile');
But this thing also not work as expected.
Screenshot of page expired screen
Screenshot of inspect form element
Any better approach is welcome. Thanks.
Creator of Inertia.js here.
So, we recommend not manually sending the csrf token on each request like this.
A better approach is to use the CSRF functionality already built into axios for this. Axios is the HTTP library that Inertia uses under the hood.
Axios automatically checks for the existence of an XSRF-TOKEN cookie. If it's present, it will then include the token in an X-XSRF-TOKEN header for any requests it makes.
The easiest way to implement this is using server-side middleware. Simply include the XSRF-TOKEN cookie on each response, and then verify the token using the X-XSRF-TOKEN header sent in the requests from axios.
Some frameworks, such as Laravel, do this automatically, meaning there is no configuration required. So, I'd recommend removing the csrf-token meta tag from your template, and removing the _token from your requests. That should take care of your issues.
That all said, keep in mind that you will not be able to download an Excel file from an Inertia request. All Inertia requests MUST return a valid Inertia response. You can use window.open for this. Something like this:
window.open(`/url/to/excel/download?slug=${generalDetails.}`, '_blank')

How to make work laravel, vue session csrf

Laravel forms need csrf to work
If i make spa, single page application, with vue+laravel so that my laravel template contains only empty html and body,
and user doesn't actually refresh the page at all during many hours of working with app,
(page does not refresh because everything is with ajax)
How do I get to keep the login session alive ?
How do I get the csrf to work ? Or can i disable it ?
The application does nothing without login first.
If you are using axios with Vue2 for your ajax requests csrf is already available in bootstrap.js, you could see there this line
let token = document.head.querySelector('meta[name="csrf-token"]');
If you want to insist for your ajax only, then you would have put this line in your mounted hook.
mounted() {
this.csrfToken = document.querySelector('meta[name="csrf-token"]').content
},
this csrfToken should be attaached in your forms like this one
<form :method="method.toUpperCase() == 'GET' ? 'GET' : 'POST'">
<input-hidden :value="csrfToken" name="_token"/>
<input-hidden
v-if="['GET', 'POST'].indexOf(method.toUpperCase()) === -1"
:value="method"
name="_method"
/>
<!--
This hidden submit button accomplishes 2 things:
1: Allows the user to hit "enter" while an input field is focused to submit the form.
2: Allows a mobile user to hit "Go" in the on-screen keyboard to submit the form.
-->
<input type="submit" class="absolute invisible z-0">
<slot/>
</form>
for good example of it. check this out csrf token
Note: Please don't disable csrf token cause it's only your way to secure your requests to the server.

How to use Go lang http client to submit http request to a SSO enabled server

I am working on a Go script that makes some API calls to a webserver. I use the net/http library. SSO can be enabled or disabled on this webserver. So my go script works well with a non-SSO webserver. It is able to hit the endpoints. But with SSO, I get a http response like this
`
Note: Since your browser does not support JavaScript,
you must press the Continue button once to proceed.
<form action="https://hostname/idp/SSO.saml2" method="post">
<div>
<input type="hidden" name="SAMLRequest" value="PD94bWwgdmVyc2lvbj......pBdXRoblJlcXVlc3Q+"/>
</div>
<noscript>
<div>
<input type="submit" value="Continue"/>
</div>
</noscript>
</form>
</body>
`
Is there a way in Go lang, to execute the form action and handle all the redirection?

CSRF error in laravel

I have a problem in Laravel . when over and over submit Form with post method and somtimes I get error and see expire error that related to CSRF
anybody knows how can I manage this error that display not in site and instead of redirect to any page else ?
Laravel makes it easy to protect your application from cross-site request forgery (CSRF).
Just add #csrf blade directive inside the form to avoid getting csrf token error.
<form method="POST" action="/profile">
#csrf
...
</form>
The directive puts something like this
<input type="hidden" name="_token" value="CzK6peomC6Pnnqdm4NsxpdGSH6v1evDnbN12oL" >
Read more about it in the laravel documentation here https://laravel.com/docs/5.6/csrf
Regarding the expiration of the token I think you might want to handle the error this way https://gist.github.com/jrmadsen67/bd0f9ad0ef1ed6bb594e
Also, there's a package which helps the forms keep awake.
https://github.com/GeneaLabs/laravel-caffeine
I hope that helps.
Laravel 5 using Blades templates, it's easy.
Add csrf toke in your blade file
{{ csrf_token() }}
If you are using Laravel 5.6 then you need to add something like this in your code of the form
#csrf
Check in detail about: CSRF Laravel

Resources