From 042416ed379b63cf9522c1982303876bd22dc6a7 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 19 Jan 2023 14:17:56 +0200 Subject: [PATCH 1/5] Add hotfix version to AndroidManifest --- app/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 06af5c8ab8..0426b4cf15 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="106" - android:versionName="2.53"> + android:versionName="2.53.0"> From e1dddc5959b5f509fe9d8fdd0f9169743e71ac76 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 19 Jan 2023 15:38:14 +0200 Subject: [PATCH 2/5] Automated hotfix version bump --- app/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 0426b4cf15..5213457a66 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="106" - android:versionName="2.53.0"> + android:versionName="2.53.1"> From 2a8b2eaba7a96e3ff391bb86fdaf888d4117a5fb Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 19 Jan 2023 23:00:37 +0200 Subject: [PATCH 3/5] Check entry path against destination path --- .../locales/android_translatable_strings.txt | 1 + app/src/org/commcare/tasks/UnzipTask.java | 33 +++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/assets/locales/android_translatable_strings.txt b/app/assets/locales/android_translatable_strings.txt index e319d9737d..34c1a2ffbe 100644 --- a/app/assets/locales/android_translatable_strings.txt +++ b/app/assets/locales/android_translatable_strings.txt @@ -285,6 +285,7 @@ mult.install.bad=The selected ZIP file is not valid. Please choose a valid zip f mult.install.progress.baddest=Couldn't write multimedia to the local filesystem at: ${0} mult.install.progress.badentry=There was a bad entry in the zip file: ${0} mult.install.progress.errormoving=There was a problem copying the multimedia from the zip file, please try again. +mult.install.progress.invalid.entry=The path of the entry ${0} doesn't match the parent folder, review the content of the ZIP file and try again! mult.install.prompt=From here you can install your app multimedia from a ZIP file on the local filesystem mult.install.button=Install Multimedia diff --git a/app/src/org/commcare/tasks/UnzipTask.java b/app/src/org/commcare/tasks/UnzipTask.java index a28b7563bf..127a051da0 100755 --- a/app/src/org/commcare/tasks/UnzipTask.java +++ b/app/src/org/commcare/tasks/UnzipTask.java @@ -77,38 +77,51 @@ private Integer unZipFromStream(ZipInputStream zis, String destinationPath) { int count = 0; ZipEntry entry = null; try { + String destCanonicalPath = destination.getCanonicalPath(); while ((entry = zis.getNextEntry()) != null) { publishProgress(Localization.get("mult.install.progress", new String[]{String.valueOf(count)})); count++; - Logger.log(TAG, "Unzipped entry " + entry.getName()); + File entryOutput = new File(destination, entry.getName()); + String outputCanonicalPath = entryOutput.getCanonicalPath(); + // Check if the entry path aligns with the destination folder + if (!outputCanonicalPath.startsWith(destCanonicalPath)) { + throw new SecurityException(Localization.get("mult.install.progress.invalid.entry", new String[]{entry.getName()})); + } + if (entry.isDirectory()) { - FileUtil.createFolder(new File(destination, entry.getName()).toString()); + FileUtil.createFolder(entryOutput.toString()); //If it's a directory we can move on to the next one continue; } - File outputFile = new File(destination, entry.getName()); - if (!outputFile.getParentFile().exists()) { - FileUtil.createFolder(outputFile.getParentFile().toString()); + if (!entryOutput.getParentFile().exists()) { + FileUtil.createFolder(entryOutput.getParentFile().toString()); } - if (outputFile.exists()) { + + if (entryOutput.exists()) { //Try to overwrite if we can - if (!outputFile.delete()) { + if (!entryOutput.delete()) { //If we couldn't, just skip for now continue; } } - if (!copyZipEntryToOutputFile(outputFile, zis)) { + if (!copyZipEntryToOutputFile(entryOutput, zis)) { return -1; } } - } catch (IOException e) { + } + catch (IOException e) { publishProgress(Localization.get("mult.install.progress.badentry", new String[]{entry.getName()})); return -1; - } finally { + } + catch (SecurityException e) { + publishProgress(e.getMessage()); + return -1; + } + finally { StreamsUtil.closeStream(zis); } Logger.log(TAG, "Successfully unzipped files"); From 8dcda3b0210a7567165415b44eb5296fee839d4e Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Fri, 20 Jan 2023 16:12:27 +0200 Subject: [PATCH 4/5] Update message related to potential path traversal attack --- app/assets/locales/android_translatable_strings.txt | 2 +- app/src/org/commcare/tasks/UnzipTask.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/locales/android_translatable_strings.txt b/app/assets/locales/android_translatable_strings.txt index 34c1a2ffbe..9cf3babe10 100644 --- a/app/assets/locales/android_translatable_strings.txt +++ b/app/assets/locales/android_translatable_strings.txt @@ -285,7 +285,7 @@ mult.install.bad=The selected ZIP file is not valid. Please choose a valid zip f mult.install.progress.baddest=Couldn't write multimedia to the local filesystem at: ${0} mult.install.progress.badentry=There was a bad entry in the zip file: ${0} mult.install.progress.errormoving=There was a problem copying the multimedia from the zip file, please try again. -mult.install.progress.invalid.entry=The path of the entry ${0} doesn't match the parent folder, review the content of the ZIP file and try again! +mult.install.progress.invalid.ccz=The selected CCZ file is invalid, please verify it and try again! mult.install.prompt=From here you can install your app multimedia from a ZIP file on the local filesystem mult.install.button=Install Multimedia diff --git a/app/src/org/commcare/tasks/UnzipTask.java b/app/src/org/commcare/tasks/UnzipTask.java index 127a051da0..eeb39cf09e 100755 --- a/app/src/org/commcare/tasks/UnzipTask.java +++ b/app/src/org/commcare/tasks/UnzipTask.java @@ -87,7 +87,7 @@ private Integer unZipFromStream(ZipInputStream zis, String destinationPath) { String outputCanonicalPath = entryOutput.getCanonicalPath(); // Check if the entry path aligns with the destination folder if (!outputCanonicalPath.startsWith(destCanonicalPath)) { - throw new SecurityException(Localization.get("mult.install.progress.invalid.entry", new String[]{entry.getName()})); + throw new SecurityException(Localization.get("mult.install.progress.invalid.ccz")); } if (entry.isDirectory()) { From d58180b38359a8a47202708c0fb7db92ddf82d87 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 25 Jul 2023 21:53:18 +0200 Subject: [PATCH 5/5] Set audio recorder sample rate --- app/src/org/commcare/views/widgets/RecordingFragment.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/org/commcare/views/widgets/RecordingFragment.java b/app/src/org/commcare/views/widgets/RecordingFragment.java index 017a278f15..95c11af3c2 100644 --- a/app/src/org/commcare/views/widgets/RecordingFragment.java +++ b/app/src/org/commcare/views/widgets/RecordingFragment.java @@ -52,6 +52,9 @@ public class RecordingFragment extends DialogFragment { private static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm"; + private static final int HEAAC_SAMPLE_RATE = 44100; + private static final int AMRNB_SAMPLE_RATE = 8000; + private String fileName; private static final String FILE_EXT = ".mp3"; @@ -192,10 +195,13 @@ private void setupRecorder() { recorder = new MediaRecorder(); } + boolean isHeAacSupported = isHeAacEncoderSupported(); + recorder.setAudioSource(MediaRecorder.AudioSource.MIC); + recorder.setAudioSamplingRate(isHeAacSupported ? HEAAC_SAMPLE_RATE : AMRNB_SAMPLE_RATE); recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); recorder.setOutputFile(fileName); - if (isHeAacEncoderSupported()) { + if (isHeAacSupported) { recorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC); } else { recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);