From 9c8cc20a807a8af138e5ddaac15582f183baecc0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 2 Jan 2019 16:53:54 +0100 Subject: [PATCH 1/4] validate all data in repo push requests This should get us closer towards not having to trust the server. fdroid/fdroidclient#1588 https://stackoverflow.com/questions/5205339/regular-expression-matching-fully-qualified-class-names/5205467 --- .../org/fdroid/fdroid/RepoXMLHandler.java | 3 +- .../main/java/org/fdroid/fdroid/Utils.java | 18 ++++++++ .../fdroid/fdroid/data/RepoPushRequest.java | 26 ++++++++++- .../fdroid/updater/RepoXMLHandlerTest.java | 45 +++++++++++++++++++ 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java index 5aef95ac7..3da55ec34 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java +++ b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java @@ -344,8 +344,7 @@ public class RepoXMLHandler extends DefaultHandler { repoDescription = cleanWhiteSpace(attributes.getValue("", "description")); repoTimestamp = parseLong(attributes.getValue("", "timestamp"), 0); repoIcon = attributes.getValue("", "icon"); - } else if (RepoPushRequest.INSTALL.equals(localName) - || RepoPushRequest.UNINSTALL.equals(localName)) { + } else if (RepoPushRequest.VALID_REQUESTS.contains(localName)) { if (repo.pushRequests == Repo.PUSH_REQUEST_ACCEPT_ALWAYS) { RepoPushRequest r = new RepoPushRequest( localName, diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index e99b9cab4..110838af2 100644 --- a/app/src/main/java/org/fdroid/fdroid/Utils.java +++ b/app/src/main/java/org/fdroid/fdroid/Utils.java @@ -76,6 +76,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; public final class Utils { @@ -98,6 +99,8 @@ public final class Utils { private static DisplayImageOptions.Builder defaultDisplayImageOptionsBuilder; private static DisplayImageOptions repoAppDisplayImageOptions; + private static Pattern safePackageNamePattern; + public static final String FALLBACK_ICONS_DIR = "/icons/"; /* @@ -621,6 +624,21 @@ public final class Utils { return sb; } + /** + * This is not strict validation of the package name, this is just to make + * sure that the package name is not used as an attack vector, e.g. SQL + * Injection. + */ + public static boolean isSafePackageName(@Nullable String packageName) { + if (TextUtils.isEmpty(packageName)) { + return false; + } + if (safePackageNamePattern == null) { + safePackageNamePattern = Pattern.compile("[a-zA-Z0-9._]+"); + } + return safePackageNamePattern.matcher(packageName).matches(); + } + /** * Calculate the number of days since the given date. */ diff --git a/app/src/main/java/org/fdroid/fdroid/data/RepoPushRequest.java b/app/src/main/java/org/fdroid/fdroid/data/RepoPushRequest.java index 49082c873..7ac81ae95 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/RepoPushRequest.java +++ b/app/src/main/java/org/fdroid/fdroid/data/RepoPushRequest.java @@ -20,6 +20,10 @@ package org.fdroid.fdroid.data; import android.support.annotation.Nullable; +import org.fdroid.fdroid.Utils; + +import java.util.Arrays; +import java.util.List; /** * Represents action requests embedded in the index XML received from a repo. @@ -32,15 +36,33 @@ public class RepoPushRequest { public static final String INSTALL = "install"; public static final String UNINSTALL = "uninstall"; + public static final List VALID_REQUESTS = Arrays.asList(INSTALL, UNINSTALL); public final String request; public final String packageName; @Nullable public final Integer versionCode; + /** + * Create a new instance. {@code request} is validated against the list of + * valid install requests. {@code packageName} has a safety validation to + * make sure that only valid Android/Java Package Name characters are included. + * If validation fails, the the values are set to {@code null}, which are + * handled in {@link org.fdroid.fdroid.IndexV1Updater#processRepoPushRequests(List)} + * or {@link org.fdroid.fdroid.IndexUpdater#processRepoPushRequests(List)} + */ public RepoPushRequest(String request, String packageName, @Nullable String versionCode) { - this.request = request; - this.packageName = packageName; + if (VALID_REQUESTS.contains(request)) { + this.request = request; + } else { + this.request = null; + } + + if (Utils.isSafePackageName(packageName)) { + this.packageName = packageName; + } else { + this.packageName = null; + } Integer i; try { diff --git a/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java b/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java index 7b568c579..a0168659f 100644 --- a/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java +++ b/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java @@ -160,6 +160,51 @@ public class RepoXMLHandlerTest { assertEquals(6, repoPushRequests.size()); } + @Test + public void testPushRequestsRepoCorruption() { + RepoPushRequest repoPushRequest; + repoPushRequest = new RepoPushRequest(null, null, null); // request with no data + assertEquals(repoPushRequest.request, null); + assertEquals(repoPushRequest.packageName, null); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid", "999999999999"); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid", + String.valueOf(((long) Integer.MAX_VALUE) + 1)); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid", + String.valueOf(((long) Integer.MIN_VALUE) - 1)); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("Robert'); DROP TABLE Students; --", "org.fdroid.fdroid", null); + assertEquals(repoPushRequest.request, null); + assertEquals(repoPushRequest.packageName, "org.fdroid.fdroid"); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("install", "Robert'); DROP TABLE Students; --", "123.1.1"); + assertEquals(repoPushRequest.request, "install"); + assertEquals(repoPushRequest.packageName, null); + assertEquals(repoPushRequest.versionCode, null); + + repoPushRequest = new RepoPushRequest("install", "--", "123"); + assertEquals(repoPushRequest.request, "install"); + assertEquals(repoPushRequest.packageName, null); + assertEquals(repoPushRequest.versionCode, new Integer(123)); + + repoPushRequest = new RepoPushRequest("uninstall", "Robert'); DROP TABLE Students; --", "123"); + assertEquals(repoPushRequest.request, "uninstall"); + assertEquals(repoPushRequest.packageName, null); + assertEquals(repoPushRequest.versionCode, new Integer(123)); + + repoPushRequest = new RepoPushRequest("badrquest", "asdfasdfasdf", "123"); + assertEquals(repoPushRequest.request, null); + assertEquals(repoPushRequest.packageName, "asdfasdfasdf"); + assertEquals(repoPushRequest.versionCode, new Integer(123)); + } + @Test public void testMediumRepo() { Repo expectedRepo = new Repo(); From 26c1ef30334d41906cb6566832c9f83440f2e60d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 2 Jan 2019 17:11:10 +0100 Subject: [PATCH 2/4] move RepoXMLHandler to org.fdroid.fdroid.data This should be lumped with the classes it uses. --- .../java/org/fdroid/fdroid/installer/ApkVerifierTest.java | 2 +- app/src/main/java/org/fdroid/fdroid/IndexUpdater.java | 1 + app/src/main/java/org/fdroid/fdroid/data/Apk.java | 1 - .../java/org/fdroid/fdroid/{ => data}/RepoXMLHandler.java | 8 +++----- .../fdroid/{updater => data}/RepoXMLHandlerTest.java | 8 ++------ .../org/fdroid/fdroid/updater/IndexV1UpdaterTest.java | 1 + .../java/org/fdroid/fdroid/mock/RepoDetails.java | 2 +- 7 files changed, 9 insertions(+), 14 deletions(-) rename app/src/main/java/org/fdroid/fdroid/{ => data}/RepoXMLHandler.java (98%) rename app/src/test/java/org/fdroid/fdroid/{updater => data}/RepoXMLHandlerTest.java (99%) diff --git a/app/src/androidTest/java/org/fdroid/fdroid/installer/ApkVerifierTest.java b/app/src/androidTest/java/org/fdroid/fdroid/installer/ApkVerifierTest.java index fabd5649b..9ee53fcdf 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/installer/ApkVerifierTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/installer/ApkVerifierTest.java @@ -28,7 +28,7 @@ import android.support.test.runner.AndroidJUnit4; import android.util.Log; import org.fdroid.fdroid.AssetUtils; -import org.fdroid.fdroid.RepoXMLHandler; +import org.fdroid.fdroid.data.RepoXMLHandler; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.compat.FileCompatTest; import org.fdroid.fdroid.data.Apk; diff --git a/app/src/main/java/org/fdroid/fdroid/IndexUpdater.java b/app/src/main/java/org/fdroid/fdroid/IndexUpdater.java index b67b3e908..2b70965b4 100644 --- a/app/src/main/java/org/fdroid/fdroid/IndexUpdater.java +++ b/app/src/main/java/org/fdroid/fdroid/IndexUpdater.java @@ -38,6 +38,7 @@ import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoPersister; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.RepoPushRequest; +import org.fdroid.fdroid.data.RepoXMLHandler; import org.fdroid.fdroid.data.Schema.RepoTable; import org.fdroid.fdroid.installer.InstallManagerService; import org.fdroid.fdroid.installer.InstallerService; diff --git a/app/src/main/java/org/fdroid/fdroid/data/Apk.java b/app/src/main/java/org/fdroid/fdroid/data/Apk.java index a4aac393b..78b9e1872 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Apk.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Apk.java @@ -16,7 +16,6 @@ import android.webkit.MimeTypeMap; import com.fasterxml.jackson.annotation.JacksonInject; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import org.fdroid.fdroid.RepoXMLHandler; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.ApkTable.Cols; diff --git a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java b/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java similarity index 98% rename from app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java rename to app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java index 3da55ec34..1971da4fc 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java +++ b/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java @@ -17,15 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.fdroid.fdroid; +package org.fdroid.fdroid.data; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import org.fdroid.fdroid.data.Apk; -import org.fdroid.fdroid.data.App; -import org.fdroid.fdroid.data.Repo; -import org.fdroid.fdroid.data.RepoPushRequest; +import org.fdroid.fdroid.IndexUpdater; +import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.ApkTable; import org.xml.sax.Attributes; import org.xml.sax.SAXException; diff --git a/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java similarity index 99% rename from app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java rename to app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java index a0168659f..fa568a5a5 100644 --- a/app/src/test/java/org/fdroid/fdroid/updater/RepoXMLHandlerTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java @@ -20,17 +20,13 @@ * MA 02110-1301, USA. */ -package org.fdroid.fdroid.updater; +package org.fdroid.fdroid.data; import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.BuildConfig; -import org.fdroid.fdroid.data.Apk; -import org.fdroid.fdroid.data.App; -import org.fdroid.fdroid.data.Repo; -import org.fdroid.fdroid.data.RepoPushRequest; import org.fdroid.fdroid.mock.RepoDetails; import org.junit.Test; import org.junit.runner.RunWith; @@ -884,7 +880,7 @@ public class RepoXMLHandlerTest { } @NonNull - static RepoDetails getFromFile(ClassLoader classLoader, String indexFilename, int pushRequests) { + public static RepoDetails getFromFile(ClassLoader classLoader, String indexFilename, int pushRequests) { Log.i(TAG, "test file: " + classLoader.getResource(indexFilename)); InputStream inputStream = classLoader.getResourceAsStream(indexFilename); return RepoDetails.getFromFile(inputStream, pushRequests); diff --git a/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java b/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java index 3ea37db40..c7319b3c0 100644 --- a/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java +++ b/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java @@ -25,6 +25,7 @@ import org.fdroid.fdroid.data.InstalledAppTestUtils; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.RepoPushRequest; +import org.fdroid.fdroid.data.RepoXMLHandlerTest; import org.fdroid.fdroid.mock.RepoDetails; import org.junit.Before; import org.junit.Test; diff --git a/app/src/testShared/java/org/fdroid/fdroid/mock/RepoDetails.java b/app/src/testShared/java/org/fdroid/fdroid/mock/RepoDetails.java index 5778f482c..e17411a41 100644 --- a/app/src/testShared/java/org/fdroid/fdroid/mock/RepoDetails.java +++ b/app/src/testShared/java/org/fdroid/fdroid/mock/RepoDetails.java @@ -2,7 +2,7 @@ package org.fdroid.fdroid.mock; import android.support.annotation.NonNull; -import org.fdroid.fdroid.RepoXMLHandler; +import org.fdroid.fdroid.data.RepoXMLHandler; import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.RepoPushRequest; From 1deec1c9b3e72bfc0fe3b9f3651291b6850f8fdb Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 2 Jan 2019 17:14:34 +0100 Subject: [PATCH 3/4] sanitize all packageNames from the index This is insurance to make sure that packageNames are not abused for exploiting F-Droid. The database queries already use SQL Prepared Statements, but who know what else might be exploitable. fdroid/fdroidclient#1588 --- .../main/java/org/fdroid/fdroid/data/Apk.java | 14 ++++++ .../main/java/org/fdroid/fdroid/data/App.java | 13 ++++++ .../fdroid/fdroid/data/RepoXMLHandler.java | 11 +++-- .../fdroid/data/RepoXMLHandlerTest.java | 40 ++++++++++++++++-- .../fdroid/updater/IndexV1UpdaterTest.java | 21 +++++++++ .../simpleIndexWithCorruptedPackageName.xml | 4 ++ ...r.at_corrupt_app_package_name_index-v1.jar | Bin 0 -> 4326 bytes ...at.or.at_corrupt_package_name_index-v1.jar | Bin 0 -> 4325 bytes 8 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 app/src/test/resources/simpleIndexWithCorruptedPackageName.xml create mode 100644 app/src/test/resources/testy.at.or.at_corrupt_app_package_name_index-v1.jar create mode 100644 app/src/test/resources/testy.at.or.at_corrupt_package_name_index-v1.jar diff --git a/app/src/main/java/org/fdroid/fdroid/data/Apk.java b/app/src/main/java/org/fdroid/fdroid/data/Apk.java index 78b9e1872..66a815fff 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Apk.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Apk.java @@ -460,6 +460,20 @@ public class Apk extends ValueObject implements Comparable, Parcelable { return null; } + /** + * Set the Package Name property while ensuring it is sanitized. + */ + @JsonProperty("packageName") + @SuppressWarnings("unused") + void setPackageName(String packageName) { + if (Utils.isSafePackageName(packageName)) { + this.packageName = packageName; + } else { + throw new IllegalArgumentException("Repo index package entry includes unsafe packageName: '" + + packageName + "'"); + } + } + @JsonProperty("uses-permission") @SuppressWarnings("unused") private void setUsesPermission(Object[][] permissions) { diff --git a/app/src/main/java/org/fdroid/fdroid/data/App.java b/app/src/main/java/org/fdroid/fdroid/data/App.java index 16d56d278..b2ea39190 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/App.java +++ b/app/src/main/java/org/fdroid/fdroid/data/App.java @@ -406,6 +406,19 @@ public class App extends ValueObject implements Comparable, Parcelable { this.description = formatDescription(description); } + /** + * Set the Package Name property while ensuring it is sanitized. + */ + @JsonProperty("packageName") + void setPackageName(String packageName) { + if (Utils.isSafePackageName(packageName)) { + this.packageName = packageName; + } else { + throw new IllegalArgumentException("Repo index app entry includes unsafe packageName: '" + + packageName + "'"); + } + } + /** * Parses the {@code localized} block in the incoming index metadata, * choosing the best match in terms of locale/language while filling as diff --git a/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java b/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java index 1971da4fc..1da274f63 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java +++ b/app/src/main/java/org/fdroid/fdroid/data/RepoXMLHandler.java @@ -22,7 +22,6 @@ package org.fdroid.fdroid.data; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import org.fdroid.fdroid.IndexUpdater; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.ApkTable; import org.xml.sax.Attributes; @@ -330,8 +329,8 @@ public class RepoXMLHandler extends DefaultHandler { } @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { super.startElement(uri, localName, qName, attributes); if ("repo".equals(localName)) { @@ -353,7 +352,11 @@ public class RepoXMLHandler extends DefaultHandler { } else if ("application".equals(localName) && curapp == null) { curapp = new App(); curapp.repoId = repo.getId(); - curapp.packageName = attributes.getValue("", "id"); + try { + curapp.setPackageName(attributes.getValue("", "id")); + } catch (IllegalArgumentException e) { + throw new SAXException(e); + } // To appease the NON NULL constraint in the DB. Usually there is a description, and it // is quite difficult to get an app to _not_ have a description when using fdroidserver. diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java index fa568a5a5..e77b53bfd 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java @@ -27,12 +27,18 @@ import android.text.TextUtils; import android.util.Log; import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.BuildConfig; +import org.fdroid.fdroid.mock.MockRepo; import org.fdroid.fdroid.mock.RepoDetails; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -48,6 +54,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; @Config(constants = BuildConfig.class) @RunWith(RobolectricTestRunner.class) @@ -124,6 +131,33 @@ public class RepoXMLHandlerTest { }); } + @Test(expected = IllegalArgumentException.class) + public void testSimpleIndexWithCorruptedPackageName() throws Throwable { + Repo expectedRepo = new Repo(); + expectedRepo.name = "F-Droid"; + expectedRepo.signingCertificate = "308201ee30820157a0030201020204300d845b300d06092a864886f70d01010b0500302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e301e170d3134303432373030303633315a170d3431303931323030303633315a302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e30819f300d06092a864886f70d010101050003818d0030818902818100a439472e4b6d01141bfc94ecfe131c7c728fdda670bb14c57ca60bd1c38a8b8bc0879d22a0a2d0bc0d6fdd4cb98d1d607c2caefbe250a0bd0322aedeb365caf9b236992fac13e6675d3184a6c7c6f07f73410209e399a9da8d5d7512bbd870508eebacff8b57c3852457419434d34701ccbf692267cbc3f42f1c5d1e23762d790203010001a321301f301d0603551d0e041604140b1840691dab909746fde4bfe28207d1cae15786300d06092a864886f70d01010b05000381810062424c928ffd1b6fd419b44daafef01ca982e09341f7077fb865905087aeac882534b3bd679b51fdfb98892cef38b63131c567ed26c9d5d9163afc775ac98ad88c405d211d6187bde0b0d236381cc574ba06ef9080721a92ae5a103a7301b2c397eecc141cc850dd3e123813ebc41c59d31ddbcb6e984168280c53272f6a442b"; // NOCHECKSTYLE LineLength + expectedRepo.description = "The official repository of the F-Droid client. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitorious.org/f-droid."; // NOCHECKSTYLE LineLength + expectedRepo.timestamp = 1398733213; + + InputStream inputStream = getClass().getClassLoader() + .getResourceAsStream("simpleIndexWithCorruptedPackageName.xml"); + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + SAXParser parser = factory.newSAXParser(); + XMLReader reader = parser.getXMLReader(); + RepoDetails repoDetails = new RepoDetails(); + MockRepo mockRepo = new MockRepo(100, Repo.PUSH_REQUEST_IGNORE); + RepoXMLHandler handler = new RepoXMLHandler(mockRepo, repoDetails); + reader.setContentHandler(handler); + InputSource is = new InputSource(new BufferedInputStream(inputStream)); + try { + reader.parse(is); + } catch (org.xml.sax.SAXException e) { + throw e.getCause(); + } + fail(); + } + @Test public void testPushRequestsRepoIgnore() { Repo expectedRepo = new Repo(); @@ -188,17 +222,17 @@ public class RepoXMLHandlerTest { repoPushRequest = new RepoPushRequest("install", "--", "123"); assertEquals(repoPushRequest.request, "install"); assertEquals(repoPushRequest.packageName, null); - assertEquals(repoPushRequest.versionCode, new Integer(123)); + assertEquals(repoPushRequest.versionCode, Integer.valueOf(123)); repoPushRequest = new RepoPushRequest("uninstall", "Robert'); DROP TABLE Students; --", "123"); assertEquals(repoPushRequest.request, "uninstall"); assertEquals(repoPushRequest.packageName, null); - assertEquals(repoPushRequest.versionCode, new Integer(123)); + assertEquals(repoPushRequest.versionCode, Integer.valueOf(123)); repoPushRequest = new RepoPushRequest("badrquest", "asdfasdfasdf", "123"); assertEquals(repoPushRequest.request, null); assertEquals(repoPushRequest.packageName, "asdfasdfasdf"); - assertEquals(repoPushRequest.versionCode, new Integer(123)); + assertEquals(repoPushRequest.versionCode, Integer.valueOf(123)); } @Test diff --git a/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java b/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java index c7319b3c0..cc9d6394d 100644 --- a/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java +++ b/app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import org.apache.commons.io.IOUtils; @@ -159,6 +160,26 @@ public class IndexV1UpdaterTest extends FDroidProviderTest { getClass().getResourceAsStream("foo"); } + @Test(expected = IllegalArgumentException.class) + public void testIndexV1WithCorruptAppPackageName() throws Throwable { + try { + testBadTestyJar("testy.at.or.at_corrupt_app_package_name_index-v1.jar"); + } catch (JsonMappingException e) { + throw e.getCause(); + } + fail(); + } + + @Test(expected = IllegalArgumentException.class) + public void testIndexV1WithCorruptPackageName() throws Throwable { + try { + testBadTestyJar("testy.at.or.at_corrupt_package_name_index-v1.jar"); + } catch (JsonMappingException e) { + throw e.getCause(); + } + fail(); + } + @Test(expected = IndexUpdater.SigningException.class) public void testIndexV1WithBadTestyJarNoManifest() throws IOException, IndexUpdater.UpdateException { testBadTestyJar("testy.at.or.at_no-MANIFEST.MF_index-v1.jar"); diff --git a/app/src/test/resources/simpleIndexWithCorruptedPackageName.xml b/app/src/test/resources/simpleIndexWithCorruptedPackageName.xml new file mode 100644 index 000000000..7cd26d89f --- /dev/null +++ b/app/src/test/resources/simpleIndexWithCorruptedPackageName.xml @@ -0,0 +1,4 @@ +A local FDroid repo generated from apps installed on Android-Nexus-7-20139453Robert'); DROP TABLE Students; --2014-09-272014-09-27Firefox(installed by null)<p>(installed by null, first installed on Sat Sep 27 23:47:05 EDT 2014, last updated on Sat Sep 27 23:47:05 EDT 2014)</p>org.mozilla.firefox_2014092317.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-2013945332.0.3201409231732.0.32014092317org.mozilla.firefox_2014092317.apk4b4e642b71acfe217758bb12ae7dec7fe46027ee732f4a9775ef7a4107deb5fb20e61aee1b748061ec3b0ab1bbe5bac43083163392014-09-27RECEIVE_BOOT_COMPLETED,org.mozilla.firefox.permission.PER_ANDROID_PACKAGE,GET_ACCOUNTS,ACCESS_NETWORK_STATE,MANAGE_ACCOUNTS,USE_CREDENTIALS,AUTHENTICATE_ACCOUNTS,WRITE_SYNC_SETTINGS,WRITE_SETTINGS,READ_SYNC_STATS,READ_SYNC_SETTINGS,org.mozilla.firefox_fxaccount.permission.PER_ACCOUNT_TYPE,org.mozilla.firefox_sync.permission.PER_ACCOUNT_TYPE,ACCESS_FINE_LOCATION,INTERNET,WRITE_EXTERNAL_STORAGE,com.android.launcher.permission.INSTALL_SHORTCUT,com.android.launcher.permission.UNINSTALL_SHORTCUT,com.android.browser.permission.READ_HISTORY_BOOKMARKS,WAKE_LOCK,VIBRATE,org.mozilla.firefox.permissions.PASSWORD_PROVIDER,org.mozilla.firefox.permissions.BROWSER_PROVIDER,org.mozilla.firefox.permissions.FORMHISTORY_PROVIDER,NFC,RECORD_AUDIO,CAMERA,READ_EXTERNAL_STORAGEcom.koushikdutta.superuser2014-09-272014-09-27Superuser(installed by null)<p>(installed by null, first installed on Sat Sep 27 23:23:22 EDT 2014, last updated on Sat Sep 27 23:23:22 EDT 2014)</p>com.koushikdutta.superuser_1030.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394531.0.3.010301.0.3.01030com.koushikdutta.superuser_1030.apk8bbe1c0aa307a0c689d0b97ea5123f6d74d42bb9f91cbeaac2583b23de3a77ab9af2c721bb87900f7e386d7a3716a7a6294460282014-09-27ACCESS_SUPERUSER,RECEIVE_BOOT_COMPLETEDinfo.guardianproject.courier2014-10-032014-10-03CourierCourier is a mobile RSS news reader with<p>Courier is a mobile RSS news reader with enhanced security features, offline reading and sharing capability. +(installed by F-Droid, first installed on Fri Oct 03 09:12:04 EDT 2014, last updated on Fri Oct 03 09:12:04 EDT 2014)</p>info.guardianproject.courier_15.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394530.1.9150.1.915info.guardianproject.courier_15.apkbf6566da1f90831887f5bf5605f8d816b1f7f694969459dec599b8bc01a827d3d70ac6a02b53ebdd1354ea7af7b9ceee1648475392014-10-03INTERNET,ACCESS_NETWORK_STATE,WRITE_EXTERNAL_STORAGE,ACCESS_WIFI_STATE,BLUETOOTH,BLUETOOTH_ADMIN,VIBRATE,READ_EXTERNAL_STORAGEorg.adaway2014-09-292014-09-29AdAway(installed by F-Droid)<p>(installed by F-Droid, first installed on Mon Sep 29 08:31:13 EDT 2014, last updated on Mon Sep 29 08:31:13 EDT 2014)</p>org.adaway_50.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394532.9.1502.9.150org.adaway_50.apkc9f4fcdca5e47abecfe8bc529ba6299f242fce1d5c87e50b8a36ace82d4fc2595292cd7cf993d06d6f6741117b8400fc281687772014-09-29INTERNET,ACCESS_NETWORK_STATE,RECEIVE_BOOT_COMPLETED,WRITE_EXTERNAL_STORAGE,WAKE_LOCK,ACCESS_SUPERUSER,READ_EXTERNAL_STORAGEinfo.guardianproject.gilga2014-10-042014-10-07Gilgamesh(installed by F-Droid)<p>(installed by F-Droid, first installed on Sat Oct 04 14:59:10 EDT 2014, last updated on Tue Oct 07 09:49:14 EDT 2014)</p>info.guardianproject.gilga_2.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394530.0.222info.guardianproject.gilga_2.apk1eac2e0043977dc8f31947f19852803207205887a5f01a1cbb8a5e477b3d82a96de574cd61a684bda38ba8e895dece7c30761142014-10-04BLUETOOTH_ADMIN,BLUETOOTH,ACCESS_WIFI_STATE,CHANGE_WIFI_STATE,INTERNETcom.google.zxing.client.android2014-09-272014-09-27Barcode Scanner(installed by null)<p>(installed by null, first installed on Sat Sep 27 23:36:20 EDT 2014, last updated on Sat Sep 27 23:36:20 EDT 2014)</p>com.google.zxing.client.android_100.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394534.7.01004.7.0100com.google.zxing.client.android_100.apk62dea7cf201d2e36725ad76b1525decb58b05dd9e4a032ed084c7a6c6d38da2cc3bb49636af03e7c23a63724eb529ea9735678152014-09-27CAMERA,INTERNET,VIBRATE,FLASHLIGHT,READ_CONTACTS,com.android.browser.permission.READ_HISTORY_BOOKMARKS,WRITE_EXTERNAL_STORAGE,CHANGE_WIFI_STATE,ACCESS_WIFI_STATE,READ_EXTERNAL_STORAGEinfo.guardianproject.lildebi2014-09-282014-09-28Lil' DebiWant an easy Debian chroot running that <p>Want an easy Debian chroot running that you can trust? Install Lil’ Debi, and you can have a Debian install running with a single click of a button. It builds up a whole Debian chroot on your phone entirely using debootstrap. You choose the release, mirror, and size of the disk image, and away it goes. It could take up to an hour on a slow device, then its done. The entire package is built from source using publicly available, repeatable builds. It even validates every package using the official Debian repository keys, which are included in the app. +(installed by null, first installed on Sun Sep 28 00:39:09 EDT 2014, last updated on Sun Sep 28 00:39:09 EDT 2014)</p>info.guardianproject.lildebi_5100.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394530.5.151000.5.15100info.guardianproject.lildebi_5100.apk7af667881af6107f3fe60d6973712506dbaf83710d383eb1c312fc75dae2e46ab4964fd759edaa54e65bb476d0276880156948082014-09-28INTERNET,ACCESS_NETWORK_STATE,ACCESS_SUPERUSER,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE,WAKE_LOCK,jackpal.androidterm.permission.RUN_SCRIPTde.danoeh.antennapod2014-10-032014-10-03AntennaPod(installed by F-Droid)<p>(installed by F-Droid, first installed on Fri Oct 03 09:08:31 EDT 2014, last updated on Fri Oct 03 09:08:31 EDT 2014)</p>de.danoeh.antennapod_40.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394530.9.9.3400.9.9.340de.danoeh.antennapod_40.apkea83cb81c03bc8b6c1fb6e61e7d0915abef8ca175789a5ac5add45c12f633ebd3870fa89bfb5e13509ce5888800bc6432815685102014-10-03INTERNET,WRITE_EXTERNAL_STORAGE,WAKE_LOCK,ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,RECEIVE_BOOT_COMPLETED,READ_EXTERNAL_STORAGEinfo.guardianproject.otr.app.im2014-09-272014-09-27ChatSecure(installed by F-Droid)<p>(installed by F-Droid, first installed on Sat Sep 27 23:42:00 EDT 2014, last updated on Sat Sep 27 23:42:00 EDT 2014)</p>info.guardianproject.otr.app.im_1403000.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-2013945314.0.3140300014.0.31403000info.guardianproject.otr.app.im_1403000.apk46b0b26e2122a8bf937be259d6219ffe5bace7b2eda692b43a5f55fff2322e13a0eeebb161f946e3516945fae8a92a3e1123585292014-09-27info.guardianproject.otr.app.providers.imps.permission.READ_ONLY,info.guardianproject.otr.app.providers.imps.permission.WRITE_ONLY,WAKE_LOCK,VIBRATE,INTERNET,CHANGE_WIFI_MULTICAST_STATE,ACCESS_WIFI_STATE,ACCESS_NETWORK_STATE,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE,RECEIVE_BOOT_COMPLETED,info.guardianproject.otr.app.im.permission.IM_SERVICE,UPDATE_APP_OPS_STATS,GET_ACCOUNTS,MANAGE_ACCOUNTS,USE_CREDENTIALS,com.google.android.googleapps.permission.GOOGLE_AUTHorg.torproject.android2014-09-272014-09-27OrbotOrbot is a free proxy app that empowers <p>Orbot is a free proxy app that empowers other apps to use the internet more securely. Orbot uses Tor to encrypt your Internet traffic and then hides it by bouncing through a series of computers around the world. Tor is free software and an open network that helps you defend against a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security known as traffic analysis. +(installed by null, first installed on Sat Sep 27 23:39:38 EDT 2014, last updated on Sat Sep 27 23:39:38 EDT 2014)</p>org.torproject.android_124.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-2013945314.0.8.112414.0.8.1124org.torproject.android_124.apk74daa523cd9e85722a9190dd95f3b839d69b7457ffcb9647ca6745824f6ef66d8bd7e51b479aeba908ff46ada3305a29554834792014-09-27INTERNET,RECEIVE_BOOT_COMPLETED,ACCESS_NETWORK_STATE,ACCESS_SUPERUSER,org.torproject.android.MANAGE_TORorg.gege.caldavsyncadapter2014-10-032014-10-03CalDAV Sync Adapter(installed by F-Droid)<p>(installed by F-Droid, first installed on Fri Oct 03 09:07:38 EDT 2014, last updated on Fri Oct 03 09:07:38 EDT 2014)</p>org.gege.caldavsyncadapter_18.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394531.8.1181.8.118org.gege.caldavsyncadapter_18.apk3fba34579260dd8f4290a0f68c7526e12385901d52d81267751336e81e2f654a9767040018038872ff3f651a32969d77796278142014-10-03AUTHENTICATE_ACCOUNTS,READ_CALENDAR,WRITE_CALENDAR,INTERNETinfo.guardianproject.checkey2014-09-272014-09-27Checkey(installed by F-Droid)<p>(installed by F-Droid, first installed on Sat Sep 27 23:44:13 EDT 2014, last updated on Sat Sep 27 23:44:21 EDT 2014)</p>info.guardianproject.checkey_1.pngUnknownLocalRepo,Android-Nexus-7-20139453LocalRepo,Android-Nexus-7-201394530.110.11info.guardianproject.checkey_1.apka8e3c102d5279a3029d0eebdeda2ffdbe1f8a3493ea7dbdc31a11affc708ee57d70ac6a02b53ebdd1354ea7af7b9ceee87867982014-09-27INTERNET diff --git a/app/src/test/resources/testy.at.or.at_corrupt_app_package_name_index-v1.jar b/app/src/test/resources/testy.at.or.at_corrupt_app_package_name_index-v1.jar new file mode 100644 index 0000000000000000000000000000000000000000..44611cedefb8988a56fde734826a4ebfe0ed7881 GIT binary patch literal 4326 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 literal 0 HcmV?d00001 diff --git a/app/src/test/resources/testy.at.or.at_corrupt_package_name_index-v1.jar b/app/src/test/resources/testy.at.or.at_corrupt_package_name_index-v1.jar new file mode 100644 index 0000000000000000000000000000000000000000..a087e839774fd60cd08d1c707e8c0a0e6d3c6673 GIT binary patch literal 4325 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 literal 0 HcmV?d00001 From 7bc7fa9288f8b485f22e57ef14c4f250ae7b4056 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 2 Jan 2019 22:13:40 +0100 Subject: [PATCH 4/4] rename LoggingQuery.query() to rawQuery() to make audits easier rawQuery() is much more dangerous, so this method should have the same name as the method it is actually calling. https://f-droid.org/docs/Second_Audit_Report/#f47--fdroidclient-raw-sql-query-executions --- app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/AppProvider.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/CategoryProvider.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/LoggingQuery.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/PackageProvider.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java index d89eb0a68..00e6645fe 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java @@ -533,7 +533,7 @@ public class ApkProvider extends FDroidProvider { queryBuilder.addSelection(query); queryBuilder.addOrderBy(sortOrder); - Cursor cursor = LoggingQuery.query(db(), queryBuilder.toString(), queryBuilder.getArgs()); + Cursor cursor = LoggingQuery.rawQuery(db(), queryBuilder.toString(), queryBuilder.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java b/app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java index c4734d889..6e5c752f2 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java @@ -131,7 +131,7 @@ public class AppPrefsProvider extends FDroidProvider { query.addFields(projection); query.addOrderBy(sortOrder); - Cursor cursor = LoggingQuery.query(db(), query.toString(), query.getArgs()); + Cursor cursor = LoggingQuery.rawQuery(db(), query.toString(), query.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java index 6283ca3d2..d7188b48e 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java @@ -892,7 +892,7 @@ public class AppProvider extends FDroidProvider { query.addOrderBy(sortOrder); query.addLimit(limit); - Cursor cursor = LoggingQuery.query(db(), query.toString(), query.getArgs()); + Cursor cursor = LoggingQuery.rawQuery(db(), query.toString(), query.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/CategoryProvider.java b/app/src/main/java/org/fdroid/fdroid/data/CategoryProvider.java index a78f53b1e..db45311e0 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/CategoryProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/CategoryProvider.java @@ -211,7 +211,7 @@ public class CategoryProvider extends FDroidProvider { query.setOnlyCategoriesWithApps(); } - Cursor cursor = LoggingQuery.query(db(), query.toString(), query.getArgs()); + Cursor cursor = LoggingQuery.rawQuery(db(), query.toString(), query.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/LoggingQuery.java b/app/src/main/java/org/fdroid/fdroid/data/LoggingQuery.java index aaa1c06ab..881d1c707 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/LoggingQuery.java +++ b/app/src/main/java/org/fdroid/fdroid/data/LoggingQuery.java @@ -161,7 +161,7 @@ final class LoggingQuery { return plan; } - public static Cursor query(SQLiteDatabase db, String query, String[] queryBuilderArgs) { + public static Cursor rawQuery(SQLiteDatabase db, String query, String[] queryBuilderArgs) { return new LoggingQuery(db, query, queryBuilderArgs).rawQuery(); } diff --git a/app/src/main/java/org/fdroid/fdroid/data/PackageProvider.java b/app/src/main/java/org/fdroid/fdroid/data/PackageProvider.java index 3b4daee34..bd70850de 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/PackageProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/PackageProvider.java @@ -138,7 +138,7 @@ public class PackageProvider extends FDroidProvider { query.addFields(projection); query.addOrderBy(sortOrder); - Cursor cursor = LoggingQuery.query(db(), query.toString(), query.getArgs()); + Cursor cursor = LoggingQuery.rawQuery(db(), query.toString(), query.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; }