Seguridad y docs: fix SQLi en updatePost, middleware por segmentos exactos, cover-cache directo al upstream, JWT sin fallback hardcodeado, password sudo fuera de deploy/setup.sh; reescritura AGENTS.md y CLAUDE.md

This commit is contained in:
Renato
2026-08-04 11:13:57 +08:00
parent 5d36c635cb
commit 451518004d
12 changed files with 419 additions and 928 deletions
+24 -9
View File
@@ -145,20 +145,35 @@ export function createPost(input: PostInput): Post {
return getPostById(result.lastInsertRowid as number)!
}
export function updatePost(id: number, updates: Partial<PostInput & { published: number }>): Post | null {
// Columnas permitidas en PATCH — whitelist estricta para impedir SQLi
// por nombres de columna y el bypass de `published`/columnas internas.
const UPDATE_FIELDS = new Set([
"title",
"title_jpn",
"artist",
"parody",
"tags",
"num_pages",
"source",
"cover_url",
"url",
"summary",
"slug",
])
export function updatePost(id: number, updates: Partial<PostInput>): Post | null {
const d = getDb()
const fields: string[] = []
const values: Record<string, unknown> = { id }
for (const [k, v] of Object.entries(updates)) {
if (v !== undefined) {
if (k === "tags") {
fields.push("tags = @tags")
values.tags = JSON.stringify(v)
} else {
fields.push(`${k} = @${k}`)
values[k] = v
}
if (v === undefined || !UPDATE_FIELDS.has(k)) continue
if (k === "tags") {
fields.push("tags = @tags")
values.tags = JSON.stringify(v)
} else {
fields.push(`${k} = @${k}`)
values[k] = v
}
}