diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
index 2e117103f7d65ab43db060b2f2505e00e07956bf..ad058aedc427d1f6acada18e3829b90cccbbfa82 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
@@ -94,6 +94,7 @@ import de.kuschku.quasseldroid.util.ui.DragInterceptBottomSheetBehavior
 import de.kuschku.quasseldroid.util.ui.drawable.DrawerToggleActivityDrawable
 import de.kuschku.quasseldroid.util.ui.drawable.NickCountDrawable
 import de.kuschku.quasseldroid.util.ui.view.WarningBarView
+import de.kuschku.quasseldroid.util.deceptive_networks.DeceptiveNetworkDialog
 import de.kuschku.quasseldroid.viewmodel.ChatViewModel
 import de.kuschku.quasseldroid.viewmodel.data.BufferData
 import de.kuschku.quasseldroid.viewmodel.helper.ChatViewModelHelper
@@ -765,54 +766,67 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       })
 
     binding.layoutMain.connectionStatus.setOnClickListener {
-      modelHelper.sessionManager.value?.orNull()?.apply {
-        log(INFO, "ChatActivity", "Reconnect triggered: User action")
-        backend.safeValue.orNull()?.autoConnect(ignoreErrors = true, ignoreSetting = true)
+      if (modelHelper.connectionProgress.value?.first == ConnectionState.CONNECTED
+        && modelHelper.deceptiveNetwork.value == true) {
+        DeceptiveNetworkDialog.Builder(this)
+          .message(R.raw.untrustworthy_network_freenode)
+          .show()
+      } else {
+        modelHelper.sessionManager.value?.orNull()?.apply {
+          log(INFO, "ChatActivity", "Reconnect triggered: User action")
+          backend.safeValue.orNull()?.autoConnect(ignoreErrors = true, ignoreSetting = true)
+        }
       }
     }
 
     // Show Connection Progress Bar
-    modelHelper.connectionProgress.toLiveData().observe(this, Observer {
-      val (state, progress, max) = it ?: Triple(ConnectionState.DISCONNECTED, 0, 0)
-      when (state) {
-        ConnectionState.DISCONNECTED,
-        ConnectionState.CLOSED     -> {
-          binding.layoutMain.layoutToolbar.progressBar.visibility = View.INVISIBLE
-
-          binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_ICON)
-          binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_disconnected))
-        }
-        ConnectionState.CONNECTING -> {
-          binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
-          binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = true
-
-          binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
-          binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_connecting))
-        }
-        ConnectionState.HANDSHAKE  -> {
-          binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
-          binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = true
+    combineLatest(modelHelper.connectionProgress, modelHelper.deceptiveNetwork)
+      .toLiveData().observe(this, Observer {
+        val (connection, deceptive) = it ?: Pair(Triple(ConnectionState.DISCONNECTED, 0, 0), false)
+        val (state, progress, max) = connection
+        when (state) {
+          ConnectionState.DISCONNECTED,
+          ConnectionState.CLOSED     -> {
+            binding.layoutMain.layoutToolbar.progressBar.visibility = View.INVISIBLE
+
+            binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_ICON)
+            binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_disconnected))
+          }
+          ConnectionState.CONNECTING -> {
+            binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
+            binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = true
 
-          binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
-          binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_handshake))
-        }
-        ConnectionState.INIT       -> {
-          binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
-          // Show indeterminate when no progress has been made yet
-          binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = progress == 0 || max == 0
-          binding.layoutMain.layoutToolbar.progressBar.progress = progress
-          binding.layoutMain.layoutToolbar.progressBar.max = max
-
-          binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
-          binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_init))
-        }
-        ConnectionState.CONNECTED  -> {
-          binding.layoutMain.layoutToolbar.progressBar.visibility = View.INVISIBLE
+            binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
+            binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_connecting))
+          }
+          ConnectionState.HANDSHAKE  -> {
+            binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
+            binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = true
 
-          binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_NONE)
+            binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
+            binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_handshake))
+          }
+          ConnectionState.INIT       -> {
+            binding.layoutMain.layoutToolbar.progressBar.visibility = View.VISIBLE
+            // Show indeterminate when no progress has been made yet
+            binding.layoutMain.layoutToolbar.progressBar.isIndeterminate = progress == 0 || max == 0
+            binding.layoutMain.layoutToolbar.progressBar.progress = progress
+            binding.layoutMain.layoutToolbar.progressBar.max = max
+
+            binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_PROGRESS)
+            binding.layoutMain.connectionStatus.setText(getString(R.string.label_status_init))
+          }
+          ConnectionState.CONNECTED  -> {
+            binding.layoutMain.layoutToolbar.progressBar.visibility = View.INVISIBLE
+            if (deceptive) {
+              binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_ICON)
+              binding.layoutMain.connectionStatus.setText(R.string.deceptive_network)
+            } else {
+              binding.layoutMain.connectionStatus.setMode(WarningBarView.MODE_NONE)
+            }
+          }
         }
