Movatterモバイル変換


[0]ホーム

URL:


securecookie

packagemodule
v1.1.2Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2023 License:BSD-3-ClauseImports:16Imported by:2,898

Details

Repository

github.com/gorilla/securecookie

Links

README

gorilla/securecookie

testingcodecovgodocsourcegraph

Gorilla Logo

securecookie encodes and decodes authenticated and optionally encryptedcookie 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 stillrecommended that sensitive data not be stored in cookies, and that HTTPS be usedto prevent cookiereplay attacks.

Examples

To use it, first create a new SecureCookie instance:

// Hash keys should be at least 32 bytes longvar 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 nilto not use encryption. If set, the length must correspond to the block sizeof the encryption algorithm. For AES, used by default, valid lengths are16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

Strong keys can be created using the convenience functionGenerateRandomKey(). Note that keys created usingGenerateRandomKey() are notautomatically persisted. New keys will be created when the application isrestarted, 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 cookievalue:

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 thatcan be encoded usingencoding/gob. To store custom types, they must beregistered first using gob.Register(). For basic types this is not needed;it works out of the box. An optional JSON encoder that usesencoding/json isavailable for types compatible with JSON.

Key Rotation

Rotating keys is an important part of any security strategy. TheEncodeMulti andDecodeMulti 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.

Documentation

Overview

Package securecookie encodes and decodes authenticated and optionallyencrypted 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.

To use it, first create a new SecureCookie instance:

var hashKey = []byte("very-secret")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 nilto not use encryption. If set, the length must correspond to the block sizeof the encryption algorithm. For AES, used by default, valid lengths are16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

Strong keys can be created using the convenience function GenerateRandomKey().

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:  "/",}http.SetCookie(w, cookie)}}

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

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 thatcan be encoded using encoding/gob. To store custom types, they must beregistered first using gob.Register(). For basic types this is not needed;it works out of the box.

Index

Constants

This section is empty.

Variables

