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

Author
5,552
Download Count*
License
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 Options struct.
Run Locally
Run in CI
Defintion
rules:
- id: session-cookie-missing-httponly
patterns:
- pattern-not-inside: |
&sessions.Options{
...,
HttpOnly: true,
...,
}
- pattern: |
&sessions.Options{
...,
}
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 Options struct.
metadata:
cwe:
- "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag"
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]
fix-regex:
regex: (HttpOnly\s*:\s+)false
replacement: \1true
severity: WARNING
languages:
- go
Examples
session-cookie-missing-httponly.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-httponly
session.Options = &sessions.Options{
Path: "/",
MaxAge: 3600,
HttpOnly: false, //set to false for xss :)
Secure: true,
}
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-httponly
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
}
Short Link: https://sg.run/4xJZ