fix: admin/lang: bad files were not rejected

Massimo Melina committed Mar 9, 2023 at 12:57 UTC 2f8f6034aad016f4ec617e739282567f7a899429
2 files changed +18 -9
admin/src/LangPage.ts
+9 -4
@@ -7,7 +7,7 @@ import { Alert, Box, Button } from '@mui/material'
7 import { Delete, Upload } from '@mui/icons-material'
8 import { IconBtn, readFile, selectFiles } from './misc'
9 import _ from 'lodash'
10 -import { toast } from './dialog'
10 +import { alertDialog, toast } from './dialog'
11
12 export default function LangPage() {
13 const { list, error, connecting, reload } = useApiList('get_langs', undefined, { addId: true })
@@ -68,9 +68,14 @@ export default function LangPage() {
68 const langs: any = {}
69 for (const f of list)
70 langs[f.name] = await readFile(f)
71 - await apiCall('add_langs', { langs })
72 - reload()
73 - toast("Loaded")
71 + try {
72 + await apiCall('add_langs', { langs })
73 + reload()
74 + toast("Loaded")
75 + }
76 + catch (e: any) {
77 + await alertDialog(e)
78 + }
79 }, { accept: '.json' })
80 }
81 }
src/api.lang.ts
+9 -5
@@ -4,8 +4,8 @@ import { ApiError, ApiHandlers, SendListReadable } from './apiMiddleware'
4 import _ from 'lodash'
5 import glob from 'fast-glob'
6 import { readFile, rm, writeFile } from 'fs/promises'
7 -import { dirTraversal, isValidFileName } from './util-files'
8 -import { HTTP_BAD_REQUEST, HTTP_SERVER_ERROR } from './const'
7 +import { HTTP_BAD_REQUEST, HTTP_NOT_ACCEPTABLE, HTTP_SERVER_ERROR } from './const'
8 +import { tryJson } from './misc'
9
10 const PREFIX = 'hfs-lang-'
11 const SUFFIX = '.json'
@@ -45,7 +45,11 @@ const apis: ApiHandlers = {
45 if (code.endsWith(SUFFIX)) // filename, actually
46 code = code.slice(PREFIX.length, -SUFFIX.length)
47 validateCode(code)
48 - await writeFile(code2file(code), String(content), 'utf8')
48 + const fn = code2file(code)
49 + const s = content = String(content)
50 + if (!tryJson(s))
51 + return new ApiError(HTTP_NOT_ACCEPTABLE, "bad content for file " + fn)
52 + await writeFile(fn, s, 'utf8')
53 }
54 return {}
55 }
@@ -59,6 +63,6 @@ function code2file(code: string) {
63 }
64
65 function validateCode(code: string) {
62 - if (!isValidFileName(code) || dirTraversal(code))
63 - throw new ApiError(HTTP_BAD_REQUEST, 'bad code')
66 + if (!/^(\w\w)(-\w\w)*$/.test(code))
67 + throw new ApiError(HTTP_BAD_REQUEST, 'bad code/filename')
68 }
\ No newline at end of file