-      }
-    })
+      })
 
     // Only show nick list when we’re in a channel bufferId
     modelHelper.bufferDataThrottled.toLiveData().observe(this, Observer {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt b/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2acf8d935c686f369a04f345d062628f3afcc0b5
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt
@@ -0,0 +1,91 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2020 Janne Mareike Koschinski
+ * Copyright (c) 2020 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.deceptive_networks
+
+import android.annotation.SuppressLint
+import android.app.Dialog
+import android.os.Bundle
+import android.text.Html
+import android.widget.TextView
+import androidx.annotation.RawRes
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentManager
+import butterknife.BindView
+import butterknife.ButterKnife
+import com.afollestad.materialdialogs.MaterialDialog
+import de.kuschku.quasseldroid.R
+
+class DeceptiveNetworkDialog : DialogFragment() {
+  private var builder: Builder? = null
+
+  @BindView(R.id.message)
+  lateinit var message: TextView
+
+  @SuppressLint("StringFormatInvalid")
+  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+    val dialog = MaterialDialog.Builder(requireContext())
+      .customView(R.layout.dialog_deceptive_network, true)
+      .title(R.string.deceptive_network)
+      .build()
+    ButterKnife.bind(this, dialog.customView!!)
+    builder?.message?.let {
+      message.text = Html.fromHtml(
+        resources.openRawResource(it).bufferedReader(Charsets.UTF_8).readText()
+      )
+    }
+    return dialog
+  }
+
+  fun show(context: FragmentActivity) = show(context.supportFragmentManager)
+  fun show(context: FragmentManager) {
+    dismissIfNecessary(context)
+    show(context, TAG)
+  }
+
+  private fun dismissIfNecessary(fragmentManager: FragmentManager) {
+    fragmentManager.findFragmentByTag(tag)?.let { frag ->
+      (frag as? DialogFragment)?.dismiss()
+      fragmentManager.beginTransaction().remove(frag).commit()
+    }
+  }
+
+  class Builder(private val fragmentManager: FragmentManager) {
+    constructor(context: FragmentActivity) : this(context.supportFragmentManager)
+
+    @RawRes
+    var message: Int? = null
+
+    fun message(@RawRes message: Int?): Builder {
+      this.message = message
+      return this
+    }
+
+    fun build() = DeceptiveNetworkDialog().apply {
+      builder = this@Builder
+    }
+
+    fun show() = build().show(fragmentManager)
+  }
+
+  companion object {
+    const val TAG = "[DECEPTIVE_NETWORK]"
+  }
+}
diff --git a/app/src/main/res/layout/dialog_deceptive_network.xml b/app/src/main/res/layout/dialog_deceptive_network.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b3328bed96ea9c1cb84fff03e97b820d6dceca40
--- /dev/null
+++ b/app/src/main/res/layout/dialog_deceptive_network.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2020 Janne Mareike Koschinski
+  Copyright (c) 2020 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:tools="http://schemas.android.com/tools"
+  android:layout_width="match_parent"
+  android:layout_height="match_parent">
+
+  <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:descendantFocusability="blocksDescendants"
+    android:orientation="vertical"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
+
+    <TextView
+      android:id="@+id/message"
+      style="@style/Widget.RtlConformTextView"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="?listPreferredItemPaddingLeft"
+      android:paddingTop="8dp"
+      android:paddingEnd="?listPreferredItemPaddingRight"
+      android:paddingBottom="8dp"
+      android:textColor="?colorTextPrimary"
+      android:textSize="16sp" />
+  </LinearLayout>
+</androidx.core.widget.NestedScrollView>
diff --git a/app/src/main/res/raw/untrustworthy_network_freenode.html b/app/src/main/res/raw/untrustworthy_network_freenode.html
new file mode 100644
index 0000000000000000000000000000000000000000..a565c563b8a3ab7a3ed94699fad9c3938ec6b231
--- /dev/null
+++ b/app/src/main/res/raw/untrustworthy_network_freenode.html
@@ -0,0 +1,21 @@
+<!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2021 Janne Mareike Koschinski
+  Copyright (c) 2021 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+<p>The staff of this network has taken over several official project channels against the wishes of the channel owners.<br/>
+Those projects have mostly moved to other networks such as libera.chat.</p>
+<p>Before joining or chatting in any project channel make sure to verify that the channel you are in hasn’t moved or been taken over.</p>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cbde82b7ea3326f5f933ae838fa95d401ef8c80e..e1fae92644f7beeb768256be5c6812c2edac2559 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -187,6 +187,8 @@
   <string name="notification_channel_highlight_title">Highlights</string>
   <string name="notification_channel_old_highlight_title">Old Highlights</string>
 
+  <string name="deceptive_network">Deceptive Network detected</string>
+
   <string name="label_missing_features">Missing Features</string>
   <string name="info_missing_features" tools:ignore="StringFormatCount">Your core is missing features that are required for Quasseldroid to work correctly. You should &lt;a href="https://quassel-irc.org&gt;upgrade&lt;/a&gt; your Quassel core to %1$s or newer.</string>
 
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/safety/DeceptiveNetworkManager.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/safety/DeceptiveNetworkManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7e86ed9a7be9258e6d4019b44d600af0d725d22d
--- /dev/null
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/safety/DeceptiveNetworkManager.kt
@@ -0,0 +1,43 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.safety
+
+import android.content.Context
+import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
+import de.kuschku.libquassel.util.ExpressionMatch
+import de.kuschku.quasseldroid.viewmodel.R
+import javax.inject.Inject
+
+class DeceptiveNetworkManager @Inject constructor(context: Context) {
+  private val untrustworthyNetworks: List<String> =
+    context.resources.getStringArray(R.array.deceptive_networks).toList()
+
+  private val matcher = ExpressionMatch(
+    untrustworthyNetworks.joinToString("\n"),
+    ExpressionMatch.MatchMode.MatchMultiWildcard,
+    false
+  )
+
+  fun isDeceptive(info: INetwork.NetworkInfo): Boolean {
+    return info.serverList.any {
+      matcher.match(it.host ?: return false, false)
+    }
+  }
+}
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
index 1458f0e23700f88138c216ddaf2791ff752f4189..d9120a21af6081deddacb7d87e30c2fd6733c387 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
@@ -25,9 +25,11 @@ import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 import de.kuschku.libquassel.quassel.syncables.IrcChannel
 import de.kuschku.libquassel.quassel.syncables.IrcUser
+import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.helper.*
+import de.kuschku.quasseldroid.util.safety.DeceptiveNetworkManager
 import de.kuschku.quasseldroid.viewmodel.ChatViewModel
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import de.kuschku.quasseldroid.viewmodel.data.BufferData
@@ -38,6 +40,7 @@ import javax.inject.Inject
 
 open class ChatViewModelHelper @Inject constructor(
   val chat: ChatViewModel,
+  val deceptiveNetworkManager: DeceptiveNetworkManager,
   quassel: QuasselViewModel
 ) : QuasselViewModelHelper(quassel) {
   val bufferViewConfig = bufferViewManager.flatMapSwitchMap { manager ->
@@ -172,6 +175,11 @@ open class ChatViewModelHelper @Inject constructor(
 
   val selectedBuffer = processSelectedBuffer(bufferViewConfig, chat.selectedBufferId)
 
+  val deceptiveNetwork =
+    network.mapSwitchMap(Network::liveNetworkInfo)
+      .mapMap(deceptiveNetworkManager::isDeceptive)
+      .mapOrElse(false)
+
   fun processChatBufferList(
     filtered: Observable<Pair<Map<BufferId, Int>, Int>>
   ) = filterBufferList(
diff --git a/viewmodel/src/main/res/values/untrustworthy_networks.xml b/viewmodel/src/main/res/values/untrustworthy_networks.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d31a6f19474991f41ce2dfc50a0f6d77970c6a9e
--- /dev/null
+++ b/viewmodel/src/main/res/values/untrustworthy_networks.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2021 Janne Mareike Koschinski
+  Copyright (c) 2021 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+<resources>
+  <string-array name="deceptive_networks" translatable="false">
+    <item>*.freenode.net</item>
+  </string-array>
+</resources>