Improve link preview validations.

This commit is contained in:
Greyson Parrelli 2026-06-10 14:16:42 +00:00 committed by Cody Henthorne
parent d447af36ba
commit fa6b512cfc
2 changed files with 60 additions and 2 deletions

View File

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.util
import com.google.common.net.InetAddresses
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.thoughtcrime.securesms.stickers.StickerUrl
import java.net.URI
@ -43,7 +44,23 @@ object LinkUtil {
return false
}
return linkUrl.toHttpUrlOrNull()?.scheme == "https"
val httpUrl = linkUrl.toHttpUrlOrNull() ?: return false
if (httpUrl.scheme != "https") {
return false
}
val host = httpUrl.host
if (host.matches(INVALID_DOMAINS_REGEX)) {
return false
}
if (isPrivateOrLocalHost(host)) {
return false
}
return true
}
/**
@ -105,5 +122,26 @@ object LinkUtil {
}
}
private fun isPrivateOrLocalHost(host: String): Boolean {
if (!InetAddresses.isInetAddress(host)) {
return false
}
val address = InetAddresses.forString(host)
if (address.isAnyLocalAddress ||
address.isLoopbackAddress ||
address.isLinkLocalAddress ||
address.isSiteLocalAddress ||
address.isMulticastAddress
) {
return true
}
// IPv6 unique local addresses (fc00::/7) are not covered by the standard helpers above.
val bytes = address.address
return bytes.size == 16 && (bytes[0].toInt() and 0xfe) == 0xfc
}
private data class LegalCharactersResult(val isLegal: Boolean, val domain: String? = null)
}

View File

@ -52,7 +52,27 @@ class LinkUtilTest_isValidPreviewUrl(private val input: String, private val outp
arrayOf("https://cool.invalid.com", true),
arrayOf("https://cool.localhost.signal.org", true),
arrayOf("https://cool.test.blarg.gov", true),
arrayOf("https://github.com/signalapp/Signal-Android/compare/v6.23.2...v6.23.3", true)
arrayOf("https://github.com/signalapp/Signal-Android/compare/v6.23.2...v6.23.3", true),
arrayOf("https://x@localhost/", false),
arrayOf("https://x@localhost", false),
arrayOf("https://user:pass@localhost/", false),
arrayOf("https://user@foo.google.com/", true),
arrayOf("https://127.0.0.1", false),
arrayOf("https://127.0.0.1/some/path", false),
arrayOf("https://127.1.2.3", false),
arrayOf("https://[::1]/", false),
arrayOf("https://x@127.0.0.1/", false),
arrayOf("https://0.0.0.0", false),
arrayOf("https://10.0.0.1", false),
arrayOf("https://172.16.0.1", false),
arrayOf("https://192.168.1.1", false),
arrayOf("https://169.254.1.1", false),
arrayOf("https://169.254.169.254", false),
arrayOf("https://[fe80::1]/", false),
arrayOf("https://[fc00::1]/", false),
arrayOf("https://[fd12:3456:789a::1]/", false),
arrayOf("https://8.8.8.8", true),
arrayOf("https://[2001:4860:4860::8888]/", true)
)
}
}