registri dei piani in git (AI-OS#309)

Refs gitea:Adriano/AI-OS#310

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-06 10:36:26 +02:00
parent 9126af28ce
commit b913a2bf90
94 changed files with 40294 additions and 0 deletions
@@ -0,0 +1,66 @@
# Review package: e2bbc90..7211d74
## Commits
7211d74 fix(sicurezza): safeNext blocca backslash (open redirect) + guardia ownership su /admin/edit
## Files changed
src/lib/safe-next.ts | 1 +
src/pages/admin/edit/[id].astro | 4 +++-
tests/safe-next.test.ts | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)
## Diff
diff --git a/src/lib/safe-next.ts b/src/lib/safe-next.ts
index b9b9a6c..1c2e5b3 100644
--- a/src/lib/safe-next.ts
+++ b/src/lib/safe-next.ts
@@ -1,7 +1,8 @@
// 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;
}
diff --git a/src/pages/admin/edit/[id].astro b/src/pages/admin/edit/[id].astro
index 7789e84..a3a0858 100644
--- a/src/pages/admin/edit/[id].astro
+++ b/src/pages/admin/edit/[id].astro
@@ -1,14 +1,16 @@
---
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>
<script id="initial-body" type="text/plain" set:html={post.body_html}></script>
<PostForm post={post} />
</Admin>
diff --git a/tests/safe-next.test.ts b/tests/safe-next.test.ts
index 9435af9..c0aeafc 100644
--- a/tests/safe-next.test.ts
+++ b/tests/safe-next.test.ts
@@ -7,12 +7,14 @@ describe('safeNext', () => {
expect(safeNext('/blog/x?y=1')).toBe('/blog/x?y=1');
});
it('rifiuta esterni, protocol-relative, api e vuoti', () => {
expect(safeNext(null)).toBe('/');
expect(safeNext('')).toBe('/');
expect(safeNext('//evil.com')).toBe('/');
expect(safeNext('https://evil.com')).toBe('/');
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('/');
});
});