mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
feat: add csrf support to api & web components (#999)
This commit is contained in:
@@ -4,6 +4,7 @@ import { AuthZService } from 'nest-authz';
|
||||
|
||||
import type { UserAccount } from '@app/graphql/generated/api/types';
|
||||
import { Role } from '@app/graphql/generated/api/types';
|
||||
import { getters } from '@app/store';
|
||||
import { handleAuthError } from '@app/utils';
|
||||
|
||||
import { ApiKeyService } from './api-key.service';
|
||||
@@ -205,6 +206,10 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
public validateCsrfToken(token?: string): boolean {
|
||||
return Boolean(token) && token === getters.emhttp().var.csrfToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user object representing a session.
|
||||
* Note: Does NOT perform validation.
|
||||
|
||||
@@ -18,6 +18,9 @@ export class UserCookieStrategy extends PassportStrategy(Strategy, strategyName)
|
||||
}
|
||||
|
||||
public validate = async (req: CustomRequest): Promise<any> => {
|
||||
return this.authService.validateCookiesCasbin(req.cookies);
|
||||
return (
|
||||
this.authService.validateCsrfToken(req.headers['x-csrf-token']) &&
|
||||
this.authService.validateCookiesCasbin(req.cookies)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { FastifyRequest } from '@app/types/fastify';
|
||||
|
||||
export interface CustomRequest extends FastifyRequest {}
|
||||
export interface CustomRequest extends FastifyRequest {
|
||||
headers: FastifyRequest['headers'] & { 'x-csrf-token'?: string };
|
||||
}
|
||||
|
||||
@@ -10,5 +10,7 @@ VITE_ALLOW_CONSOLE_LOGS=true
|
||||
# For an Unraid Webgui deployment, set this to 10.
|
||||
VITE_TAILWIND_BASE_FONT_SIZE=16
|
||||
VITE_WEBGUI=http://localhost:3001
|
||||
# static override for csrf token during development.
|
||||
VITE_CSRF_TOKEN="0000000000000000"
|
||||
# Flag for mocking a user session during development via an unsecure cookie
|
||||
VITE_MOCK_USER_SESSION=true
|
||||
|
||||
@@ -20,7 +20,9 @@ const httpEndpoint = WEBGUI_GRAPHQL;
|
||||
const wsEndpoint = new URL(WEBGUI_GRAPHQL.toString().replace('http', 'ws'));
|
||||
|
||||
// const headers = { 'x-api-key': serverStore.apiKey };
|
||||
const headers = {};
|
||||
const headers = {
|
||||
'x-csrf-token': globalThis.csrf_token,
|
||||
};
|
||||
|
||||
const httpLink = createHttpLink({
|
||||
uri: httpEndpoint.toString(),
|
||||
|
||||
7
web/helpers/globals.d.ts
vendored
Normal file
7
web/helpers/globals.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var csrf_token: string;
|
||||
}
|
||||
|
||||
// an export or import statement is required to make this file a module
|
||||
export {};
|
||||
@@ -40,6 +40,11 @@ const DOCS_REGISTRATION_REPLACE_KEY = new URL('/go/changing-the-flash-device/',
|
||||
|
||||
const SUPPORT = new URL('https://unraid.net');
|
||||
|
||||
// initialize csrf_token in nuxt playground
|
||||
if (import.meta.env.VITE_CSRF_TOKEN) {
|
||||
globalThis.csrf_token = import.meta.env.VITE_CSRF_TOKEN;
|
||||
}
|
||||
|
||||
export {
|
||||
ACCOUNT,
|
||||
ACCOUNT_CALLBACK,
|
||||
|
||||
Reference in New Issue
Block a user