Go / gorilla Cache Deception
cache_deception.go
package main
import (
"log"
"net/http"
"os"
"path/filepath"
"time"
"github.com/gorilla/mux"
)
// spaHandler implements the http.Handler interface, so we can use it
// to respond to HTTP requests. The path to the static directory and
// path to the index file within that static directory are used to
// serve the SPA in the given static directory.
type spaHandler struct {
staticPath string
indexPath string
}
// ServeHTTP inspects the URL path to locate a file within the static dir
// on the SPA handler. If a file is found, it will be served. If not, the
// file located at the index path on the SPA handler will be served. This
// is suitable behavior for serving an SPA (single page application).
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Join internally call path.Clean to prevent directory traversal
path := filepath.Join(h.staticPath, r.URL.Path)
// check whether a file exists or is a directory at the given path
fi, err := os.Stat(path)
if os.IsNotExist(err) || fi.IsDir() {
// file does not exist or path is a directory, serve index.html
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
return
}
if err != nil {
// if we got an error (that wasn't that the file doesn't exist) stating the
// file, return a 500 internal server error and stop
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// otherwise, use http.FileServer to serve the static file
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}
func main() {
router := mux.NewRouter()
spa := spaHandler{staticPath: "build", indexPath: "index.html"}
router.PathPrefix("/test/").Handler(spa)
srv := &http.Server{
Handler: router,
Addr: "127.0.0.1:8000",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
cache_deception_rule.yaml
rules:
- id: detect-generic-path-star-gorillamux
patterns:
- pattern-either:
- pattern: $Y.PathPrefix($X, ...)
- pattern-inside: |
import "github.com/gorilla/mux"
...
- metavariable-pattern:
metavariable: $X
patterns:
- pattern-either:
- pattern-regex: \/([\w]+)?\/
- pattern-regex: ^"\/"
message: Avoid using regex patterns with asterisk (*) in route handlers.
languages: [go]
severity: WARNING
metadata:
category: security
cwe: "CWE-525: Use of Web Browser Cache Containing Sensitive Information"
subcategory: [audit]
confidence: HIGH
impact: HIGH
technology: [golang, gorillamux]
description: "`Golang Gorilla Mux` Possible Web Cache Deception"