Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-26 16:00:36 +04:00
commit ff8f9c9b18
3 changed files with 44 additions and 4 deletions

View file

@ -11,14 +11,21 @@ import java.net.URI
*/
object ExternalUrlValidator {
private val trustedHost: List<String> = listOf("tangem.com")
private val trustedHosts: Set<String> = setOf(
"tangem.com",
"www.tangem.com",
"buy.tangem.com",
"app.tangem.com",
"tangem.surveysparrow.com",
"feedback.tangem.com",
)
/** Check if [externalUri] is trusted */
fun isUriTrusted(externalUri: String): Boolean {
return try {
val uri = URI.create(externalUri)
uri.scheme == "https" && uri.host in trustedHost
uri.scheme == "https" && uri.host in trustedHosts
} catch (e: Exception) {
val exception = IllegalStateException("Failed to validate URI: $externalUri", e)

View file

@ -23,11 +23,32 @@ class ExternalUrlValidatorTest(private val model: Model) {
@JvmStatic
@Parameterized.Parameters
fun data(): Collection<Model> = listOf(
// Trusted hosts — exact match
Model(url = "https://tangem.com", expected = true),
Model(url = "https://tange.com", expected = false),
Model(url = "https://tangem.com/pricing/?promocode=tgapp20ups", expected = true),
Model(url = "https://www.tangem.com", expected = true),
Model(url = "https://app.tangem.com", expected = true),
Model(url = "https://buy.tangem.com/?promocode=NEWINAPP", expected = true),
Model(url = "https://feedback.tangem.com", expected = true),
Model(url = "https://tangem.surveysparrow.com/s/tangem-pay/tt-F8XXH", expected = true),
// Subdomains not on the list
Model(url = "https://express.tangem.com/v1/", expected = false),
Model(url = "https://fake.tangem.com", expected = false),
Model(url = "https://join.tangem.com", expected = false),
// Sibling hosts on the same registrable parent
Model(url = "https://surveysparrow.com", expected = false),
Model(url = "https://fake.surveysparrow.com", expected = false),
// Suffix-injection attempts
Model(url = "https://tangem.com.attacker.com", expected = false),
Model(url = "https://faketangem.com", expected = false),
Model(url = "https://buy.tangem.com.attacker.com", expected = false),
// Wrong scheme
Model(url = "http://tangem.com", expected = false),
Model(url = "http://buy.tangem.com", expected = false),
// Typos
Model(url = "https://tange.com", expected = false),
Model(url = "http://tandem.com", expected = false),
// Garbage
Model(url = "adawdawdassdw", expected = false),
)