fix(security): prevent symlink traversal in asset walker, safe cert tmpdir, and atomic icon copy (#1255)

This commit is contained in:
Dylan M. Taylor
2026-10-24 04:36:46 -04:00
committed by GitHub
parent fdc4f74034
commit 996bf871cd
3 changed files with 12 additions and 6 deletions
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}