Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
For #9338 - Introduce SafeUrl to strip unwanted uri schemes
Browse files Browse the repository at this point in the history
Interested clients can overwrite "mozac_url_schemes_blocklist" with a custom
list of uri schemes that will be recursively removed from the front of the uri.
  • Loading branch information
Mugurell authored and mergify[bot] committed Jan 7, 2021
1 parent e10fb53 commit b7fbb89
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package mozilla.components.support.utils

import android.content.Context

/**
* Collection of methods used for ensuring the validity and security of URLs.
*/
object SafeUrl {
/**
* Remove recursively the schemes declared in [R.array.mozac_url_schemes_blocklist]
* from the front of [unsafeText].
*/
fun stripUnsafeUrlSchemes(context: Context, unsafeText: CharSequence?): String? {
val urlSchemesBlocklist = context.resources.getStringArray(R.array.mozac_url_schemes_blocklist)
var safeUrl = unsafeText.toString()
if (safeUrl.isEmpty()) {
return safeUrl
}

@Suppress("ControlFlowWithEmptyBody", "EmptyWhileBlock")
while (urlSchemesBlocklist.find {
if (safeUrl.startsWith(it, true)) {
safeUrl = safeUrl.replaceFirst(Regex(it, RegexOption.IGNORE_CASE), "")
true
} else {
false
}
} != null) {
}

return safeUrl
}
}
10 changes: 10 additions & 0 deletions components/support/utils/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources>
<!--
List of url schemes used by methods of SafeUrl.
-->
<string-array name="mozac_url_schemes_blocklist" />
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package mozilla.components.support.utils

import android.content.Context
import android.content.res.Resources
import androidx.test.ext.junit.runners.AndroidJUnit4
import mozilla.components.support.test.mock
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doReturn

@RunWith(AndroidJUnit4::class)
class SafeUrlTest {
@Test
fun `WHEN schemes blocklist is empty THEN stripUnsafeUrlSchemes should return the initial String`() {
val resources = mock<Resources>()
val context = mock<Context>()
doReturn(resources).`when`(context).resources
doReturn(emptyArray<String>()).`when`(resources).getStringArray(R.array.mozac_url_schemes_blocklist)

val result = SafeUrl.stripUnsafeUrlSchemes(context, "unsafeText")

assertEquals("unsafeText", result)
}

@Test
fun `WHEN schemes blocklist contains items not found in the argument THEN stripUnsafeUrlSchemes should return the initial String`() {
val resources = mock<Resources>()
val context = mock<Context>()
doReturn(resources).`when`(context).resources
doReturn(arrayOf("alien")).`when`(resources).getStringArray(R.array.mozac_url_schemes_blocklist)

val result = SafeUrl.stripUnsafeUrlSchemes(context, "thisIsAnOkText")

assertEquals("thisIsAnOkText", result)
}

@Test
fun `WHEN schemes blocklist contains items found in the argument THEN stripUnsafeUrlSchemes should recursively remove them from the front`() {
val resources = mock<Resources>()
val context = mock<Context>()
doReturn(resources).`when`(context).resources
doReturn(arrayOf("one", "two")).`when`(resources).getStringArray(R.array.mozac_url_schemes_blocklist)

val result = SafeUrl.stripUnsafeUrlSchemes(context, "two" + "one" + "one" + "two" + "safeText")
assertEquals("safeText", result)

val result2 = SafeUrl.stripUnsafeUrlSchemes(context, "one" + "two" + "one" + "two" + "safeText" + "one")
assertEquals("safeText" + "one", result2)
}
}
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/android-components/blob/master/.config.yml)

* **support-utils**:
* 🌟 Added SafeUrl#stripUnsafeUrlSchemes that can cleanup unwanted uri schemes. Interested clients can specify what these are by overwriting "mozac_url_schemes_blocklist".

* **feature-prompts**:
* 🚒 Bug fixed [issue #9229](https://github.com/mozilla-mobile/android-components/issues/9229) - Dismiss SelectLoginPrompt from the current tab when opening a new one ensuring the new one can show it's own. When returning to the previous tab users should focus a login field to see the SelectLoginPrompt again.

Expand Down

0 comments on commit b7fbb89

Please sign in to comment.