Skip to content

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

License

Notifications You must be signed in to change notification settings

devhaozi/securecookie

 
 

Repository files navigation

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 encrypted and validated using ChaCha20-Poly1305, the content is 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:

// Keys must be 32 bytes long
var key = []byte("32-byte-long-auth-key")
var s, err = securecookie.New(hashKey, blockKey)

The key is required and must be 32 bytes, used to authenticate and encrypt cookie values.

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"])
		}
	}
}

Secure cookies can hold any value thatcan be encoded using encoding/json. it works out of the box.

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 previous, _ = securecookie.New(securecookie.GenerateRandomKey(32))
var current, _ = securecookie.New(securecookie.GenerateRandomKey(32))
var cookies = map[string]*securecookie.SecureCookie{
	"previous": previous,
	"current": current,
}

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.

About

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

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 95.6%
  • Makefile 4.4%