I discovered it is not a good idea to expose the CSRF token through HandleInertiaRequests middleware, as it can be used for cross site attacks. All i needed to do was change my route and sanctum handled the rest.
Mar 23, 2023
1
Level 10
Security issues when exposing CSRF token in the response
Hello, I am trying to do an axios request in my Vue component & I need to have the CSRF token for sanctum authentication of the request. Is there any security risk if I expose the X-CSRF token through HandleInertiaRequests middleware?
I am trying to implement a feature that will let the user know if the username they are typing in is available. Even with the CSRF token exposed, I am still getting a 401 response, so I really am stuck with this. So far this is the code I have. Maybe you can suggest a better way of doing it?
<script setup>
import {Link, router, useForm} from '@inertiajs/vue3';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
import AppHead from "@/Layouts/AppHead.vue";
import {reactive, toRefs, watch} from "vue";
import axios from "axios";
const form = useForm({
email: '',
username: '',
password: '',
password_confirmation: '',
terms: false,
});
const state = reactive({
checking: false,
available: false,
unavailable: false
});
watch(() => form.username, (value) => {
checkUsername();
});
const checkUsername = () => {
state.checking = true;
axios.get('/users/' + form.username + '/exists', {
withCredentials: true,
headers: {
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
})
.then(response => {
state.checking = false;
state.available = response.data.exists;
state.unavailable = !response.data.exists;
})
.catch(error => {
console.error(error);
state.checking = false;
});
};
const {checking, available, unavailable} = toRefs(state);
const submit = () => {
form.post(route('login'), {
onFinish: () => form.reset('password', 'password_confirmation'),
});
};
</script>
<template>
<AppHead title="Register">
<meta content="Register" name="description"/>
<meta name="csrf-token" :content="$page.props.csrfToken">
</AppHead>
<form @submit.prevent="submit">
<div class="m-2">
<InputLabel for="username" value="Username"/>
<div class="flex">
<TextInput
id="username"
v-model="form.username"
autocomplete="username"
autofocus
class="mt-1 block"
type="text"
/>
<InputError :message="form.errors.username" class="mt-2"/>
<span v-show="checking">Checking...</span>
<span v-show="available">Available!</span>
<span v-show="unavailable">Unavailable!</span>
</div>
</div>
<div class="mt-4 m-2">
<InputLabel for="email" value="Email"/>
<TextInput
id="email"
v-model="form.email"
autocomplete="email"
class="mt-1 block w-full"
type="email"
/>
<InputError :message="form.errors.email" class="mt-2"/>
</div>
<div class="mt-4 m-2">
<InputLabel for="password" value="Password"/>
<TextInput
id="password"
v-model="form.password"
autocomplete="new-password"
class="mt-1 block w-full"
type="password"
/>
<InputError :message="form.errors.password" class="mt-2"/>
</div>
<div class="mt-4 m-2">
<InputLabel for="password_confirmation" value="Confirm Password"/>
<TextInput
id="password_confirmation"
v-model="form.password_confirmation"
autocomplete="new-password"
class="mt-1 block w-full"
type="password"
/>
<InputError :message="form.errors.password_confirmation" class="mt-2"/>
</div>
<div class="flex items-center justify-end mt-4">
<Link :href="route('login')" class="underline text-sm text-gray-600 hover:text-gray-900">
Already registered?
</Link>
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing" class="ml-4">
Register
</PrimaryButton>
</div>
<div class="m-2 mt-4 pt-4 border-t border-gray-500">
<p class="text-center text-gray-500 text-xs">
Social Login Coming Soon here...
</p>
</div>
</form>
</template>
Level 10
Please or to participate in this conversation.