增加代码安全性,防止目录穿越

main
amuliang 2023-08-05 09:09:19 +08:00
parent f4fc5321a8
commit 33bf27327c
3 changed files with 19 additions and 6 deletions

View File

@ -16,10 +16,11 @@ function mkdirsSync(dirname) {
} }
function storeResource(path, url) { function storeResource(path, url) {
path = handlePath(path);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
mkdirsSync(_path.dirname(path)); mkdirsSync(_path.dirname(path));
const writeableStream = fs.createWriteStream(path); const writeableStream = fs.createWriteStream(path);
request.get(url).pipe(writeableStream).on('close', () => { request.get({ url: url, timeout: 10000 }).pipe(writeableStream).on('close', () => {
resolve(true); resolve(true);
}); });
}); });
@ -30,6 +31,7 @@ async function storeMusic(path, url) {
} }
function storeLrc(path, content) { function storeLrc(path, content) {
path = handlePath(path);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
mkdirsSync(_path.dirname(path)); mkdirsSync(_path.dirname(path));
fs.writeFileSync(path, content, { overwrite: true }); fs.writeFileSync(path, content, { overwrite: true });
@ -45,6 +47,12 @@ function checkMusicExists(path) {
return fs.existsSync(path); return fs.existsSync(path);
} }
function handlePath(path) {
// 必须保存到downloads目录过滤关键字符防止目录穿越
if(path.indexOf('/downloads/') != 0) path = '/downloads/' + path;
return path.replace('..', '').replace(/\.+/g, '.').replace(/\/+/g, '/').replace(/\\+/g, '\\');
}
module.exports = { module.exports = {
storeMusic, storeMusic,
storeLrc, storeLrc,

View File

@ -27,7 +27,7 @@
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<div style="width:1000px;margin: 0 auto;"> <div style="width:1000px;margin: 0 auto;padding:5px;">
<div style="margin: 10px 0"> <div style="margin: 10px 0">
<label>选择搜索源:</label> <label>选择搜索源:</label>
<Checkbox-Group v-model="selected_sources" style="display: inline-block;"> <Checkbox-Group v-model="selected_sources" style="display: inline-block;">
@ -122,8 +122,7 @@
el: "#app", el: "#app",
data() { data() {
const ajax = axios.create({ const ajax = axios.create({
baseURL: 'http://musicdlr.amuliang.top:5750', baseURL: document.location.href.indexOf('localhost') >= 0 ? 'http://localhost:5750' : 'http://musicdlr.amuliang.top:5750',
//baseURL: 'http://localhost:5000',
timeout: 10000, timeout: 10000,
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
@ -151,7 +150,9 @@
computed: { computed: {
renderedStorePath() { renderedStorePath() {
let current_item = this.current_item; let current_item = this.current_item;
return this.store_path_root + this.store_path.replaceAll("{title}", current_item.title).replaceAll("{author}", current_item.author) + '.' + this.current_item.extension; let title = current_item.title.replace(/[\/\\\:]+/g, '_');
let author = current_item.author.replace(/[\/\\\:]+/g, '_');
return this.store_path_root + this.store_path.replaceAll("{title}", title).replaceAll("{author}", author) + '.' + this.current_item.extension;
} }
}, },
methods: { methods: {
@ -179,7 +180,7 @@
async searches() { async searches() {
let selected_sources = this.selected_sources.map(item => item); let selected_sources = this.selected_sources.map(item => item);
let keywords = this.keywords; let keywords = this.keywords;
if(selected_sources.length == 0 || !keywords) { if(selected_sources.length == 0 || !keywords || keywords.trim() == '') {
return; return;
} }
this.is_searching = true; this.is_searching = true;

View File

@ -1,5 +1,9 @@
#!/bin/bash #!/bin/bash
#修改dns
echo "nameserver 114.114.114.114" > /etc/resolv.conf
wait
# 拉取代码 # 拉取代码
git clone http://${REMOTE_ADDR}/amuliang/music-downloader.git /music-downloader git clone http://${REMOTE_ADDR}/amuliang/music-downloader.git /music-downloader
wait wait