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 d552647d2..30e77857b 100644
--- a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java
+++ b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java
@@ -708,11 +708,20 @@ public class AppProvider extends FDroidProvider {
     }
 
     private AppQuerySelection queryInstalledWithKnownVulns() {
-        // Include the hash in this check because otherwise any app with any vulnerable version will
-        // get returned.
-        String selection = " antiFeature." + Schema.AntiFeatureTable.Cols.NAME + " = 'KnownVuln' AND " +
-                getApkTableName() + "." + ApkTable.Cols.HASH + " = installed." + InstalledAppTable.Cols.HASH;
-        return new AppQuerySelection(selection).requireNaturalInstalledTable().requireNatrualJoinAntiFeatures();
+        String apk = getApkTableName();
+
+        // Include the hash in this check because otherwise apps with any vulnerable version will
+        // get returned, rather than just the installed version.
+        String compareHash = apk + "." + ApkTable.Cols.HASH + " = installed." + InstalledAppTable.Cols.HASH;
+        String knownVuln = " antiFeature." + Schema.AntiFeatureTable.Cols.NAME + " = 'KnownVuln' ";
+        String notIgnored = " COALESCE(prefs." + AppPrefsTable.Cols.IGNORE_VULNERABILITIES + ", 0) = 0 ";
+
+        String selection = knownVuln + " AND " + compareHash + " AND " + notIgnored;
+
+        return new AppQuerySelection(selection)
+                .requireNaturalInstalledTable()
+                .requireNatrualJoinAntiFeatures()
+                .requireLeftJoinPrefs();
     }
 
     static AppQuerySelection queryPackageNames(String packageNames, String packageNameField) {
diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
index 8476e04ad..b9a0b1168 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
@@ -93,6 +93,9 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
     @Nullable
     private final Button actionButton;
 
+    @Nullable
+    private final Button secondaryButton;
+
     private final DisplayImageOptions displayImageOptions;
 
     @Nullable
@@ -137,11 +140,16 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
         progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
         cancelButton = (ImageButton) itemView.findViewById(R.id.cancel_button);
         actionButton = (Button) itemView.findViewById(R.id.action_button);
+        secondaryButton = (Button) itemView.findViewById(R.id.secondary_button);
 
         if (actionButton != null) {
             actionButton.setOnClickListener(onActionClicked);
         }
 
+        if (secondaryButton != null) {
+            secondaryButton.setOnClickListener(onSecondaryButtonClicked);
+        }
+
         if (cancelButton != null) {
             cancelButton.setOnClickListener(onCancelDownload);
         }
@@ -213,6 +221,15 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
             }
         }
 
+        if (secondaryButton != null) {
+            if (viewState.shouldShowSecondaryButton()) {
+                secondaryButton.setVisibility(View.VISIBLE);
+                secondaryButton.setText(viewState.getSecondaryButtonText());
+            } else {
+                secondaryButton.setVisibility(View.GONE);
+            }
+        }
+
         if (progressBar != null) {
             if (viewState.showProgress()) {
                 progressBar.setVisibility(View.VISIBLE);
@@ -392,6 +409,18 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
         }
     };
 
+    @SuppressWarnings("FieldCanBeLocal")
+    private final View.OnClickListener onSecondaryButtonClicked = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (currentApp == null) {
+                return;
+            }
+
+            onSecondaryButtonPressed(currentApp);
+        }
+    };
+
     protected void onActionButtonPressed(@NonNull App app) {
         // When the button says "Run", then launch the app.
         if (currentStatus != null && currentStatus.status == AppUpdateStatusManager.Status.Installed) {
@@ -441,6 +470,9 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
         }
     }
 
