From 8fd78a76ab6e54478f81b31a1c110a46ff5351eb Mon Sep 17 00:00:00 2001 From: gakuzzzz Date: Thu, 27 Aug 2015 02:52:42 +0900 Subject: [PATCH] fixed vulnerable of timing attack --- README.ja.md | 18 +++++++--------- README.md | 21 +++++++------------ .../jp/t2v/lab/play2/auth/TokenAccessor.scala | 17 ++++++++++++++- project/Build.scala | 2 +- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/README.ja.md b/README.ja.md index 7b2424b..bc9c0ae 100644 --- a/README.ja.md +++ b/README.ja.md @@ -36,10 +36,8 @@ Play2.4.2 で動作確認をしています。 以前のバージョン --------------------------------------- -Play2.3.x 向けの使用方法は [0.13.2 README](https://github.com/t2v/play2-auth/blob/release0.13.2/README.ja.md)をご参照ください。 -Play2.2.x 向けの使用方法は [0.11.0 README](https://github.com/t2v/play2-auth/blob/release0.11.0/README.ja.md)をご参照ください。 -Play2.1.x 向けの使用方法は [0.10.1 README](https://github.com/t2v/play2-auth/blob/release0.10.1/README.ja.md)をご参照ください。 -Play2.0.x 向けの使用方法は [0.7 README](https://github.com/t2v/play2-auth/blob/release0.7/README.ja.md)をご参照ください。 +Play2.3.x 向けの使用方法は [0.13.5 README](https://github.com/t2v/play2-auth/blob/release0.13.5/README.ja.md)をご参照ください。 +Play2.2.x 向けの使用方法は [0.11.1 README](https://github.com/t2v/play2-auth/blob/release0.11.1/README.ja.md)をご参照ください。 Play2.1以前をお使いの方へ --------------------------------------- @@ -53,18 +51,18 @@ Play2.1以前をお使いの方へ `Build.scala` もしくは `build.sbt` にライブラリ依存性定義を追加します。 - "jp.t2v" %% "play2-auth" % "0.14.0", - "jp.t2v" %% "play2-auth-social" % "0.14.0", // ソーシャルログイン - "jp.t2v" %% "play2-auth-test" % "0.14.0" % "test", + "jp.t2v" %% "play2-auth" % "0.14.1", + "jp.t2v" %% "play2-auth-social" % "0.14.1", // ソーシャルログイン + "jp.t2v" %% "play2-auth-test" % "0.14.1" % "test", play.sbt.Play.autoImport.cache // デフォルトのIdContainerを使う場合のみ必要です For example: `Build.scala` ```scala val appDependencies = Seq( - "jp.t2v" %% "play2-auth" % "0.14.0", - "jp.t2v" %% "play2-auth-social" % "0.14.0", - "jp.t2v" %% "play2-auth-test" % "0.14.0" % "test", + "jp.t2v" %% "play2-auth" % "0.14.1", + "jp.t2v" %% "play2-auth-social" % "0.14.1", + "jp.t2v" %% "play2-auth-test" % "0.14.1" % "test", play.sbt.Play.autoImport.cache // デフォルトのIdContainerを使う場合のみ必要です ) ``` diff --git a/README.md b/README.md index 2933b4a..3a202e0 100644 --- a/README.md +++ b/README.md @@ -36,14 +36,9 @@ Play2x-Auth provides a way of composition. Previous Version --------------------------------------- -for Play2.3.x, Please see [previous version 0.11.0 README](https://github.com/t2v/play2-auth/blob/release0.13.2/README.md) - -for Play2.2.x, Please see [previous version 0.11.0 README](https://github.com/t2v/play2-auth/blob/release0.11.0/README.md) - -for Play2.1.x, Please see [previous version 0.10.1 README](https://github.com/t2v/play2-auth/tree/release0.10.1) - -for Play2.0.x, Please see [previous version 0.7 README](https://github.com/t2v/play2-auth/tree/release0.7) +for Play2.3.x, Please see [previous version 0.13.5 README](https://github.com/t2v/play2-auth/blob/release0.13.5/README.md) +for Play2.2.x, Please see [previous version 0.11.1 README](https://github.com/t2v/play2-auth/blob/release0.11.1/README.md) Attention --------------------------------------- @@ -61,18 +56,18 @@ Add dependency declarations into your `Build.scala` or `build.sbt` file: * __for Play2.4.x__ - "jp.t2v" %% "play2-auth" % "0.14.0", - "jp.t2v" %% "play2-auth-social" % "0.14.0", // for social login - "jp.t2v" %% "play2-auth-test" % "0.14.0" % "test", + "jp.t2v" %% "play2-auth" % "0.14.1", + "jp.t2v" %% "play2-auth-social" % "0.14.1", // for social login + "jp.t2v" %% "play2-auth-test" % "0.14.1" % "test", play.sbt.Play.autoImport.cache // only when you use default IdContainer For example your `Build.scala` might look like this: ```scala val appDependencies = Seq( - "jp.t2v" %% "play2-auth" % "0.14.0", - "jp.t2v" %% "play2-auth-social" % "0.14.0", - "jp.t2v" %% "play2-auth-test" % "0.14.0" % "test", + "jp.t2v" %% "play2-auth" % "0.14.1", + "jp.t2v" %% "play2-auth-social" % "0.14.1", + "jp.t2v" %% "play2-auth-test" % "0.14.1" % "test", play.sbt.Play.autoImport.cache ) ``` diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/TokenAccessor.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/TokenAccessor.scala index 2ceb461..3fb965d 100644 --- a/module/src/main/scala/jp/t2v/lab/play2/auth/TokenAccessor.scala +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/TokenAccessor.scala @@ -13,9 +13,24 @@ trait TokenAccessor { protected def verifyHmac(token: SignedToken): Option[AuthenticityToken] = { val (hmac, value) = token.splitAt(40) - if (Crypto.sign(value) == hmac) Some(value) else None + if (safeEquals(Crypto.sign(value), hmac)) Some(value) else None } protected def sign(token: AuthenticityToken): SignedToken = Crypto.sign(token) + token + // Do not change this unless you understand the security issues behind timing attacks. + // This method intentionally runs in constant time if the two strings have the same length. + // If it didn't, it would be vulnerable to a timing attack. + protected def safeEquals(a: String, b: String) = { + if (a.length != b.length) { + false + } else { + var equal = 0 + for (i <- Array.range(0, a.length)) { + equal |= a(i) ^ b(i) + } + equal == 0 + } + } + } diff --git a/project/Build.scala b/project/Build.scala index b67734a..057a0e0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -9,7 +9,7 @@ object ApplicationBuild extends Build { val playVersion = play.core.PlayVersion.current lazy val baseSettings = Seq( - version := "0.14.0", + version := "0.14.1", scalaVersion := "2.11.6", crossScalaVersions := Seq("2.10.5", "2.11.6"), organization := "jp.t2v",