From f1b552e157a610c600768a83da547ecf24253478 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 22 Apr 2016 17:55:22 +0200 Subject: [PATCH] =?UTF-8?q?built-in=20web=20server=20=E2=80=94=20forbid=20?= =?UTF-8?q?untrusted=20access:=20check=20param=20in=20referer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jetbrains/builtInWebServer/BuiltInWebServer.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt index 16e478a69ec8..355a998cae51 100644 --- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt +++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt @@ -40,9 +40,9 @@ import com.intellij.util.net.NetUtils import io.netty.channel.Channel import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.http.* -import io.netty.handler.codec.http.cookie.ClientCookieEncoder import io.netty.handler.codec.http.cookie.DefaultCookie import io.netty.handler.codec.http.cookie.ServerCookieDecoder +import io.netty.handler.codec.http.cookie.ServerCookieEncoder import org.jetbrains.ide.HttpRequestHandler import org.jetbrains.io.* import java.awt.datatransfer.StringSelection @@ -112,9 +112,11 @@ private val STANDARD_COOKIE by lazy { FileUtil.writeToFile(file, token!!) } + // explicit setting domain cookie on localhost doesn't work for chrome + // http://stackoverflow.com/questions/8134384/chrome-doesnt-create-cookie-for-domain-localhost-in-broken-https val cookie = DefaultCookie(cookieName, token!!) cookie.isHttpOnly = true - cookie.setMaxAge(TimeUnit.DAYS.toMillis(365 * 10)) + cookie.setMaxAge(TimeUnit.DAYS.toSeconds(365 * 10)) cookie.setPath("/") cookie } @@ -225,14 +227,15 @@ private fun validateToken(request: HttpRequest, channel: Channel, urlDecoder: Qu } } - val token = urlDecoder.parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() + // we must check referrer - if html cached, browser will send request without query + val token = urlDecoder.parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() ?: request.referrer?.let { QueryStringDecoder(it).parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() } val url = "${channel.uriScheme}://${request.host!!}${urlDecoder.path()}" if (token != null && tokens.getIfPresent(token) != null) { tokens.invalidate(token) // we redirect because it is not easy to change and maintain all places where we send response val response = HttpResponseStatus.TEMPORARY_REDIRECT.response() response.headers().add(HttpHeaderNames.LOCATION, url) - response.headers().set(HttpHeaderNames.SET_COOKIE, ClientCookieEncoder.STRICT.encode(STANDARD_COOKIE)) + response.headers().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(STANDARD_COOKIE)) response.send(channel, request) return true }