From 27bac2ef483926c508bb3287719d9bed25959337 Mon Sep 17 00:00:00 2001 From: AviKav Date: Sun, 5 Jul 2020 12:56:15 -0400 Subject: [PATCH 1/2] 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) From a20c759700965134909284fc7f26ce086e7f73d0 Mon Sep 17 00:00:00 2001 From: AviKav Date: Sun, 5 Jul 2020 13:06:47 -0400 Subject: [PATCH 2/2] Move referrer check to before DB access and crypto for token check --- src/main/kotlin/mdnet/base/server/ImageServer.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/mdnet/base/server/ImageServer.kt b/src/main/kotlin/mdnet/base/server/ImageServer.kt index 0e09f73..06520fa 100644 --- a/src/main/kotlin/mdnet/base/server/ImageServer.kt +++ b/src/main/kotlin/mdnet/base/server/ImageServer.kt @@ -88,6 +88,11 @@ class ImageServer( "/data" } + "/$chapterHash/$fileName" + if (!request.referrerMatches(ALLOWED_REFERER_DOMAINS)) { + LOGGER.info { "Request for $sanitizedUri rejected due to non-allowed referrer ${request.header("Referer")}" } + return@then Response(Status.FORBIDDEN) + } + if (tokenized || serverSettings.forceTokens) { val tokenArr = Base64.getUrlDecoder().decode(Path.of("token")(request)) val token = try { @@ -135,11 +140,7 @@ class ImageServer( } } - if (!request.referrerMatches(ALLOWED_REFERER_DOMAINS)) { - snapshot?.close() - 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) { + if (snapshot != null && imageDatum != null) { request.handleCacheHit(sanitizedUri, getRc4(rc4Bytes), snapshot, imageDatum) } else { if (snapshot != null) { @@ -167,7 +168,6 @@ class ImageServer( } } - 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) {