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
|
||||
// protocol-relative ("//"), non puntare alle API. Tutto il resto → home.
|
||||
export function safeNext(next: string | null): string {
|
||||
if (next && next.includes('\\')) return '/';
|
||||
if (!next || !next.startsWith('/') || next.startsWith('//')) return '/';
|
||||
if (next.startsWith('/api/')) return '/';
|
||||
return next;
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
import Admin from '../../../layouts/Admin.astro';
|
||||
import PostForm from '../../../components/admin/PostForm.astro';
|
||||
import { getDb } from '../../../lib/db';
|
||||
import { getPostById } from '../../../lib/posts';
|
||||
import { getPostById, canModifyPost } from '../../../lib/posts';
|
||||
export const prerender = false;
|
||||
const post = getPostById(getDb(), Number(Astro.params.id));
|
||||
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}`}>
|
||||
<h1>Modifica articolo</h1>
|
||||
|
||||
@@ -14,5 +14,7 @@ describe('safeNext', () => {
|
||||
expect(safeNext('/api/admin/posts')).toBe('/');
|
||||
expect(safeNext('javascript:alert(1)')).toBe('/');
|
||||
expect(safeNext('not-a-path')).toBe('/');
|
||||
expect(safeNext('/\\evil.com')).toBe('/');
|
||||
expect(safeNext('/\\/evil.com')).toBe('/');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user