• Stars
    star
    652
  • Rank 66,433 (Top 2 %)
  • Language
    Go
  • License
    BSD 3-Clause "New...
  • Created over 11 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Package gorilla/securecookie encodes and decodes authenticated and optionally encrypted cookie values for Go web applications.

gorilla/securecookie

testing codecov godoc sourcegraph

Gorilla Logo

securecookie encodes and decodes authenticated and optionally encrypted cookie values.

Secure cookies can't be forged, because their values are validated using HMAC. When encrypted, the content is also inaccessible to malicious eyes. It is still recommended that sensitive data not be stored in cookies, and that HTTPS be used to prevent cookie replay attacks.

Examples

To use it, first create a new SecureCookie instance:

// Hash keys should be at least 32 bytes long
var hashKey = []byte("very-secret")
// Block keys should be 16 bytes (AES-128) or 32 bytes (AES-256) long.
// Shorter keys may weaken the encryption used.
var blockKey = []byte("a-lot-secret")
var s = securecookie.New(hashKey, blockKey)

The hashKey is required, used to authenticate the cookie value using HMAC. It is recommended to use a key with 32 or 64 bytes.

The blockKey is optional, used to encrypt the cookie value -- set it to nil to not use encryption. If set, the length must correspond to the block size of the encryption algorithm. For AES, used by default, valid lengths are 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

Strong keys can be created using the convenience function GenerateRandomKey(). Note that keys created using GenerateRandomKey() are not automatically persisted. New keys will be created when the application is restarted, and previously issued cookies will not be able to be decoded.

Once a SecureCookie instance is set, use it to encode a cookie value:

func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
	value := map[string]string{
		"foo": "bar",
	}
	if encoded, err := s.Encode("cookie-name", value); err == nil {
		cookie := &http.Cookie{
			Name:  "cookie-name",
			Value: encoded,
			Path:  "/",
			Secure: true,
			HttpOnly: true,
		}
		http.SetCookie(w, cookie)
	}
}

Later, use the same SecureCookie instance to decode and validate a cookie value:

func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
	if cookie, err := r.Cookie("cookie-name"); err == nil {
		value := make(map[string]string)
		if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil {
			fmt.Fprintf(w, "The value of foo is %q", value["foo"])
		}
	}
}

We stored a map[string]string, but secure cookies can hold any value that can be encoded using encoding/gob. To store custom types, they must be registered first using gob.Register(). For basic types this is not needed; it works out of the box. An optional JSON encoder that uses encoding/json is available for types compatible with JSON.

Key Rotation

Rotating keys is an important part of any security strategy. The EncodeMulti and DecodeMulti functions allow for multiple keys to be rotated in and out. For example, let's take a system that stores keys in a map:

// keys stored in a map will not be persisted between restarts
// a more persistent storage should be considered for production applications.
var cookies = map[string]*securecookie.SecureCookie{
	"previous": securecookie.New(
		securecookie.GenerateRandomKey(64),
		securecookie.GenerateRandomKey(32),
	),
	"current": securecookie.New(
		securecookie.GenerateRandomKey(64),
		securecookie.GenerateRandomKey(32),
	),
}

Using the current key to encode new cookies:

func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
	value := map[string]string{
		"foo": "bar",
	}
	if encoded, err := securecookie.EncodeMulti("cookie-name", value, cookies["current"]); err == nil {
		cookie := &http.Cookie{
			Name:  "cookie-name",
			Value: encoded,
			Path:  "/",
		}
		http.SetCookie(w, cookie)
	}
}

Later, decode cookies. Check against all valid keys:

func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
	if cookie, err := r.Cookie("cookie-name"); err == nil {
		value := make(map[string]string)
		err = securecookie.DecodeMulti("cookie-name", cookie.Value, &value, cookies["current"], cookies["previous"])
		if err == nil {
			fmt.Fprintf(w, "The value of foo is %q", value["foo"])
		}
	}
}

Rotate the keys. This strategy allows previously issued cookies to be valid until the next rotation:

func Rotate(newCookie *securecookie.SecureCookie) {
	cookies["previous"] = cookies["current"]
	cookies["current"] = newCookie
}

License

BSD licensed. See the LICENSE file for details.

More Repositories

1

websocket

Package gorilla/websocket is a fast, well-tested and widely used WebSocket implementation for Go.
Go
20,778
star
2

mux

Package gorilla/mux is a powerful HTTP router and URL matcher for building Go web servers with 🦍
Go
19,888
star
3

sessions

Package gorilla/sessions provides cookie and filesystem sessions and infrastructure for custom session backends.
Go
2,694
star
4

handlers

Package gorilla/handlers is a collection of useful middleware for Go HTTP services & web applications 🛃
Go
1,604
star
5

schema

Package gorilla/schema fills a struct with form values.
Go
1,276
star
6

csrf

Package gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒
Go
976
star
7

feeds

Package gorilla/feeds is a golang rss/atom generator library
Go
703
star
8

rpc

Package gorilla/rpc is a golang foundation for RPC over HTTP services.
Go
560
star
9

context

Package gorilla/context is a golang registry for global request variables.
Go
429
star
10

http

Package gorilla/http is an alternative HTTP client implementation for Go.
Go
263
star
11

pat

Package gorilla/pat is a pretty simple HTTP router for Go.
Go
141
star
12

css

Package gorilla/css is a CSS3 tokenizer.
Go
83
star
13

muxy

Package gorilla/muxy takes gorilla/mux to the next level
Go
74
star
14

gorilla.github.io

Gorilla web toolkit's website.
HTML
58
star
15

reverse

Package gorilla/reverse is a set of utilities to create request routers.
Go
51
star
16

i18n

Package gorilla/i18n groups packages related to internationalization
Go
49
star
17

template

A fork of the standard template packages.
Go
45
star
18

.github

The .github repository for the @gorilla organization.
9
star