github.com/google/go-safeweb@v0.0.0-20231219055052-64d8cfc90fbb/safehttp/cookie.go (about)

     1  // Copyright 2020 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package safehttp
    16  
    17  import (
    18  	"net/http"
    19  )
    20  
    21  // A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
    22  // HTTP response or the Cookie header of an HTTP request.
    23  //
    24  // See https://tools.ietf.org/html/rfc6265 for details.
    25  type Cookie struct {
    26  	wrapped *http.Cookie
    27  }
    28  
    29  // NewCookie creates a new Cookie with safe default settings.
    30  // Those safe defaults are:
    31  //   - Secure: true (if the framework is not in dev mode)
    32  //   - HttpOnly: true
    33  //   - SameSite: Lax
    34  //
    35  // For more info about all the options, see:
    36  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
    37  func NewCookie(name, value string) *Cookie {
    38  	devMu.RLock()
    39  	defer devMu.RUnlock()
    40  	return &Cookie{
    41  		&http.Cookie{
    42  			Name:     name,
    43  			Value:    value,
    44  			Secure:   !isLocalDev,
    45  			HttpOnly: true,
    46  			SameSite: http.SameSiteLaxMode,
    47  		},
    48  	}
    49  }
    50  
    51  // SameSite allows a server to define a cookie attribute making it impossible for
    52  // the browser to send this cookie along with cross-site requests. The main
    53  // goal is to mitigate the risk of cross-origin information leakage, and provide
    54  // some protection against cross-site request forgery attacks.
    55  //
    56  // See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details.
    57  type SameSite int
    58  
    59  const (
    60  	// SameSiteLaxMode allows sending cookies with same-site requests and
    61  	// cross-site top-level navigations.
    62  	SameSiteLaxMode SameSite = iota + 1
    63  	// SameSiteStrictMode allows sending cookie only with same-site requests.
    64  	SameSiteStrictMode
    65  	// SameSiteNoneMode allows sending cookies with all requests, including the
    66  	// ones made cross-origin.
    67  	SameSiteNoneMode
    68  )
    69  
    70  // SameSite sets the SameSite attribute.
    71  func (c *Cookie) SameSite(s SameSite) {
    72  	switch s {
    73  	case SameSiteLaxMode:
    74  		c.wrapped.SameSite = http.SameSiteLaxMode
    75  	case SameSiteStrictMode:
    76  		c.wrapped.SameSite = http.SameSiteStrictMode
    77  	case SameSiteNoneMode:
    78  		c.wrapped.SameSite = http.SameSiteNoneMode
    79  	}
    80  }
    81  
    82  // SetMaxAge sets the MaxAge attribute.
    83  //
    84  // - MaxAge = 0 means no 'Max-Age' attribute specified.
    85  // - MaxAge < 0 means delete cookie now, equivalently 'Max-Age: 0'
    86  // - MaxAge > 0 means Max-Age attribute present and given in seconds
    87  func (c *Cookie) SetMaxAge(maxAge int) {
    88  	c.wrapped.MaxAge = maxAge
    89  }
    90  
    91  // Path sets the path attribute.
    92  func (c *Cookie) Path(path string) {
    93  	c.wrapped.Path = path
    94  }
    95  
    96  // Domain sets the domain attribute.
    97  func (c *Cookie) Domain(domain string) {
    98  	c.wrapped.Domain = domain
    99  }
   100  
   101  // DisableSecure disables the secure attribute.
   102  func (c *Cookie) DisableSecure() {
   103  	c.wrapped.Secure = false
   104  }
   105  
   106  // DisableHTTPOnly disables the HttpOnly attribute.
   107  func (c *Cookie) DisableHTTPOnly() {
   108  	c.wrapped.HttpOnly = false
   109  }
   110  
   111  // Name returns the name of the cookie.
   112  func (c *Cookie) Name() string {
   113  	return c.wrapped.Name
   114  }
   115  
   116  // Value returns the value of the cookie.
   117  func (c *Cookie) Value() string {
   118  	return c.wrapped.Value
   119  }
   120  
   121  // String returns the serialization of the cookie for use in a Set-Cookie
   122  // response header. If c is nil or c.Name() is invalid, the empty string is
   123  // returned.
   124  func (c *Cookie) String() string {
   125  	return c.wrapped.String()
   126  }