mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-03-28 11:39:26 +01:00
Fixes 4 high-severity findings from a comprehensive security audit: 1. Path traversal on ZIM file delete — resolve()+startsWith() containment 2. Path traversal on Map file delete — same pattern 3. Path traversal on docs read — same pattern (already used in rag_service) 4. SSRF on download endpoints — block private/internal IPs, require TLD Also adds assertNotPrivateUrl() to content update endpoints. Full audit report attached as admin/docs/security-audit-v1.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31 lines
1.0 KiB
TypeScript
31 lines
1.0 KiB
TypeScript
import { CollectionUpdateService } from '#services/collection_update_service'
|
|
import {
|
|
assertNotPrivateUrl,
|
|
applyContentUpdateValidator,
|
|
applyAllContentUpdatesValidator,
|
|
} from '#validators/common'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
|
|
export default class CollectionUpdatesController {
|
|
async checkForUpdates({}: HttpContext) {
|
|
const service = new CollectionUpdateService()
|
|
return await service.checkForUpdates()
|
|
}
|
|
|
|
async applyUpdate({ request }: HttpContext) {
|
|
const update = await request.validateUsing(applyContentUpdateValidator)
|
|
assertNotPrivateUrl(update.download_url)
|
|
const service = new CollectionUpdateService()
|
|
return await service.applyUpdate(update)
|
|
}
|
|
|
|
async applyAllUpdates({ request }: HttpContext) {
|
|
const { updates } = await request.validateUsing(applyAllContentUpdatesValidator)
|
|
for (const update of updates) {
|
|
assertNotPrivateUrl(update.download_url)
|
|
}
|
|
const service = new CollectionUpdateService()
|
|
return await service.applyAllUpdates(updates)
|
|
}
|
|
}
|