Skip to content

Commit f092a63

Browse files
committed
Add allowed URL filtering to WXClient requests
Introduces a check in WXClient to block web resource requests from unauthorized domains based on allowUrls patterns defined in the configuration. Updates WebUIConfig to support allowUrls as a list of patterns and compiles them for efficient matching.
1 parent d3f81b6 commit f092a63

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

webui/src/main/kotlin/com/dergoogler/mmrl/webui/client/WXClient.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import com.dergoogler.mmrl.webui.PathHandler
2020
import com.dergoogler.mmrl.webui.R
2121
import com.dergoogler.mmrl.webui.WXAssetLoader
2222
import com.dergoogler.mmrl.webui.component.ErrorScreen
23+
import com.dergoogler.mmrl.webui.forbiddenResponse
2324
import com.dergoogler.mmrl.webui.handler.internalPathHandler
2425
import com.dergoogler.mmrl.webui.handler.suPathHandler
2526
import com.dergoogler.mmrl.webui.handler.webrootPathHandler
2627
import com.dergoogler.mmrl.webui.model.Insets
2728
import com.dergoogler.mmrl.webui.model.WebResourceErrors
29+
import com.dergoogler.mmrl.webui.model.invoke
2830
import com.dergoogler.mmrl.webui.util.WebUIOptions
2931
import com.dergoogler.mmrl.webui.util.drawCompose
3032
import com.dergoogler.mmrl.webui.view.WXSwipeRefresh
@@ -191,6 +193,13 @@ open class WXClient : WebViewClient {
191193
): WebResourceResponse? {
192194
val urlString = request.url.toString()
193195

196+
// Check if the request is from an allowed domain
197+
if (!isAllowedUrl(urlString)) {
198+
Log.d(TAG, "Blocking request from unauthorized domain: $urlString")
199+
return forbiddenResponse
200+
}
201+
202+
// Handle favicon requests
194203
if (urlString.endsWith("/favicon.ico")) {
195204
Log.d(TAG, "Blocking favicon.ico request for $urlString")
196205
return WebResourceResponse("image/png", null, null)
@@ -200,6 +209,14 @@ open class WXClient : WebViewClient {
200209
return mWxAssetsLoader(request.url)
201210
}
202211

212+
private fun isAllowedUrl(requestHost: String?): Boolean = mOptions.config {
213+
if (requestHost == null) return@config false
214+
if (allowUrls.isEmpty()) return@config true
215+
return@config allowUrlsPatterns.any { pattern ->
216+
pattern.matcher(requestHost).matches()
217+
}
218+
}
219+
203220
private companion object {
204221
const val TAG = "WXClient"
205222
}

webui/src/main/kotlin/com/dergoogler/mmrl/webui/model/Config.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import dalvik.system.InMemoryDexClassLoader
3939
import kotlinx.coroutines.flow.StateFlow
4040
import java.nio.ByteBuffer
4141
import java.util.concurrent.ConcurrentHashMap
42+
import java.util.regex.Pattern
4243

4344

4445
object WebUIPermissions {
@@ -278,6 +279,8 @@ enum class WebUIConfigAdditionalConfigType {
278279
SWITCH,
279280
}
280281

282+
operator fun <T, R> ConfigFile<T>.invoke(block: T.() -> R): R = block(getConfig())
283+
281284
@JsonClass(generateAdapter = true)
282285
data class WebUIConfig(
283286
val __module__identifier__: ModId,
@@ -292,6 +295,7 @@ data class WebUIConfig(
292295
val refreshInterceptor: String? = null,
293296
val exitConfirm: Boolean = true,
294297
val pullToRefresh: Boolean = false,
298+
val allowUrls: MutableList<String> = mutableListOf(),
295299
val pullToRefreshHelper: Boolean = true,
296300
val historyFallbackFile: String = "index.html",
297301
val autoStatusBarsStyle: Boolean = true,
@@ -313,6 +317,9 @@ data class WebUIConfig(
313317
override fun getConfigType(): Class<WebUIConfig> = WebUIConfig::class.java
314318
override fun getDefaultConfigFactory(id: ModId): WebUIConfig = WebUIConfig(id)
315319

320+
internal val allowUrlsPatterns =
321+
allowUrls.mapNotNull { Pattern.compile(it, Pattern.CASE_INSENSITIVE) }
322+
316323
val hasRootPathPermission get() = WebUIPermissions.WX_ROOT_PATH in permissions
317324

318325
val useJavaScriptRefreshInterceptor get() = refreshInterceptor == "javascript"

0 commit comments

Comments
 (0)