diff --git a/Core/Utils/BrowserUtils.cs b/Core/Utils/BrowserUtils.cs
index 3971d0ea..dc6c1341 100644
--- a/Core/Utils/BrowserUtils.cs
+++ b/Core/Utils/BrowserUtils.cs
@@ -27,6 +27,17 @@ public static string HeaderUserAgent{
             }
         }
 
+        public static bool IsValidUrl(string url){
+            Uri uri;
+            
+            if (Uri.TryCreate(url, UriKind.Absolute, out uri)){
+                string scheme = uri.Scheme;
+                return scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp || scheme == Uri.UriSchemeMailto;
+            }
+
+            return false;
+        }
+
         public static void OpenExternalBrowser(string url){
             using(Process.Start(url)){}
         }
diff --git a/tests/Core/Utils/TestBrowserUtils.cs b/tests/Core/Utils/TestBrowserUtils.cs
index b2736a08..6f96df31 100644
--- a/tests/Core/Utils/TestBrowserUtils.cs
+++ b/tests/Core/Utils/TestBrowserUtils.cs
@@ -4,6 +4,37 @@
 namespace UnitTests.Core.Utils{
     [TestClass]
     public class TestBrowserUtils{
+        [TestMethod]
+        public void TestIsValidUrl(){
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com")); // base
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://www.google.com")); // www.
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.co.uk")); // co.uk
+            
+            Assert.IsTrue(BrowserUtils.IsValidUrl("https://google.com")); // https
+            Assert.IsTrue(BrowserUtils.IsValidUrl("ftp://google.com")); // ftp
+            Assert.IsTrue(BrowserUtils.IsValidUrl("mailto:someone@google.com")); // mailto
+
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com/")); // trailing slash
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com/?")); // trailing question mark
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com/?a=5&b=x")); // parameters
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com/#hash")); // parameters + hash
+            Assert.IsTrue(BrowserUtils.IsValidUrl("http://google.com/?a=5&b=x#hash")); // parameters + hash
+
+            foreach(string tld in new string[]{ "accountants", "blackfriday", "cancerresearch", "coffee", "cool", "foo", "travelersinsurance" }){
+                Assert.IsTrue(BrowserUtils.IsValidUrl("http://test."+tld)); // long and unusual TLDs
+            }
+
+            Assert.IsFalse(BrowserUtils.IsValidUrl("explorer")); // file
+            Assert.IsFalse(BrowserUtils.IsValidUrl("explorer.exe")); // file
+            Assert.IsFalse(BrowserUtils.IsValidUrl("://explorer.exe")); // file-sorta
+            Assert.IsFalse(BrowserUtils.IsValidUrl("file://explorer.exe")); // file-proper
+            
+            Assert.IsFalse(BrowserUtils.IsValidUrl("")); // empty
+            Assert.IsFalse(BrowserUtils.IsValidUrl("lol")); // random
+
+            Assert.IsFalse(BrowserUtils.IsValidUrl("gopher://nobody.cares")); // lmao rekt
+        }
+
         [TestMethod]
         public void TestGetFileNameFromUrl(){
             Assert.AreEqual("index.html", BrowserUtils.GetFileNameFromUrl("http://test.com/index.html"));