diff --git a/back/api/config.ts b/back/api/config.ts index a3afb5f2f46..f91feb773c8 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -1,4 +1,3 @@ -import { getFileContentByName, getLastModifyFilePath } from '../config/util'; import { Router, Request, Response, NextFunction } from 'express'; import { Container } from 'typedi'; import { Logger } from 'winston'; diff --git a/back/api/log.ts b/back/api/log.ts index f7fcabf797d..2ddc32be5b8 100644 --- a/back/api/log.ts +++ b/back/api/log.ts @@ -1,10 +1,9 @@ import { Router, Request, Response, NextFunction } from 'express'; import { Container } from 'typedi'; import { Logger } from 'winston'; -import * as fs from 'fs'; import config from '../config'; import { getFileContentByName, readDirs, rmPath } from '../config/util'; -import { join } from 'path'; +import { join, resolve } from 'path'; import { celebrate, Joi } from 'celebrate'; const route = Router(); const blacklist = ['.tmp']; @@ -30,15 +29,19 @@ export default (app: Router) => { '/detail', async (req: Request, res: Response, next: NextFunction) => { try { - if (blacklist.includes(req.path)) { - return res.send({ code: 403, message: '暂无权限' }); - } - const filePath = join( + const finalPath = resolve( config.logPath, - (req.query.path || '') as string, - req.query.file as string, + (req.query.path as string) || '', + (req.query.file as string) || '', ); - const content = await getFileContentByName(filePath); + + if ( + blacklist.includes(req.query.path as string) || + !finalPath.startsWith(config.logPath) + ) { + return res.send({ code: 403, message: '暂无权限' }); + } + const content = await getFileContentByName(finalPath); res.send({ code: 200, data: content }); } catch (e) { return next(e); @@ -50,15 +53,18 @@ export default (app: Router) => { '/:file', async (req: Request, res: Response, next: NextFunction) => { try { - if (blacklist.includes(req.path)) { - return res.send({ code: 403, message: '暂无权限' }); - } - const filePath = join( + const finalPath = resolve( config.logPath, - (req.query.path || '') as string, - req.params.file, + (req.query.path as string) || '', + (req.params.file as string) || '', ); - const content = await getFileContentByName(filePath); + if ( + blacklist.includes(req.path) || + !finalPath.startsWith(config.logPath) + ) { + return res.send({ code: 403, message: '暂无权限' }); + } + const content = await getFileContentByName(finalPath); res.send({ code: 200, data: content }); } catch (e) { return next(e); diff --git a/back/api/script.ts b/back/api/script.ts index d321decaea0..b9a22330cb6 100644 --- a/back/api/script.ts +++ b/back/api/script.ts @@ -1,11 +1,4 @@ -import { - fileExist, - getFileContentByName, - readDirs, - getLastModifyFilePath, - readDir, - rmPath, -} from '../config/util'; +import { fileExist, readDirs, readDir, rmPath } from '../config/util'; import { Router, Request, Response, NextFunction } from 'express'; import { Container } from 'typedi'; import { Logger } from 'winston'; diff --git a/back/config/serverEnv.ts b/back/config/serverEnv.ts index 1f9d5e0d35c..1b39761cdbd 100644 --- a/back/config/serverEnv.ts +++ b/back/config/serverEnv.ts @@ -5,13 +5,13 @@ let pickedEnv: Record; function getPickedEnv() { if (pickedEnv) return pickedEnv; - const picked = pick(process.env, ['QlBaseUrl', 'DeployEnv']); + const picked = pick(process.env, ['QlBaseUrl', 'DeployEnv', 'QL_DIR']); if (picked.QlBaseUrl) { if (!picked.QlBaseUrl.startsWith('/')) { - picked.QlBaseUrl = `/${picked.QlBaseUrl}` + picked.QlBaseUrl = `/${picked.QlBaseUrl}`; } if (!picked.QlBaseUrl.endsWith('/')) { - picked.QlBaseUrl = `${picked.QlBaseUrl}/` + picked.QlBaseUrl = `${picked.QlBaseUrl}/`; } } pickedEnv = picked as Record; diff --git a/back/services/config.ts b/back/services/config.ts index 2b5a27036fe..ab002a79b6f 100644 --- a/back/services/config.ts +++ b/back/services/config.ts @@ -11,9 +11,21 @@ export default class ConfigService { public async getFile(filePath: string, res: Response) { let content = ''; - if (config.blackFileList.includes(filePath) || !filePath) { - res.send({ code: 403, message: '文件无法访问' }); + const avaliablePath = [config.rootPath, config.configPath].map((x) => + path.resolve(x, filePath), + ); + + if ( + config.blackFileList.includes(filePath) || + avaliablePath.every( + (x) => + !x.startsWith(config.scriptPath) && !x.startsWith(config.configPath), + ) || + !filePath + ) { + return res.send({ code: 403, message: '文件无法访问' }); } + if (filePath.startsWith('sample/')) { const res = await got.get( `https://gitlab.com/whyour/qinglong/-/raw/master/${filePath}`, diff --git a/back/services/script.ts b/back/services/script.ts index 084d12926c0..d75510841fe 100644 --- a/back/services/script.ts +++ b/back/services/script.ts @@ -65,11 +65,13 @@ export default class ScriptService { } public async getFile(filePath: string, fileName: string) { - let _filePath = join(config.scriptPath, filePath, fileName); - if (filePath.startsWith(config.dataPath)) { - _filePath = join(filePath, fileName); + const finalPath = path.resolve(config.scriptPath, filePath, fileName); + + if (!finalPath.startsWith(config.scriptPath)) { + return ''; } - const content = await getFileContentByName(_filePath); + + const content = await getFileContentByName(finalPath); return content; } } diff --git a/src/utils/index.ts b/src/utils/index.ts index a0becf5a1e6..09bc2f5a20c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -313,8 +313,9 @@ export function getCommandScript( ['.js', '.ts', '.sh', '.py'].some((y) => x.endsWith(y)), ); if (!scriptsPart) return; - if (scriptsPart.startsWith('/ql/data/scripts')) { - scriptsPart = scriptsPart.replace('/ql/data/scripts/', ''); + const scriptDir = `${window.__ENV__QL_DIR}/data/scripts`; + if (scriptsPart.startsWith(scriptDir)) { + scriptsPart = scriptsPart.replace(scriptDir, ''); } let p: string, s: string; diff --git a/typings.d.ts b/typings.d.ts index bdc76dfd989..69159c68dbf 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -12,4 +12,5 @@ declare module '*.svg' { interface Window { __ENV__QlBaseUrl: string; __ENV__DeployEnv: string; + __ENV__QL_DIR: string; }