View Source
var (// ErrMacInvalid indicates that cookie decoding failed because the HMAC// could not be extracted and verified.  Direct use of this error// variable is deprecated; it is public only for legacy compatibility,// and may be privatized in the future, as it is rarely useful to// distinguish between this error and other Error implementations.ErrMacInvalid = cookieError{/* contains filtered or unexported fields */})

Functions

funcDecodeMulti

func DecodeMulti(namestring, valuestring, dst interface{}, codecs ...Codec)error

DecodeMulti decodes a cookie value using a group of codecs.

The codecs are tried in order. Multiple codecs are accepted to allowkey rotation.

On error, may return a MultiError.

funcEncodeMulti

func EncodeMulti(namestring, value interface{}, codecs ...Codec) (string,error)

EncodeMulti encodes a cookie value using a group of codecs.

The codecs are tried in order. Multiple codecs are accepted to allowkey rotation.

On error, may return a MultiError.

funcGenerateRandomKey

func GenerateRandomKey(lengthint) []byte

GenerateRandomKey creates a random key with the given length in bytes.On failure, returns nil.

Note that keys created using `GenerateRandomKey()` are not automaticallypersisted. New keys will be created when the application is restarted, andpreviously issued cookies will not be able to be decoded.

Callers should explicitly check for the possibility of a nil return, treatit as a failure of the system random number generator, and not continue.

Types

typeCodec

type Codec interface {Encode(namestring, value interface{}) (string,error)Decode(name, valuestring, dst interface{})error}

Codec defines an interface to encode and decode cookie values.

funcCodecsFromPairs

func CodecsFromPairs(keyPairs ...[]byte) []Codec

CodecsFromPairs returns a slice of SecureCookie instances.

It is a convenience function to create a list of codecs for key rotation. Notethat the generated Codecs will have the default options applied: callersshould iterate over each Codec and type-assert the underlying *SecureCookie tochange these.

Example:

codecs := securecookie.CodecsFromPairs(     []byte("new-hash-key"),     []byte("new-block-key"),     []byte("old-hash-key"),     []byte("old-block-key"), )// Modify each instance.for _, s := range codecs {       if cookie, ok := s.(*securecookie.SecureCookie); ok {           cookie.MaxAge(86400 * 7)           cookie.SetSerializer(securecookie.JSONEncoder{})           cookie.HashFunc(sha512.New512_256)       }   }

typeError

type Error interface {error// IsUsage returns true for errors indicating the client code probably// uses this library incorrectly.  For example, the client may have// failed to provide a valid hash key, or may have failed to configure// the Serializer adequately for encoding value.IsUsage()bool// IsDecode returns true for errors indicating that a cookie could not// be decoded and validated.  Since cookies are usually untrusted// user-provided input, errors of this type should be expected.// Usually, the proper action is simply to reject the request.IsDecode()bool// IsInternal returns true for unexpected errors occurring in the// securecookie implementation.IsInternal()bool// Cause, if it returns a non-nil value, indicates that this error was// propagated from some underlying library.  If this method returns nil,// this error was raised directly by this library.//// Cause is provided principally for debugging/logging purposes; it is// rare that application logic should perform meaningfully different// logic based on Cause.  See, for example, the caveats described on// (MultiError).Cause().Cause()error}

Error is the interface of all errors returned by functions in this library.

typeGobEncoder

type GobEncoder struct{}

GobEncoder encodes cookie values using encoding/gob. This is the simplestencoder and can handle complex types via gob.Register.

func (GobEncoder)Deserialize

func (eGobEncoder) Deserialize(src []byte, dst interface{})error

Deserialize decodes a value using gob.

func (GobEncoder)Serialize

func (eGobEncoder) Serialize(src interface{}) ([]byte,error)

Serialize encodes a value using gob.

typeJSONEncoder

type JSONEncoder struct{}

JSONEncoder encodes cookie values using encoding/json. Users who wish toencode complex types need to satisfy the json.Marshaller andjson.Unmarshaller interfaces.

func (JSONEncoder)Deserialize

func (eJSONEncoder) Deserialize(src []byte, dst interface{})error

Deserialize decodes a value using encoding/json.

func (JSONEncoder)Serialize

func (eJSONEncoder) Serialize(src interface{}) ([]byte,error)

Serialize encodes a value using encoding/json.

typeMultiError

type MultiError []error

MultiError groups multiple errors.

func (MultiError)Cause

func (mMultiError) Cause()error

Cause returns nil for MultiError; there is no unique underlying cause in thegeneral case.

Note: we could conceivably return a non-nil Cause only when there is exactlyone child error with a Cause. However, it would be brittle for client codeto rely on the arity of causes inside a MultiError, so we have opted not toprovide this functionality. Clients which really wish to access the Causesof the underlying errors are free to iterate through the errors themselves.

func (MultiError)Error

func (mMultiError) Error()string

func (MultiError)IsDecode

func (mMultiError) IsDecode()bool

func (MultiError)IsInternal

func (mMultiError) IsInternal()bool

func (MultiError)IsUsage

func (mMultiError) IsUsage()bool

typeNopEncoder

type NopEncoder struct{}

NopEncoder does not encode cookie values, and instead simply accepts a []byte(as an interface{}) and returns a []byte. This is particularly useful whenyou encoding an object upstream and do not wish to re-encode it.

func (NopEncoder)Deserialize

func (eNopEncoder) Deserialize(src []byte, dst interface{})error

Deserialize passes a []byte through as-is.

func (NopEncoder)Serialize

func (eNopEncoder) Serialize(src interface{}) ([]byte,error)

Serialize passes a []byte through as-is.

typeSecureCookie

type SecureCookie struct {// contains filtered or unexported fields}

SecureCookie encodes and decodes authenticated and optionally encryptedcookie values.

funcNew

func New(hashKey, blockKey []byte) *SecureCookie

New returns a new SecureCookie.

hashKey is required, used to authenticate values using HMAC. Create it usingGenerateRandomKey(). It is recommended to use a key with 32 or 64 bytes.

blockKey is optional, used to encrypt values. Create it usingGenerateRandomKey(). The key length must correspond to the key sizeof the encryption algorithm. For AES, used by default, valid lengths are16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.The default encoder used for cookie serialization is encoding/gob.

Note that keys created using GenerateRandomKey() are not automaticallypersisted. New keys will be created when the application is restarted, andpreviously issued cookies will not be able to be decoded.

func (*SecureCookie)BlockFunc

func (s *SecureCookie) BlockFunc(f func([]byte) (cipher.Block,error)) *SecureCookie

BlockFunc sets the encryption function used to create a cipher.Block.

Default is crypto/aes.New.

func (*SecureCookie)Decode

func (s *SecureCookie) Decode(name, valuestring, dst interface{})error

Decode decodes a cookie value.

It decodes, verifies a message authentication code, optionally decrypts andfinally deserializes the value.

The name argument is the cookie name. It must be the same name used whenit was stored. The value argument is the encoded cookie value. The dstargument is where the cookie will be decoded. It must be a pointer.

func (*SecureCookie)Encode

func (s *SecureCookie) Encode(namestring, value interface{}) (string,error)

Encode encodes a cookie value.

It serializes, optionally encrypts, signs with a message authentication code,and finally encodes the value.

The name argument is the cookie name. It is stored with the encoded value.The value argument is the value to be encoded. It can be any value that canbe encoded using the currently selected serializer; see SetSerializer().

It is the client's responsibility to ensure that value, when encoded usingthe current serialization/encryption settings on s and then base64-encoded,is shorter than the maximum permissible length.

func (*SecureCookie)HashFunc

func (s *SecureCookie) HashFunc(f func()hash.Hash) *SecureCookie

HashFunc sets the hash function used to create HMAC.

Default is crypto/sha256.New.

func (*SecureCookie)MaxAge

func (s *SecureCookie) MaxAge(valueint) *SecureCookie

MaxAge restricts the maximum age, in seconds, for the cookie value.

Default is 86400 * 30. Set it to 0 for no restriction.

func (*SecureCookie)MaxLength

func (s *SecureCookie) MaxLength(valueint) *SecureCookie

MaxLength restricts the maximum length, in bytes, for the cookie value.

Default is 4096, which is the maximum value accepted by Internet Explorer.

func (*SecureCookie)MinAge

func (s *SecureCookie) MinAge(valueint) *SecureCookie

MinAge restricts the minimum age, in seconds, for the cookie value.

Default is 0 (no restriction).

func (*SecureCookie)SetSerializer

func (s *SecureCookie) SetSerializer(szSerializer) *SecureCookie

Encoding sets the encoding/serialization method for cookies.

Default is encoding/gob. To encode special structures using encoding/gob,they must be registered first using gob.Register().

typeSerializer

type Serializer interface {Serialize(src interface{}) ([]byte,error)Deserialize(src []byte, dst interface{})error}

Serializer provides an interface for providing custom serializers for cookievalues.

Source Files

View all Source files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp