Runner: Geruest, Eingabepruefung, Auth

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 21:53:41 +00:00
1 parent c402837df6
commit aeb08580bb
7 files changed
+296

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
// Strikte Eingabeprüfung für Runner-Jobs.
const RE_SUB = /^[a-z0-9-]{1,63}$/;
const RE_REPO = /^[\w.-]+\/[\w.-]+$/;
const RE_SHA = /^[0-9a-f]{7,40}$/;
const RE_BRANCH = /^[\w./-]{1,100}$/;
const RE_ENV = /^[A-Z_][A-Z0-9_]*$/;
const MODES = ['auto', 'build', 'dev'];
export const isValidSub = (s) => typeof s === 'string' && RE_SUB.test(s);
export function validateJob(body) {
if (!body || typeof body !== 'object' || Array.isArray(body)) return { ok: false, error: 'Ungültige Anfrage' };
const { sub, repo, sha, branch } = body;
if (!isValidSub(sub)) return { ok: false, error: 'Ungültige Subdomain' };
if (typeof repo !== 'string' || !RE_REPO.test(repo)) return { ok: false, error: 'Ungültiges Repository' };
if (typeof sha !== 'string' || !RE_SHA.test(sha)) return { ok: false, error: 'Ungültiger Commit' };
if (typeof branch !== 'string' || !RE_BRANCH.test(branch) || branch.includes('..')) return { ok: false, error: 'Ungültiger Branch' };
const mode = body.mode === undefined || body.mode === '' ? 'auto' : body.mode;
if (!MODES.includes(mode)) return { ok: false, error: 'Ungültiger Modus' };
let index;
if (body.index !== undefined && body.index !== '') {
const i = body.index;
if (typeof i !== 'string' || i.length > 200 || i.startsWith('/') || i.split(/[\\/]/).includes('..') || i.includes('\0')) {
return { ok: false, error: 'Ungültiger Startseiten-Pfad' };
}
index = i;
}
const env = {};
if (body.env !== undefined) {
if (!body.env || typeof body.env !== 'object' || Array.isArray(body.env)) return { ok: false, error: 'Ungültige Variablen' };
const names = Object.keys(body.env);
if (names.length > 30) return { ok: false, error: 'Zu viele Variablen (max. 30)' };
for (const n of names) {
const v = body.env[n];
if (!RE_ENV.test(n)) return { ok: false, error: `Ungültiger Variablenname: ${n}` };
if (typeof v !== 'string' || Buffer.byteLength(v) > 4096) return { ok: false, error: `Ungültiger Wert für ${n}` };
env[n] = v;
}
}
const job = { ...body, sub, repo, sha, branch, mode, env };
if (index !== undefined) job.index = index; else delete job.index;
return { ok: true, job };
}