From ef28f4947a6f5d8344884fa30fa5f8a897df5b5b Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Fri, 22 May 2026 18:15:50 +0200 Subject: [PATCH] =?UTF-8?q?fix(ios-vpn):=20blocklist.bin=20File-Protection?= =?UTF-8?q?=20=E2=80=94=20.completeUntilFirstUserAuthentication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Layer 1 (PacketTunnel-DNS-Sinkhole) blockte nichts: `startTunnel` lud 0 Hashes, obwohl `blocklist.bin` 330k Hashes hatte. Ursache: `syncBlocklist` setzte `URLFileProtection.complete` — die Datei ist damit bei GESPERRTEM Gerät unlesbar. Der PacketTunnel wird OS-getrieben (on-demand) auch während Lock-Phasen neu gestartet → `open()` schlägt fehl → 0 Hashes → Layer 1 tot bis zum nächsten App-Sync. Beweis aus den Extension-Logs: `blocklist reloaded` (Darwin-Notif nach App-Sync, Gerät entsperrt) = 329k-330k Hashes; `startTunnel → blocklist geladen` = 0 — dieselbe Datei, dieselbe Path. Fix: `.complete` → `.completeUntilFirstUserAuthentication` (blocklist.bin + webContent-Cache). Bleibt at-rest verschlüsselt (DiGA-konform), ist aber nach dem ersten Entsperren seit Boot lesbar — die korrekte Klasse für eine Datei, die eine Network-Extension 24/7 lesen muss. Co-Authored-By: Claude Opus 4.7 --- .../ios/RebreakProtectionModule.swift | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift index c33c465..17c9efc 100644 --- a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift +++ b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift @@ -735,9 +735,18 @@ public class RebreakProtectionModule: Module { let tmpURL = finalURL.appendingPathExtension("tmp") try data.write(to: tmpURL, options: .atomic) - // DiGA-Hardening + // DiGA-Hardening: Datei verschlüsselt at-rest. WICHTIG: + // `.completeUntilFirstUserAuthentication`, NICHT `.complete` — + // die PacketTunnel-Extension muss `blocklist.bin` auch bei + // GESPERRTEM Gerät lesen können. `startTunnel` läuft OS-getrieben + // (on-demand) auch während Lock-Phasen; `.complete` macht die Datei + // dann unlesbar → `HashList.load()` liefert 0 Hashes → Layer 1 + // blockt nichts, bis die App das nächste Mal synct. + // `.completeUntilFirstUserAuthentication` bleibt at-rest + // verschlüsselt, ist aber nach dem ersten Entsperren seit Boot + // lesbar — die korrekte Klasse für eine 24/7-NE-Datei. try? (tmpURL as NSURL).setResourceValue( - URLFileProtection.complete, + URLFileProtection.completeUntilFirstUserAuthentication, forKey: .fileProtectionKey ) var mut = tmpURL @@ -895,9 +904,11 @@ public class RebreakProtectionModule: Module { let tmpURL = finalURL.appendingPathExtension("tmp") try data.write(to: tmpURL, options: .atomic) - // DiGA-Hardening (gespiegelt von syncBlocklist). + // DiGA-Hardening (gespiegelt von syncBlocklist) — + // `.completeUntilFirstUserAuthentication`, damit die Datei auch aus + // Hintergrund-Kontexten bei gesperrtem Gerät lesbar bleibt. try? (tmpURL as NSURL).setResourceValue( - URLFileProtection.complete, + URLFileProtection.completeUntilFirstUserAuthentication, forKey: .fileProtectionKey ) var mut = tmpURL