fix: use execFile to prevent shell injection, add path traversal guard
parent
c470d28f59
commit
a83c6c2b68
|
|
@ -1,7 +1,7 @@
|
||||||
const { exec, execSync } = require('child_process');
|
const { execFile, execFileSync, execSync } = require('child_process');
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const execAsync = util.promisify(exec);
|
const execFileAsync = util.promisify(execFile);
|
||||||
|
|
||||||
const SCRIPTS = {
|
const SCRIPTS = {
|
||||||
spotify_play: 'tell application "Spotify" to play',
|
spotify_play: 'tell application "Spotify" to play',
|
||||||
|
|
@ -38,7 +38,11 @@ function resolveCommand(command) {
|
||||||
return { type: 'app', name: command.slice(4) };
|
return { type: 'app', name: command.slice(4) };
|
||||||
}
|
}
|
||||||
if (command.startsWith('save:')) {
|
if (command.startsWith('save:')) {
|
||||||
|
try {
|
||||||
return { type: 'save', ...JSON.parse(command.slice(5)) };
|
return { type: 'save', ...JSON.parse(command.slice(5)) };
|
||||||
|
} catch {
|
||||||
|
return { type: 'unknown' };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { type: 'unknown' };
|
return { type: 'unknown' };
|
||||||
}
|
}
|
||||||
|
|
@ -48,18 +52,21 @@ async function executeMacCommand(command) {
|
||||||
const resolved = resolveCommand(command);
|
const resolved = resolveCommand(command);
|
||||||
|
|
||||||
if (resolved.type === 'applescript') {
|
if (resolved.type === 'applescript') {
|
||||||
const { stdout } = await execAsync(`osascript -e '${resolved.script}'`);
|
const { stdout } = await execFileAsync('osascript', ['-e', resolved.script]);
|
||||||
return { success: true, output: stdout.trim() };
|
return { success: true, output: stdout.trim() };
|
||||||
}
|
}
|
||||||
if (resolved.type === 'open') {
|
if (resolved.type === 'open') {
|
||||||
execSync(`open "${resolved.url}"`);
|
execFileSync('open', [resolved.url]);
|
||||||
return { success: true, output: 'Geöffnet' };
|
return { success: true, output: 'Geöffnet' };
|
||||||
}
|
}
|
||||||
if (resolved.type === 'app') {
|
if (resolved.type === 'app') {
|
||||||
execSync(`open -a "${resolved.name}"`);
|
execFileSync('open', ['-a', resolved.name]);
|
||||||
return { success: true, output: `${resolved.name} geöffnet` };
|
return { success: true, output: `${resolved.name} geöffnet` };
|
||||||
}
|
}
|
||||||
if (resolved.type === 'save') {
|
if (resolved.type === 'save') {
|
||||||
|
if (resolved.filename.includes('/') || resolved.filename.includes('\\')) {
|
||||||
|
return { success: false, output: 'Ungültiger Dateiname' };
|
||||||
|
}
|
||||||
const filePath = `${process.env.HOME}/Desktop/${resolved.filename}`;
|
const filePath = `${process.env.HOME}/Desktop/${resolved.filename}`;
|
||||||
fs.writeFileSync(filePath, resolved.content, 'utf8');
|
fs.writeFileSync(filePath, resolved.content, 'utf8');
|
||||||
return { success: true, output: `Gespeichert: ${filePath}` };
|
return { success: true, output: `Gespeichert: ${filePath}` };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue