go.lang.security.audit.net.cookie-missing-httponly.cookie-missing-httponly

profile photo of semgrepsemgrep
Author
5,552
Download Count*

A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie.

Run Locally

Run in CI

Defintion

rules:
  - id: cookie-missing-httponly
    patterns:
      - pattern-not-inside: |
          http.Cookie{
            ...,
            HttpOnly: true,
            ...,
          }
      - pattern: |
          http.Cookie{
            ...,
          }
    message: A session cookie was detected without setting the 'HttpOnly' flag. The
      'HttpOnly' flag for cookies instructs the browser to forbid client-side
      scripts from reading the cookie which mitigates XSS attacks. Set the
      'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie.
    metadata:
      cwe:
        - "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag"
      owasp:
        - A05:2021 - Security Misconfiguration
      references:
        - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go
        - https://golang.org/src/net/http/cookie.go
      category: security
      technology:
        - go
      confidence: MEDIUM
      subcategory:
        - vuln
      likelihood: LOW
      impact: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cookie Security
    fix-regex:
      regex: (HttpOnly\s*:\s+)false
      replacement: \1true
    severity: WARNING
    languages:
      - go

Examples

cookie-missing-httponly.go

// cf. https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go

package util

import (
	"net/http"
	"time"
)

func SetCookieLevel(w http.ResponseWriter, r *http.Request, cookievalue string){

	level := cookievalue
	if level == "" {
		level = "low"
	}
	SetCookie(w,"Level",level)

}

func CheckLevel(r *http.Request) bool {
	level := GetCookie(r, "Level")
	if level == "" || level == "low" {
		return false //set default level to low
	} else if level == "high" {
		return true //level == high
	} else {
		return false // level == low
	}
}

/* cookie setter getter */

func SetCookie(w http.ResponseWriter, name, value string){
    // ruleid: cookie-missing-httponly
	cookie := http.Cookie{
		Name: name,
		Value: value,
	}
	http.SetCookie(w, &cookie)
}

func SetSecureCookie(w http.ResponseWriter, name, value string){
    // ok: cookie-missing-httponly
	cookie := http.Cookie{
        Secure: true,
        HttpOnly: true,
		Name: name,
		Value: value,
	}
	http.SetCookie(w, &cookie)
}

func GetCookie(r *http.Request, name string)string{
	cookie, _ := r.Cookie(name)
	return cookie.Value
}

func DeleteCookie(w http.ResponseWriter, cookies []string){
	for _,name := range cookies{
        // ruleid: cookie-missing-httponly
		cookie := &http.Cookie{
			Name:     name,
			Value:    "",
			Expires: time.Unix(0, 0),
		}
		http.SetCookie(w, cookie)
	}
}