+    /** To be overridden by subclasses if desired */
+    protected void onSecondaryButtonPressed(@NonNull App app) { }
+
     @SuppressWarnings("FieldCanBeLocal")
     private final View.OnClickListener onCancelDownload = new View.OnClickListener() {
         @Override
diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemState.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemState.java
index 2a1e31fe8..2fef4de81 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemState.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemState.java
@@ -14,6 +14,7 @@ public class AppListItemState {
     private final App app;
     private CharSequence mainText = null;
     private CharSequence actionButtonText = null;
+    private CharSequence secondaryButtonText = null;
     private CharSequence statusText = null;
     private CharSequence secondaryStatusText = null;
     private int progressCurrent = -1;
@@ -34,6 +35,11 @@ public class AppListItemState {
         return this;
     }
 
+    public AppListItemState showSecondaryButton(CharSequence label) {
+        secondaryButtonText = label;
+        return this;
+    }
+
     public AppListItemState setStatusText(CharSequence text) {
         this.statusText = text;
         return this;
@@ -74,6 +80,14 @@ public class AppListItemState {
         return actionButtonText;
     }
 
+    public boolean shouldShowSecondaryButton() {
+        return secondaryButtonText != null;
+    }
+
+    public CharSequence getSecondaryButtonText() {
+        return secondaryButtonText;
+    }
+
     public boolean showProgress() {
         return progressCurrent >= 0;
     }
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
index a466ae98e..69f744aca 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
@@ -14,6 +14,8 @@ import org.fdroid.fdroid.AppUpdateStatusManager;
 import org.fdroid.fdroid.R;
 import org.fdroid.fdroid.data.Apk;
 import org.fdroid.fdroid.data.App;
+import org.fdroid.fdroid.data.AppPrefs;
+import org.fdroid.fdroid.data.AppPrefsProvider;
 import org.fdroid.fdroid.data.AppProvider;
 import org.fdroid.fdroid.installer.Installer;
 import org.fdroid.fdroid.installer.InstallerService;
@@ -39,16 +41,17 @@ public class KnownVulnAppListItemController extends AppListItemController {
 
         // TODO: Take into account signature when multi-sig stuff is merged.
         if (app.installedVersionCode < app.suggestedVersionCode) {
-            mainText = activity.getString(R.string.updates__app_with_known_vulnerability__upgrade, app.name);
+            mainText = activity.getString(R.string.updates__app_with_known_vulnerability__prompt_upgrade, app.name);
             actionButtonText = activity.getString(R.string.menu_upgrade);
         } else {
-            mainText = activity.getString(R.string.updates__app_with_known_vulnerability__uninstall, app.name);
+            mainText = activity.getString(R.string.updates__app_with_known_vulnerability__prompt_uninstall, app.name);
             actionButtonText = activity.getString(R.string.menu_uninstall);
         }
 
         return new AppListItemState(app)
                 .setMainText(mainText)
-                .showActionButton(actionButtonText);
+                .showActionButton(actionButtonText)
+                .showSecondaryButton(activity.getString(R.string.updates__app_with_known_vulnerability__ignore));
     }
 
     @Override
@@ -69,18 +72,32 @@ public class KnownVulnAppListItemController extends AppListItemController {
         }
     }
 
+    @Override
+    protected void onSecondaryButtonPressed(@NonNull App app) {
+        AppPrefs prefs = app.getPrefs(activity);
+        prefs.ignoreVulnerabilities = true;
+        AppPrefsProvider.Helper.update(activity, app, prefs);
+        refreshUpdatesList();
+    }
+
     private void unregisterUninstallReceiver() {
         LocalBroadcastManager.getInstance(activity).unregisterReceiver(installReceiver);
     }
 
+    /**
+     * Trigger the LoaderManager in UpdatesAdapter to automatically requery for the list of
+     * apps with known vulnerabilities (i.e. this app should no longer be in that list).
+     */
+    private void refreshUpdatesList() {
+        activity.getContentResolver().notifyChange(AppProvider.getInstalledWithKnownVulnsUri(), null);
+    }
+
     private final BroadcastReceiver installReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             switch (intent.getAction()) {
                 case Installer.ACTION_UNINSTALL_COMPLETE:
-                    // This will cause the LoaderManager in UpdatesAdapter to automatically requery for the list of
-                    // apps with known vulnerabilities (i.e. this app should no longer be in that list).
-                    activity.getContentResolver().notifyChange(AppProvider.getInstalledWithKnownVulnsUri(), null);
+                    refreshUpdatesList();
                     unregisterUninstallReceiver();
                     break;
 
diff --git a/app/src/main/res/layout/known_vuln_app_list_item.xml b/app/src/main/res/layout/known_vuln_app_list_item.xml
index 6420162fd..80a4ff265 100644
--- a/app/src/main/res/layout/known_vuln_app_list_item.xml
+++ b/app/src/main/res/layout/known_vuln_app_list_item.xml
@@ -63,4 +63,16 @@
         app:layout_constraintTop_toBottomOf="@+id/app_name"
         tools:text="Uninstall"/>
 
+    <Button
+        android:id="@+id/secondary_button"
+        style="@style/DetailsSecondaryButtonStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="16dp"
+        android:layout_marginRight="16dp"
+        android:layout_marginTop="8dp"
+        app:layout_constraintEnd_toStartOf="@+id/action_button"
+        app:layout_constraintTop_toBottomOf="@+id/app_name"
+        tools:text="Ignore"/>
+
 </android.support.constraint.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3ad55ce16..7503ea30f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -97,8 +97,9 @@ This often occurs with apps installed via Google Play or other sources, if they
     <string name="updates__tts__download_app">Download</string>
     <string name="updates__tts__download_updates_for_all_apps">Download all updates</string>
 
-    <string name="updates__app_with_known_vulnerability__uninstall">We found a vulnerability with %1$s. We recommend uninstalling this app immediately.</string>
-    <string name="updates__app_with_known_vulnerability__upgrade">We found a vulnerability with %1$s. We recommend upgrading to the newest version immediately.</string>
+    <string name="updates__app_with_known_vulnerability__prompt_uninstall">We found a vulnerability with %1$s. We recommend uninstalling this app immediately.</string>
+    <string name="updates__app_with_known_vulnerability__prompt_upgrade">We found a vulnerability with %1$s. We recommend upgrading to the newest version immediately.</string>
+    <string name="updates__app_with_known_vulnerability__ignore">Ignore</string>
 
     <string name="updates__hide_updateable_apps">Hide apps</string>
     <string name="updates__show_updateable_apps">Show apps</string>
diff --git a/app/src/main/res/values/styles_detail.xml b/app/src/main/res/values/styles_detail.xml
index 885879496..e6d2825da 100644
--- a/app/src/main/res/values/styles_detail.xml
+++ b/app/src/main/res/values/styles_detail.xml
@@ -24,6 +24,10 @@
         <item name="android:background">@drawable/button_secondary_background_selector</item>
     </style>
 
+    <style name="DetailsSecondaryButtonStyleSmall" parent="DetailsSecondaryButtonStyle">
+        <item name="android:padding">8dp</item>
+    </style>
+
     <style name="DetailsMoreButtonStyle">
         <item name="android:padding">5dp</item>
         <item name="android:textSize">15sp</item>
diff --git a/app/src/test/java/org/fdroid/fdroid/AntiFeaturesTest.java b/app/src/test/java/org/fdroid/fdroid/AntiFeaturesTest.java
index 622a4ab7f..2adb32ef7 100644
--- a/app/src/test/java/org/fdroid/fdroid/AntiFeaturesTest.java
+++ b/app/src/test/java/org/fdroid/fdroid/AntiFeaturesTest.java
@@ -6,6 +6,8 @@ import android.content.ContentValues;
 import org.fdroid.fdroid.data.Apk;
 import org.fdroid.fdroid.data.ApkProvider;
 import org.fdroid.fdroid.data.App;
+import org.fdroid.fdroid.data.AppPrefs;
+import org.fdroid.fdroid.data.AppPrefsProvider;
 import org.fdroid.fdroid.data.AppProvider;
 import org.fdroid.fdroid.data.FDroidProviderTest;
 import org.fdroid.fdroid.data.InstalledAppTestUtils;
@@ -107,6 +109,21 @@ public class AntiFeaturesTest extends FDroidProviderTest {
         assertEquals(0, installed.size());
     }
 
+    @Test
+    public void allVulnerableButIgnored() {
+        install(allVuln, 101);
+        List<App> installed = AppProvider.Helper.findInstalledAppsWithKnownVulns(context);
+        assertEquals(1, installed.size());
+
+        App app = installed.get(0);
+        AppPrefs prefs = app.getPrefs(context);
+        prefs.ignoreVulnerabilities = true;
+        AppPrefsProvider.Helper.update(context, app, prefs);
+
+        List<App> installedButIgnored = AppProvider.Helper.findInstalledAppsWithKnownVulns(context);
+        assertEquals(0, installedButIgnored.size());
+    }
+
     @Test
     public void antiFeaturesSaveCorrectly() {
         List<Apk> notVulnApks = ApkProvider.Helper.findByPackageName(context, notVuln.packageName);