From 27bac2ef483926c508bb3287719d9bed25959337 Mon Sep 17 00:00:00 2001 From: AviKav Date: Sun, 5 Jul 2020 12:56:15 -0400 Subject: [PATCH] Fix referrer check --- .../kotlin/mdnet/base/server/ImageServer.kt | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/mdnet/base/server/ImageServer.kt b/src/main/kotlin/mdnet/base/server/ImageServer.kt index fd2b0ef..0e09f73 100644 --- a/src/main/kotlin/mdnet/base/server/ImageServer.kt +++ b/src/main/kotlin/mdnet/base/server/ImageServer.kt @@ -135,9 +135,10 @@ class ImageServer( } } - if (request.header("Referer")?.startsWith("https://mangadex.org") == false) { + if (!request.referrerMatches(ALLOWED_REFERER_DOMAINS)) { snapshot?.close() - Response(Status.FORBIDDEN) + LOGGER.info { "Request for $sanitizedUri rejected due to non-allowed referrer ${request.header("Referer")}" } + return@then Response(Status.FORBIDDEN) } else if (snapshot != null && imageDatum != null) { request.handleCacheHit(sanitizedUri, getRc4(rc4Bytes), snapshot, imageDatum) } else { @@ -152,6 +153,21 @@ class ImageServer( } } + /** + * Filters referrers based on passed (sub)domains. Ignores `scheme` (protocol) in URL + */ + private fun Request.referrerMatches(allowedDomains: List, permitBlank: Boolean = true): Boolean { + val referer = this.header("Referer") ?: return permitBlank // Referrer was misspelled as "Referer" and now we're stuck with it -_- + if (referer == "") return permitBlank + + return allowedDomains.any { + referer.substringAfter("//") // Ignore scheme + .substringBefore("/") // Ignore path + .endsWith(it) + } + } + + private fun Request.handleCacheHit(sanitizedUri: String, cipher: Cipher, snapshot: DiskLruCache.Snapshot, imageDatum: ImageDatum): Response { // our files never change, so it's safe to use the browser cache return if (this.header("If-Modified-Since") != null) { @@ -274,6 +290,7 @@ class ImageServer( private val JACKSON: ObjectMapper = jacksonObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .registerModule(JavaTimeModule()) + private val ALLOWED_REFERER_DOMAINS = listOf("mangadex.org", "mangadex.network") // TODO: Factor out hardcoded domains? private fun baseHandler(): Filter = CachingFilters.Response.MaxAge(Clock.systemUTC(), Constants.MAX_AGE_CACHE)