From e26507821087bf26cb6a4f3dcf0d754a7eaf04ee Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 27 Dec 2022 18:00:24 +0100 Subject: [PATCH] Secure zip --- .../app/fedilab/android/helper/ZipHelper.java | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/helper/ZipHelper.java b/app/src/main/java/app/fedilab/android/helper/ZipHelper.java index e9873b94..ffe595d8 100644 --- a/app/src/main/java/app/fedilab/android/helper/ZipHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/ZipHelper.java @@ -136,14 +136,22 @@ public class ZipHelper { f.mkdirs(); } boolean successful = true; - try (ZipInputStream zin = new ZipInputStream(new FileInputStream(fullPath + ".zip"))) { + FileInputStream fileInputStream = new FileInputStream(fullPath + ".zip"); + try (ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fileInputStream))) { ZipEntry ze; while ((ze = zin.getNextEntry()) != null) { if (!successful) { break; } - String path = fullPath + ze.getName(); - File unzipFile = new File(path); + File unzipFile = new File(fullPath, ze.getName()); + boolean sure = ensureZipPathSafety(unzipFile, fullPath); + if (!sure) { + Handler mainHandler = new Handler(Looper.getMainLooper()); + Runnable myRunnable = () -> Toasty.error(context, context.getString(R.string.toast_error), Toasty.LENGTH_SHORT).show(); + mainHandler.post(myRunnable); + + return; + } FileOutputStream out = new FileOutputStream(unzipFile, false); BufferedOutputStream fout = new BufferedOutputStream(out, BUFFER_SIZE); try { @@ -157,9 +165,9 @@ public class ZipHelper { fout.close(); } if (ze.getName().contains("settings")) { - successful = restoreSettings(context, Uri.fromFile(new File(path))); + successful = restoreSettings(context, Uri.fromFile(new File(unzipFile.getAbsolutePath()))); } else if (ze.getName().contains("database")) { - successful = importDB(context, path); + successful = importDB(context, unzipFile.getAbsolutePath()); } else { break; } @@ -183,6 +191,18 @@ public class ZipHelper { } + private static boolean ensureZipPathSafety(final File outputFile, final String destDirectory) { + String destDirCanonicalPath; + try { + destDirCanonicalPath = (new File(destDirectory)).getCanonicalPath(); + String outputFilecanonicalPath = outputFile.getCanonicalPath(); + return outputFilecanonicalPath.startsWith(destDirCanonicalPath); + } catch (IOException e) { + e.printStackTrace(); + } + return true; + } + private static String storeSettings(Context context, String suffix) { boolean res = false; ObjectOutputStream output = null;