search console SEO ableitungen
This commit is contained in:
158
src/lib/csrf.ts
158
src/lib/csrf.ts
@@ -1,79 +1,79 @@
|
||||
import { cookies } from 'next/headers';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getCsrfCookieOptions } from './cookieConfig';
|
||||
|
||||
const CSRF_TOKEN_COOKIE = 'csrf_token';
|
||||
const CSRF_TOKEN_HEADER = 'x-csrf-token';
|
||||
|
||||
/**
|
||||
* Generate a new CSRF token and set it as a cookie
|
||||
*/
|
||||
export function generateCsrfToken(): string {
|
||||
const token = uuidv4();
|
||||
|
||||
cookies().set(CSRF_TOKEN_COOKIE, token, getCsrfCookieOptions());
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSRF token from cookies
|
||||
*/
|
||||
export function getCsrfToken(): string | undefined {
|
||||
return cookies().get(CSRF_TOKEN_COOKIE)?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate CSRF token from request header against cookie
|
||||
*/
|
||||
export function validateCsrfToken(headerToken: string | null): boolean {
|
||||
if (!headerToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const cookieToken = getCsrfToken();
|
||||
|
||||
if (!cookieToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constant-time comparison to prevent timing attacks
|
||||
return cookieToken === headerToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF Protection middleware for API routes
|
||||
*/
|
||||
export function csrfProtection(request: Request): { valid: boolean; error?: string } {
|
||||
const method = request.method;
|
||||
|
||||
// Only protect state-changing methods
|
||||
if (['GET', 'HEAD', 'OPTIONS'].includes(method)) {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
const headerToken = request.headers.get(CSRF_TOKEN_HEADER);
|
||||
|
||||
if (!validateCsrfToken(headerToken)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid or missing CSRF token'
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSRF token for client-side use
|
||||
* This should be called from a GET endpoint
|
||||
*/
|
||||
export function getOrCreateCsrfToken(): string {
|
||||
let token = getCsrfToken();
|
||||
|
||||
if (!token) {
|
||||
token = generateCsrfToken();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
import { cookies } from 'next/headers';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getCsrfCookieOptions } from './cookieConfig';
|
||||
|
||||
const CSRF_TOKEN_COOKIE = 'csrf_token';
|
||||
const CSRF_TOKEN_HEADER = 'x-csrf-token';
|
||||
|
||||
/**
|
||||
* Generate a new CSRF token and set it as a cookie
|
||||
*/
|
||||
export function generateCsrfToken(): string {
|
||||
const token = uuidv4();
|
||||
|
||||
cookies().set(CSRF_TOKEN_COOKIE, token, getCsrfCookieOptions());
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSRF token from cookies
|
||||
*/
|
||||
export function getCsrfToken(): string | undefined {
|
||||
return cookies().get(CSRF_TOKEN_COOKIE)?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate CSRF token from request header against cookie
|
||||
*/
|
||||
export function validateCsrfToken(headerToken: string | null): boolean {
|
||||
if (!headerToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const cookieToken = getCsrfToken();
|
||||
|
||||
if (!cookieToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constant-time comparison to prevent timing attacks
|
||||
return cookieToken === headerToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF Protection middleware for API routes
|
||||
*/
|
||||
export function csrfProtection(request: Request): { valid: boolean; error?: string } {
|
||||
const method = request.method;
|
||||
|
||||
// Only protect state-changing methods
|
||||
if (['GET', 'HEAD', 'OPTIONS'].includes(method)) {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
const headerToken = request.headers.get(CSRF_TOKEN_HEADER);
|
||||
|
||||
if (!validateCsrfToken(headerToken)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid or missing CSRF token'
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSRF token for client-side use
|
||||
* This should be called from a GET endpoint
|
||||
*/
|
||||
export function getOrCreateCsrfToken(): string {
|
||||
let token = getCsrfToken();
|
||||
|
||||
if (!token) {
|
||||
token = generateCsrfToken();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user