Token mismatch exception even after adding protected $except array - laravel-5.1

Well, this is the third that this token mismatch is making me crazy. I tried adding the tokens as suggested by others on Stack Overflow but that did not solve the problem. Then I tried removing protection from certain routes, that is not working even. I don't know what's going on.
This is how I am removing csrf protection
protected $except = ['/donate-money', 'donate-money-main', '/donate-money-main'];
I have this in the head
<meta name="csrf-token" content="{{ csrf_token() }}">
and following code before my AJAX request
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

You don't have to pass the token in the header, but in the data you sent with the ajax request.
data: {_token: token, ......}
Removing the csrf protection is bad practice and you should avoid it.

Related

How to add the CSRF token to the HTTP header using fetch API and VanillaJS

I am trying to send a POST-request to a server that is configured to use Spring Security. When submitting my request, I get a 403 error. This is issue is due to CSRF protection. When disabling CSRF in my Spring Security Configuration, the POST request works fine.
I am using the fetch API to send my POST-request. This allows for specifying the HTTP-header that comes with the body containing my JSON-object that I am trying to POST. I am now trying to add the CSRF token to my HTTP-header. For this purpose, I have added the following two meta-tags to the head-section of my HTML:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
I have then added the following lines to my JavaScript:
const token = document.querySelector('meta[name="_csrf"]').content;
const header = document.querySelector('meta[name="_csrf_header"]').content;
let responsePromise = fetch(
"myEndpoint",
{ method: 'POST', headers: {'Content-Type': 'application/json', header: token}, body: JSON.stringify(myJSON) });
})
I am assuming that Spring Security fills out the content of my CSRF-token. So far the error message still persists though. I think there might be nothing inside my _csrf meta-tag. When logging the content (token and header), I just receive:
${_csrf.headerName}
${_csrf.token}
While I am expecting to see the header name "X-CSRF-Token" and the actual token. So could it be that Spring security does not automatically fill out this content?
======= Update:
My project is a Maven project. I have added the Thymeleaf-dependency to my pom.xml. I don't know much about thymeleaf, but it seemed to be the easiest way to implement the Login mechanism with Spring Security. Anyways, when replacing content with th:content in my meta-tags, the header and the token are actually found and will be logged in my console. I am still not able to POST my request though, the 403 remains.
Add 'th' before the attribute for thymeleaf processing
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

How to get CSRF tokens in a React/Rails App? ActionController::InvalidAuthenticityToken

Before going into more detail about the title, I just want to describe the problem at a basic level. I'm getting the dreaded 422, Unprocessable Entity error (ActionController::InvalidAuthenticityToken) after asynchronous requests in my app. What's the best way to handle this?
Loads of answers will say do:
skip_before_action :verify_authenticity_token
(which is now skip_forgery_protection in Rails 6), and then usually in the comments people get way more upvotes asking about whether or not that's a security risk. There are probably 5 threads like that.
The alternatives to doing this though, is sending the csrf token along with the POST request. So, most answers say make sure to include these headers
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
and also a csrf token like:
'X-CSRF-Token': csrfToken
The issue is getting the csrf token itself. I've tried displaying the contents of the header object with
const getHeaders = () => {
let headers = new window.Headers({
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
})
const csrfToken = document.head.querySelector("[name='csrf-token']")
if (csrfToken) { headers.append('X-CSRF-Token', csrfToken) }
return headers
}
and
let headers = getHeaders();
headers.forEach(function(value, name) {
console.log(name + ": " + value);
});
and that doesn't work. I'm guessing however I'm actually getting the token isn't working. Namely:
document.head.querySelector("[name='csrf-token']")
What's the best way to do this with plain ol' JavaScript, no other libraries? I've tried other suggestions and methods to attempt to get the token but so far all have failed. I'm assuming this lives somewhere on my browser but where? I can see all the data in Redux dev tools so the issue is definitely just this token as opposed to sending the correct data correctly (not to mention skip_forgery_protection completely solves it).
In the mean time sadly skip_forgery_protection works perfectly fine added to my Rails controllers, as security isn't the biggest concern in this stage, but I would rather fix the token issue. Thanks!

Wikimedia CSRF Token invalid

