mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-06-13 00:07:26 +02:00
Migrate cookie signing to SHA256 from SHA1 (#524)
Also, cleanup the code & make the specific hashing algorithm chosen a function variable. Co-authored-by: Henry Jenkins <henry@henryjenkins.name>
This commit is contained in:
parent
07df29db37
commit
9d626265e8
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
## Changes since v5.1.1
|
## Changes since v5.1.1
|
||||||
|
|
||||||
|
- [#524](https://github.com/oauth2-proxy/oauth2-proxy/pull/524) Sign cookies with SHA256 (@NickMeves)
|
||||||
- [#515](https://github.com/oauth2-proxy/oauth2-proxy/pull/515) Drop configure script in favour of native Makefile env and checks (@JoelSpeed)
|
- [#515](https://github.com/oauth2-proxy/oauth2-proxy/pull/515) Drop configure script in favour of native Makefile env and checks (@JoelSpeed)
|
||||||
- [#487](https://github.com/oauth2-proxy/oauth2-proxy/pull/487) Switch flags to PFlag to remove StringArray (@JoelSpeed)
|
- [#487](https://github.com/oauth2-proxy/oauth2-proxy/pull/487) Switch flags to PFlag to remove StringArray (@JoelSpeed)
|
||||||
- [#484](https://github.com/oauth2-proxy/oauth2-proxy/pull/484) Replace configuration loading with Viper (@JoelSpeed)
|
- [#484](https://github.com/oauth2-proxy/oauth2-proxy/pull/484) Replace configuration loading with Viper (@JoelSpeed)
|
||||||
|
@ -6,8 +6,10 @@ import (
|
|||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -25,8 +27,7 @@ func Validate(cookie *http.Cookie, seed string, expiration time.Duration) (value
|
|||||||
if len(parts) != 3 {
|
if len(parts) != 3 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sig := cookieSignature(seed, cookie.Name, parts[0], parts[1])
|
if checkSignature(parts[2], seed, cookie.Name, parts[0], parts[1]) {
|
||||||
if checkHmac(parts[2], sig) {
|
|
||||||
ts, err := strconv.Atoi(parts[1])
|
ts, err := strconv.Atoi(parts[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -53,13 +54,13 @@ func Validate(cookie *http.Cookie, seed string, expiration time.Duration) (value
|
|||||||
func SignedValue(seed string, key string, value string, now time.Time) string {
|
func SignedValue(seed string, key string, value string, now time.Time) string {
|
||||||
encodedValue := base64.URLEncoding.EncodeToString([]byte(value))
|
encodedValue := base64.URLEncoding.EncodeToString([]byte(value))
|
||||||
timeStr := fmt.Sprintf("%d", now.Unix())
|
timeStr := fmt.Sprintf("%d", now.Unix())
|
||||||
sig := cookieSignature(seed, key, encodedValue, timeStr)
|
sig := cookieSignature(sha256.New, seed, key, encodedValue, timeStr)
|
||||||
cookieVal := fmt.Sprintf("%s|%s|%s", encodedValue, timeStr, sig)
|
cookieVal := fmt.Sprintf("%s|%s|%s", encodedValue, timeStr, sig)
|
||||||
return cookieVal
|
return cookieVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func cookieSignature(args ...string) string {
|
func cookieSignature(signer func() hash.Hash, args ...string) string {
|
||||||
h := hmac.New(sha1.New, []byte(args[0]))
|
h := hmac.New(signer, []byte(args[0]))
|
||||||
for _, arg := range args[1:] {
|
for _, arg := range args[1:] {
|
||||||
h.Write([]byte(arg))
|
h.Write([]byte(arg))
|
||||||
}
|
}
|
||||||
@ -68,6 +69,17 @@ func cookieSignature(args ...string) string {
|
|||||||
return base64.URLEncoding.EncodeToString(b)
|
return base64.URLEncoding.EncodeToString(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkSignature(signature string, args ...string) bool {
|
||||||
|
checkSig := cookieSignature(sha256.New, args...)
|
||||||
|
if checkHmac(signature, checkSig) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: After appropriate rollout window, remove support for SHA1
|
||||||
|
legacySig := cookieSignature(sha1.New, args...)
|
||||||
|
return checkHmac(signature, legacySig)
|
||||||
|
}
|
||||||
|
|
||||||
func checkHmac(input, expected string) bool {
|
func checkHmac(input, expected string) bool {
|
||||||
inputMAC, err1 := base64.URLEncoding.DecodeString(input)
|
inputMAC, err1 := base64.URLEncoding.DecodeString(input)
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
|
@ -1,12 +1,31 @@
|
|||||||
package encryption
|
package encryption
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestSignAndValidate(t *testing.T) {
|
||||||
|
seed := "0123456789abcdef"
|
||||||
|
key := "cookie-name"
|
||||||
|
value := base64.URLEncoding.EncodeToString([]byte("I am soooo encoded"))
|
||||||
|
epoch := "123456789"
|
||||||
|
|
||||||
|
sha256sig := cookieSignature(sha256.New, seed, key, value, epoch)
|
||||||
|
sha1sig := cookieSignature(sha1.New, seed, key, value, epoch)
|
||||||
|
|
||||||
|
assert.True(t, checkSignature(sha256sig, seed, key, value, epoch))
|
||||||
|
// This should be switched to False after fully deprecating SHA1
|
||||||
|
assert.True(t, checkSignature(sha1sig, seed, key, value, epoch))
|
||||||
|
|
||||||
|
assert.False(t, checkSignature(sha256sig, seed, key, "tampered", epoch))
|
||||||
|
assert.False(t, checkSignature(sha1sig, seed, key, "tampered", epoch))
|
||||||
|
}
|
||||||
|
|
||||||
func TestEncodeAndDecodeAccessToken(t *testing.T) {
|
func TestEncodeAndDecodeAccessToken(t *testing.T) {
|
||||||
const secret = "0123456789abcdefghijklmnopqrstuv"
|
const secret = "0123456789abcdefghijklmnopqrstuv"
|
||||||
const token = "my access token"
|
const token = "my access token"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user