fixxing command injection vulnerability, need some future changes (refactor, remove proxychains4 and remove run, only drun mode for starting process)
This commit is contained in:
@@ -32,6 +32,14 @@ PanelWindow {
|
|||||||
property var allItems: []
|
property var allItems: []
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
property bool proxyMode: false
|
property bool proxyMode: false
|
||||||
|
property string proxyUrl: ""
|
||||||
|
|
||||||
|
Component.onCompleted: readProxyUrl()
|
||||||
|
|
||||||
|
function readProxyUrl() {
|
||||||
|
proxyUrlProc.command = ["cat", Cfg.Config.launcherCacheDir + "/proxy.conf"]
|
||||||
|
proxyUrlProc.running = true
|
||||||
|
}
|
||||||
|
|
||||||
// When launcherSelectFirst is true the first result is pre-selected;
|
// When launcherSelectFirst is true the first result is pre-selected;
|
||||||
// otherwise the list starts with no selection (-1).
|
// otherwise the list starts with no selection (-1).
|
||||||
@@ -77,21 +85,92 @@ PanelWindow {
|
|||||||
function readCache() {
|
function readCache() {
|
||||||
const path = Cfg.Config.launcherCacheDir + "/" + (mode === "drun" ? "drun.txt" : "run.txt")
|
const path = Cfg.Config.launcherCacheDir + "/" + (mode === "drun" ? "drun.txt" : "run.txt")
|
||||||
dataProc.rawOutput = ""
|
dataProc.rawOutput = ""
|
||||||
dataProc.command = ["bash", "-c", "cat " + path]
|
dataProc.command = ["cat", path]
|
||||||
dataProc.running = true
|
dataProc.running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shellQuote(str) {
|
||||||
|
// POSIX single-quote escaping: wrap in ' and replace every ' with '\''
|
||||||
|
return "'" + str.replace(/'/g, "'\\''") + "'"
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseExec(str) {
|
||||||
|
const args = []
|
||||||
|
let current = ""
|
||||||
|
let inSingle = false
|
||||||
|
let inDouble = false
|
||||||
|
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
const ch = str[i]
|
||||||
|
|
||||||
|
if (inSingle) {
|
||||||
|
if (ch === "'") inSingle = false
|
||||||
|
else current += ch
|
||||||
|
} else if (inDouble) {
|
||||||
|
if (ch === '"') inDouble = false
|
||||||
|
else current += ch
|
||||||
|
} else if (ch === "'") {
|
||||||
|
inSingle = true
|
||||||
|
} else if (ch === '"') {
|
||||||
|
inDouble = true
|
||||||
|
} else if (/\s/.test(ch)) {
|
||||||
|
if (current.length > 0) {
|
||||||
|
args.push(current)
|
||||||
|
current = ""
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current += ch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current.length > 0) args.push(current)
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
function launch(item) {
|
function launch(item) {
|
||||||
if (!item || !item.exec) return
|
if (!item || !item.exec) return
|
||||||
|
|
||||||
const cleanExec = item.exec.replace(/%[fFuUik]/g, "").trim()
|
let cleanExec = item.exec.replace(/%[fFuUik]/g, "").trim()
|
||||||
const finalExec = root.proxyMode ? "proxychains4 " + cleanExec : cleanExec
|
|
||||||
const logPath = "/tmp/qml_launch.log"
|
const logPath = "/tmp/qml_launch.log"
|
||||||
|
|
||||||
launchProc.command = ["sh", "-c", finalExec + " > " + logPath + " 2>&1 &"]
|
const lowerExec = cleanExec.toLowerCase()
|
||||||
|
const isBrowser = lowerExec.includes("chromium") || lowerExec.includes("chrome") || lowerExec.includes("firefox")
|
||||||
|
|
||||||
|
let extraArgs = []
|
||||||
|
let envVars = []
|
||||||
|
let prefix = ""
|
||||||
|
let useProxyChains = false
|
||||||
|
|
||||||
|
if (root.proxyMode) {
|
||||||
|
if (isBrowser && root.proxyUrl) {
|
||||||
|
// Browsers: use native proxy flags instead of proxychains4
|
||||||
|
// to avoid LD_PRELOAD sandbox conflicts
|
||||||
|
if (lowerExec.includes("chromium") || lowerExec.includes("chrome")) {
|
||||||
|
extraArgs.push("--proxy-server=" + root.proxyUrl)
|
||||||
|
}
|
||||||
|
if (lowerExec.includes("firefox")) {
|
||||||
|
envVars.push("all_proxy=" + root.proxyUrl)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Non-browsers: use proxychains4 normally
|
||||||
|
useProxyChains = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const envPrefix = envVars.length > 0 ? "env " + envVars.join(" ") + " " : ""
|
||||||
|
if (useProxyChains) {
|
||||||
|
prefix = envPrefix + "/usr/bin/proxychains4 "
|
||||||
|
} else {
|
||||||
|
prefix = envPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = parseExec(cleanExec)
|
||||||
|
const fullArgs = args.concat(extraArgs)
|
||||||
|
const cmd = prefix + fullArgs.map(a => shellQuote(a)).join(" ") + " > " + shellQuote(logPath) + " 2>&1 < /dev/null &"
|
||||||
|
|
||||||
|
launchProc.command = ["sh", "-c", cmd]
|
||||||
launchProc.running = true
|
launchProc.running = true
|
||||||
|
|
||||||
console.log("Launching: " + finalExec)
|
console.log("Launching: " + prefix + cleanExec + (extraArgs.length ? " " + extraArgs.join(" ") : ""))
|
||||||
if (typeof close === "function") close()
|
if (typeof close === "function") close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +225,17 @@ PanelWindow {
|
|||||||
|
|
||||||
Process { id: launchProc }
|
Process { id: launchProc }
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: proxyUrlProc
|
||||||
|
property string rawOutput: ""
|
||||||
|
stdout: SplitParser { onRead: data => proxyUrlProc.rawOutput = data.trim() }
|
||||||
|
onRunningChanged: {
|
||||||
|
if (!running && rawOutput) {
|
||||||
|
root.proxyUrl = rawOutput
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Transparent overlay — captures clicks outside the bubble and closes the
|
// Transparent overlay — captures clicks outside the bubble and closes the
|
||||||
// launcher. Sits below clipContainer in stacking order (declared first),
|
// launcher. Sits below clipContainer in stacking order (declared first),
|
||||||
// so clicks inside the bubble still reach the bubble's own MouseAreas.
|
// so clicks inside the bubble still reach the bubble's own MouseAreas.
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ get_desktop_files() {
|
|||||||
exec=$(
|
exec=$(
|
||||||
grep -m1 '^Exec=' "$f" \
|
grep -m1 '^Exec=' "$f" \
|
||||||
| cut -d= -f2- \
|
| cut -d= -f2- \
|
||||||
| sed 's/%[fFuUik]//g' \
|
| sed 's/%[fFuUik]//g'
|
||||||
| xargs
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type=$(
|
type=$(
|
||||||
@@ -90,12 +89,31 @@ build_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extract_proxy() {
|
||||||
|
local conf="${PROXYCHAINS_CONF_FILE:-/etc/proxychains4.conf}"
|
||||||
|
[ -f "$conf" ] || conf="/etc/proxychains.conf"
|
||||||
|
[ -f "$conf" ] || return
|
||||||
|
|
||||||
|
local line
|
||||||
|
line=$(awk '/^\[ProxyList\]/{found=1; next} found && NF && !/^#/{print; exit}' "$conf")
|
||||||
|
[ -n "$line" ] || return
|
||||||
|
|
||||||
|
local ptype host port
|
||||||
|
ptype=$(echo "$line" | awk '{print $1}')
|
||||||
|
host=$(echo "$line" | awk '{print $2}')
|
||||||
|
port=$(echo "$line" | awk '{print $3}')
|
||||||
|
|
||||||
|
echo "${ptype}://${host}:${port}"
|
||||||
|
}
|
||||||
|
|
||||||
update_cache() {
|
update_cache() {
|
||||||
build_drun > "$DRUN_CACHE.tmp"
|
build_drun > "$DRUN_CACHE.tmp"
|
||||||
build_run > "$RUN_CACHE.tmp"
|
build_run > "$RUN_CACHE.tmp"
|
||||||
|
|
||||||
mv "$DRUN_CACHE.tmp" "$DRUN_CACHE"
|
mv "$DRUN_CACHE.tmp" "$DRUN_CACHE"
|
||||||
mv "$RUN_CACHE.tmp" "$RUN_CACHE"
|
mv "$RUN_CACHE.tmp" "$RUN_CACHE"
|
||||||
|
|
||||||
|
extract_proxy > "$CACHE_DIR/proxy.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user