go.jwt-go.security.jwt.hardcoded-jwt-key

Verifed by r2c
Community Favorite
profile photo of semgrepsemgrep
Author
178,848
Download Count*

A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).

Run Locally

Run in CI

Defintion

rules:
  - id: hardcoded-jwt-key
    message: A hard-coded credential was detected. It is not recommended to store
      credentials in source-code, as this risks secrets being leaked and used by
      either an internal or external malicious adversary. It is recommended to
      use environment variables to securely provide credentials or retrieve
      credentials from a secure vault or HSM (Hardware Security Module).
    options:
      interfile: true
    metadata:
      cwe:
        - "CWE-798: Use of Hard-coded Credentials"
      references:
        - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
      owasp:
        - A07:2021 - Identification and Authentication Failures
      category: security
      technology:
        - jwt
        - secrets
      confidence: MEDIUM
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: HIGH
      impact: MEDIUM
      interfile: true
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Hard-coded Secrets
    severity: WARNING
    languages:
      - go
    mode: taint
    pattern-sources:
      - patterns:
          - pattern-inside: |
              []byte("$F")
    pattern-sinks:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  $TOKEN.SignedString($F)
          - focus-metavariable: $F

Examples

jwt.go

// https://www.sohamkamani.com/blog/golang/2019-01-01-jwt-authentication/
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
)

//...
// import the jwt-go library

//...

var users = map[string]string{
	"user1": "password1",
	"user2": "password2",
}

// Create a struct to read the username and password from the request body
type Credentials struct {
	Password string `json:"password"`
	Username string `json:"username"`
}

// Create a struct that will be encoded to a JWT.
// We add jwt.StandardClaims as an embedded type, to provide fields like expiry time
type Claims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

// Create the Signin handler
func Signin(w http.ResponseWriter, r *http.Request) {

	// Create the JWT key used to create the signature
	var jwtKey = []byte("my_secret_key")
	var x = "foo"

	var creds Credentials
	// Get the JSON body and decode into credentials
	err := json.NewDecoder(r.Body).Decode(&creds)
	if err != nil {
		// If the structure of the body is wrong, return an HTTP error
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	// Get the expected password from our in memory map
	expectedPassword, ok := users[creds.Username]

	// If a password exists for the given user
	// AND, if it is the same as the password we received, the we can move ahead
	// if NOT, then we return an "Unauthorized" status
	if !ok || expectedPassword != creds.Password {
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	// Declare the expiration time of the token
	// here, we have kept it as 5 minutes
	expirationTime := time.Now().Add(5 * time.Minute)
	// Create the JWT claims, which includes the username and expiry time
	claims := &Claims{
		Username: creds.Username,
		StandardClaims: jwt.StandardClaims{
			// In JWT, the expiry time is expressed as unix milliseconds
			ExpiresAt: expirationTime.Unix(),
		},
	}

	// Declare the token with the algorithm used for signing, and the claims
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// ruleid: hardcoded-jwt-key
	tokenString, err := token.SignedString(jwtKey)
	// ruleid: hardcoded-jwt-key
	tokenString, err := token.SignedString([]byte("my_secret_key"))
	if err != nil {
		// If there is an error in creating the JWT return an internal server error
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	// Finally, we set the client cookie for "token" as the JWT we just generated
	// we also set an expiry time which is the same as the token itself
	http.SetCookie(w, &http.Cookie{
		Name:    "token",
		Value:   tokenString,
		Expires: expirationTime,
	})


}