I am using the MediaWiki Action API, where I use the OAuth2 authorization flow to obtain a access token.
For uploading a image, a CSRF Token is required. I get the token by making a post request to https://commons.wikimedia.org/w/api.php?action=query&meta=tokens&format=json with the auth code in the header. This works and I get a response containing the CSRF Token:
{
"batchcomplete": "",
"query": {
"tokens": {
"csrftoken": "516091e04d05c9ae2c7bca4727c071fb615ee122+\\"
}
}
}
I then take this token and check for its validity immediately after, making a post request to https://commons.wikimedia.org/w/api.php?action=checktoken&type=csrf&format=json with the obtained token in the body (as required per api documentation). These requests happen in less than a second between each other. However, the response always is 'invalid':
{
"checktoken": {
"result": "invalid",
"generated": "2021-10-07T12:07:20Z"
}
}
I am using Dart/Flutter btw, but I doubt thats the problem.
after a long time I finally figured it out, and the answer could not be more simple:
The checktoken action still requires a oAuth 2 access token in the header. With this included, everything works as it should. I hope this at least helps someone else.

security safe to disable csrf tokens for json rails calls?

I have an existing rails backend website which makes json calls to server. Now,I am developing a mobile iOS app to use the same backend and send calls in json. However, mobile requests are failing with:
WARNING: Can't verify CSRF token authenticity
Searching around stackoverflow, many suggested to disable csrf checks for json calls by using something like this:
# Or this in your application_controller.rb
def verified_request?
if request.content_type == "application/json"
true
else
super()
end
end
But my question is , I dont understand how does this prevent csrf attacks in json format? Attacker can always send a json request to our endpoint from their site. Anyone has insights into this? I couldn't find any clear answer to this.
What you are describing is very easy to exploit using Flash:
var request:URLRequest = new URLRequest("http://stackoverflow.com");
request.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/json'));
request.data = unescape('{"a":1,"b":{"c":3}}');
request.method = URLRequestMethod.POST;
navigateToURL(request, '_blank');
If you look at the CSRF prevention cheat sheet you can check the referer to make sure its from a domain you trust. If the referer is blank then it could be originating from a https url, so that should be considered a failure. Relying on Ruby's CSRF token is a stronger form a CSRF protection.
This is a fix for ajax
Get csrf_token from rails or if using something else, from meta
// js file
var csrf_token = $('meta[name=csrf-token]').attr('content');
or
//js.erb file
var csrf_token = "<%= request.session["<%= _csrf_token %>"] %>";
then add this to js
$("body").bind("ajaxSend", function(elm, xhr, s){
if (s.type == "POST") {
// place lines mentioned above here
// line goes here...
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
}
});
One approach you can take is to leave on CSRF checks but disable based on a http header being present. If your json requests have a JWT token, you can do something like this in the relevant controllers.
protect_from_forgery with: :exception, unless: -> { some_auth_token.valid? }
Form submissions won't be able to set a http header and thus csrf will protect against it.
You json requests should have an Authorization header to be secure.

Required parameter is missing: grant_type

I am trying to authenticate google api in ruby. I got code parameter successfully. But I couldn't get access token using code params.i am passing following parameter to get access token
https://accounts.google.com/o/oauth2/token?code=4/HttxxNNyD8RU-emkYJufAM2&client_id=103xxxxxx-t8uaeuc4cexxxxxxxxv3ha1r50e.apps.googleusercontent.com&client_secret=xxxxxx&grant_type=authorization_code
i got following response:
An error occured connecting to the server: 400 returned.
<TITLE>Required parameter is missing: grant_type</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Required parameter is missing: grant_type</H1> <H2>Error 400</H2>
Any one help me to get accesstoken
Looks like the slash shouldn't be there in your code parameter. If needed it should be url encoded.
The format that Google shared these code keys is like the one given in the example. I do not believe your problem is because any of the credentials. I highly recommend to visit http://www.visualab.org/index.php/using-google-rest-api-for-analytics and I assure you will be fine. Also do not forget these tokens expires in 3600 seconds so have to whether reload the key approval screen for requesting new 'code' or follow the instructions in the link and understand 'refresh token' 'access token' for further lines of codes.

Resources