go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure

profile photo of semgrepsemgrep
Author
5,552
Download Count*

A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct.

Run Locally

Run in CI

Defintion

rules:
  - id: session-cookie-missing-secure
    patterns:
      - pattern-not-inside: |
          &sessions.Options{
            ...,
            Secure: true,
            ...,
          }
      - pattern: |
          &sessions.Options{
            ...,
          }
    message: A session cookie was detected without setting the 'Secure' flag. The
      'secure' flag for cookies prevents the client from transmitting the cookie
      over insecure channels such as HTTP. Set the 'Secure' flag by setting
      'Secure' to 'true' in the Options struct.
    metadata:
      cwe:
        - "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
      owasp:
        - A05:2021 - Security Misconfiguration
      references:
        - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69
      category: security
      technology:
        - gorilla
      confidence: MEDIUM
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cookie Security
    fix-regex:
      regex: (Secure\s*:\s+)false
      replacement: \1true
    severity: WARNING
    languages:
      - go

Examples

session-cookie-missing-secure.go

// cf. https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go

package session

import (
	"log"
	"fmt"
	"net/http"
	"govwa/util/config"
	"github.com/gorilla/sessions"
)

type Self struct{}

func New() *Self {
	return &Self{}
}

var store = sessions.NewCookieStore([]byte(config.Cfg.Sessionkey))

func (self *Self) SetSession(w http.ResponseWriter, r *http.Request, data map[string]string) {
	session, err := store.Get(r, "govwa")

	if err != nil {
		log.Println(err.Error())
	}

    // ruleid: session-cookie-missing-secure
	session.Options = &sessions.Options{
		Path:     "/",
		MaxAge:   3600,
		HttpOnly: false, //set to false for xss :)
        Secure: false,
	}

	session.Values["govwa_session"] = true

	//create new session to store on server side
	if data != nil {
		for key, value := range data {
			session.Values[key] = value
		}
	}
	err = session.Save(r, w) //safe session and send it to client as cookie

		if err != nil {
			log.Println(err.Error())
		}
}

func (self *Self) GetSession(r *http.Request, key string) string  {
	session, err := store.Get(r, "govwa")

	if err != nil {
		log.Println(err.Error())
		return ""
	}
	data := session.Values[key]
	sv := fmt.Sprintf("%v", data)
	return sv
}

func (self *Self) DeleteSession(w http.ResponseWriter, r *http.Request) {
	session, err := store.Get(r, "govwa")
	if err != nil {
		log.Println(err.Error())
	}

    // ruleid: session-cookie-missing-secure
	session.Options = &sessions.Options{
		MaxAge:   -1,
		HttpOnly: false, //set to false for xss :)
	}

	session.Values["govwa_session"] = false
	err = session.Save(r, w) //safe session and send it to client as cookie

	if err != nil {
		log.Println(err.Error())
	}

	return
}

func (self *Self) IsLoggedIn(r *http.Request) bool {
	s, err := store.Get(r, "govwa")
	if err != nil {
		log.Println(err.Error())
	}
	if auth, ok := s.Values["govwa_session"].(bool); !ok || !auth {
		return false
	}
	return true
}