fix(sicurezza): safeNext blocca backslash (open redirect) + guardia ownership su /admin/edit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
// Path interno sicuro per il redirect post-login: deve iniziare con "/", non essere
|
// Path interno sicuro per il redirect post-login: deve iniziare con "/", non essere
|
||||||
// protocol-relative ("//"), non puntare alle API. Tutto il resto → home.
|
// protocol-relative ("//"), non puntare alle API. Tutto il resto → home.
|
||||||
export function safeNext(next: string | null): string {
|
export function safeNext(next: string | null): string {
|
||||||
|
if (next && next.includes('\\')) return '/';
|
||||||
if (!next || !next.startsWith('/') || next.startsWith('//')) return '/';
|
if (!next || !next.startsWith('/') || next.startsWith('//')) return '/';
|
||||||
if (next.startsWith('/api/')) return '/';
|
if (next.startsWith('/api/')) return '/';
|
||||||
return next;
|
return next;
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
import Admin from '../../../layouts/Admin.astro';
|
import Admin from '../../../layouts/Admin.astro';
|
||||||
import PostForm from '../../../components/admin/PostForm.astro';
|
import PostForm from '../../../components/admin/PostForm.astro';
|
||||||
import { getDb } from '../../../lib/db';
|
import { getDb } from '../../../lib/db';
|
||||||
import { getPostById } from '../../../lib/posts';
|
import { getPostById, canModifyPost } from '../../../lib/posts';
|
||||||
export const prerender = false;
|
export const prerender = false;
|
||||||
const post = getPostById(getDb(), Number(Astro.params.id));
|
const post = getPostById(getDb(), Number(Astro.params.id));
|
||||||
if (!post) return Astro.redirect('/admin');
|
if (!post) return Astro.redirect('/admin');
|
||||||
|
const u = Astro.locals.user!;
|
||||||
|
if (!canModifyPost(u.role, u.id, post)) return Astro.redirect('/admin');
|
||||||
---
|
---
|
||||||
<Admin title={`Modifica: ${post.title}`}>
|
<Admin title={`Modifica: ${post.title}`}>
|
||||||
<h1>Modifica articolo</h1>
|
<h1>Modifica articolo</h1>
|
||||||
|
|||||||
@@ -14,5 +14,7 @@ describe('safeNext', () => {
|
|||||||
expect(safeNext('/api/admin/posts')).toBe('/');
|
expect(safeNext('/api/admin/posts')).toBe('/');
|
||||||
expect(safeNext('javascript:alert(1)')).toBe('/');
|
expect(safeNext('javascript:alert(1)')).toBe('/');
|
||||||
expect(safeNext('not-a-path')).toBe('/');
|
expect(safeNext('not-a-path')).toBe('/');
|
||||||
|
expect(safeNext('/\\evil.com')).toBe('/');
|
||||||
|
expect(safeNext('/\\/evil.com')).toBe('/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user