mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 10:27:00 -06:00
fix(security): prevent symlink traversal in asset walker, safe cert tmpdir, and atomic icon copy (#1255)
This commit is contained in:
@@ -17,12 +17,13 @@ if [[ -z "${APPLE_CERTIFICATE:-}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TMP="${RUNNER_TEMP:-${TMPDIR:-/tmp}}"
|
||||
TMP_BASE="${RUNNER_TEMP:-${TMPDIR:-/tmp}}"
|
||||
TMP="$(mktemp -d "${TMP_BASE}/figcraft-signing.XXXXXX")"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
KEYCHAIN="$TMP/figcraft-signing.keychain-db"
|
||||
CERT="$TMP/figcraft-signing.p12"
|
||||
KC_PASS="${KEYCHAIN_PASSWORD:-$(openssl rand -hex 24)}"
|
||||
|
||||
trap 'rm -f "$CERT"' EXIT
|
||||
printf '%s' "$APPLE_CERTIFICATE" | base64 --decode >"$CERT"
|
||||
security create-keychain -p "$KC_PASS" "$KEYCHAIN"
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
||||
|
||||
+6
-2
@@ -67,11 +67,15 @@ pub fn generate(root: &Path) -> bool {
|
||||
for png in &pngs {
|
||||
ico.extend_from_slice(png);
|
||||
}
|
||||
ok &= std::fs::write(dir.join("figcraft.ico"), ico).is_ok();
|
||||
let ico_path = dir.join("figcraft.ico");
|
||||
let _ = std::fs::remove_file(&ico_path);
|
||||
ok &= std::fs::write(&ico_path, ico).is_ok();
|
||||
// The lighter trace keeps the scalable theme icon cheap to render.
|
||||
let sd = dir.join("hicolor/scalable/apps");
|
||||
let _ = std::fs::create_dir_all(&sd);
|
||||
ok &= std::fs::copy(dir.join("figcraft-small.svg"), sd.join("ai.storyteller.figcraft.svg")).is_ok();
|
||||
let target = sd.join("ai.storyteller.figcraft.svg");
|
||||
let _ = std::fs::remove_file(&target);
|
||||
ok &= std::fs::copy(dir.join("figcraft-small.svg"), &target).is_ok();
|
||||
eprintln!("icon: wrote {}", dir.display());
|
||||
ok
|
||||
}
|
||||
|
||||
+3
-2
@@ -201,10 +201,11 @@ fn assets() -> bool {
|
||||
fn walk(dir: &std::path::Path, f: &mut dyn FnMut(&std::path::Path)) {
|
||||
let Ok(rd) = std::fs::read_dir(dir) else { return };
|
||||
for e in rd.flatten() {
|
||||
let Ok(ft) = e.file_type() else { continue };
|
||||
let p = e.path();
|
||||
if p.is_dir() {
|
||||
if ft.is_dir() && !ft.is_symlink() {
|
||||
walk(&p, f);
|
||||
} else {
|
||||
} else if !ft.is_dir() {
|
||||
f(&p);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user