Skip to content

Commit

Permalink
refactor: move jwt generation in the challenges and create commands
Browse files Browse the repository at this point in the history
  • Loading branch information
emmanuelgautier committed Sep 30, 2023
1 parent 846d267 commit eb66676
Show file tree
Hide file tree
Showing 20 changed files with 313 additions and 121 deletions.
14 changes: 14 additions & 0 deletions challenges/jwt-alg-none-bypass/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

jwt-alg-none-bypass
26 changes: 26 additions & 0 deletions challenges/jwt-alg-none-bypass/cmd/jwt/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package jwt

import (
"fmt"
"log"

"github.com/golang-jwt/jwt/v5"
"github.com/spf13/cobra"
)

func NewJwtCmd() (jwtCmd *cobra.Command) {
jwtCmd = &cobra.Command{
Use: "jwt",
Run: func(cmd *cobra.Command, args []string) {
token := jwt.New(jwt.SigningMethodNone)
tokenString, err := token.SignedString(jwt.UnsafeAllowNoneSignatureType)
if err != nil {
log.Fatal(err)
}

fmt.Printf("Token example: %s", tokenString)
},
}

return jwtCmd
}
29 changes: 29 additions & 0 deletions challenges/jwt-alg-none-bypass/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import (
"os"

"github.com/cerberauth/vulns-challenges/challenges/jwt-alg-none-bypass/cmd/jwt"
"github.com/cerberauth/vulns-challenges/challenges/jwt-alg-none-bypass/cmd/serve"

"github.com/spf13/cobra"
)

func NewRootCmd() (cmd *cobra.Command) {
var rootCmd = &cobra.Command{}

rootCmd.AddCommand(serve.NewServeCmd())
rootCmd.AddCommand(jwt.NewJwtCmd())

return rootCmd
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the RootCmd.
func Execute() {
c := NewRootCmd()

if err := c.Execute(); err != nil {
os.Exit(1)
}
}
18 changes: 18 additions & 0 deletions challenges/jwt-alg-none-bypass/cmd/serve/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package serve

import (
"github.com/spf13/cobra"

"github.com/cerberauth/vulns-challenges/challenges/jwt-alg-none-bypass/serve"
)

func NewServeCmd() (serveCmd *cobra.Command) {
serveCmd = &cobra.Command{
Use: "serve",
Run: func(cmd *cobra.Command, args []string) {
serve.RunServer()
},
}

return serveCmd
}
10 changes: 9 additions & 1 deletion challenges/jwt-alg-none-bypass/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ module github.com/cerberauth/vulns-challenges/challenges/jwt-alg-none-bypass

go 1.20

require github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
require (
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/spf13/cobra v1.7.0
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
10 changes: 10 additions & 0 deletions challenges/jwt-alg-none-bypass/go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
48 changes: 2 additions & 46 deletions challenges/jwt-alg-none-bypass/main.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,7 @@
package main

import (
"fmt"
"log"
"net/http"
"strings"

"github.com/golang-jwt/jwt/v5"
)
import "github.com/cerberauth/vulns-challenges/challenges/jwt-alg-none-bypass/cmd"

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
w.WriteHeader(401)
return
}

parts := strings.Split(authorizationHeader, "Bearer")
if len(parts) != 2 {
w.WriteHeader(401)
return
}

tokenString := strings.TrimSpace(parts[1])
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// fake vulnerability
if token.Method.Alg() == "none" {
return jwt.UnsafeAllowNoneSignatureType, nil
}

if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}

return []byte("my_secret_key"), nil
})

if token != nil && token.Valid {
w.WriteHeader(204)
} else {
fmt.Println(err)
w.WriteHeader(401)
}
})

if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
cmd.Execute()
}
50 changes: 50 additions & 0 deletions challenges/jwt-alg-none-bypass/serve/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package serve

import (
"fmt"
"log"
"net/http"
"strings"

"github.com/golang-jwt/jwt/v5"
)

func RunServer() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
w.WriteHeader(401)
return
}

parts := strings.Split(authorizationHeader, "Bearer")
if len(parts) != 2 {
w.WriteHeader(401)
return
}

tokenString := strings.TrimSpace(parts[1])
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// fake vulnerability
if token.Method.Alg() == "none" {
return jwt.UnsafeAllowNoneSignatureType, nil
}

if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}

return []byte("my_secret_key"), nil
})

if token != nil && token.Valid {
w.WriteHeader(204)
} else {
fmt.Println(err)
w.WriteHeader(401)
}
})

log.Println("starting server")
log.Fatal(http.ListenAndServe(":8080", nil))
}
14 changes: 14 additions & 0 deletions challenges/jwt-weak-hmac-secret/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

jwt-weak-hmac-secret
26 changes: 26 additions & 0 deletions challenges/jwt-weak-hmac-secret/cmd/jwt/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package jwt

import (
"fmt"
"log"

"github.com/golang-jwt/jwt/v5"
"github.com/spf13/cobra"
)

func NewJwtCmd() (jwtCmd *cobra.Command) {
jwtCmd = &cobra.Command{
Use: "jwt",
Run: func(cmd *cobra.Command, args []string) {
token := jwt.New(jwt.SigningMethodHS256)
tokenString, err := token.SignedString([]byte("secret"))
if err != nil {
log.Fatal(err)
}

fmt.Printf("Token example: %s", tokenString)
},
}

return jwtCmd
}
29 changes: 29 additions & 0 deletions challenges/jwt-weak-hmac-secret/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import (
"os"

"github.com/cerberauth/vulns-challenges/challenges/jwt-weak-hmac-secret/cmd/jwt"
"github.com/cerberauth/vulns-challenges/challenges/jwt-weak-hmac-secret/cmd/serve"

"github.com/spf13/cobra"
)

func NewRootCmd() (cmd *cobra.Command) {
var rootCmd = &cobra.Command{}

rootCmd.AddCommand(serve.NewServeCmd())
rootCmd.AddCommand(jwt.NewJwtCmd())

return rootCmd
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the RootCmd.
func Execute() {
c := NewRootCmd()

if err := c.Execute(); err != nil {
os.Exit(1)
}
}
18 changes: 18 additions & 0 deletions challenges/jwt-weak-hmac-secret/cmd/serve/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package serve

import (
"github.com/spf13/cobra"

"github.com/cerberauth/vulns-challenges/challenges/jwt-weak-hmac-secret/serve"
)

func NewServeCmd() (serveCmd *cobra.Command) {
serveCmd = &cobra.Command{
Use: "serve",
Run: func(cmd *cobra.Command, args []string) {
serve.RunServer()
},
}

return serveCmd
}
10 changes: 9 additions & 1 deletion challenges/jwt-weak-hmac-secret/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ module github.com/cerberauth/vulns-challenges/challenges/jwt-weak-hmac-secret

go 1.20

require github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
require (
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/spf13/cobra v1.7.0
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
12 changes: 12 additions & 0 deletions challenges/jwt-weak-hmac-secret/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
43 changes: 2 additions & 41 deletions challenges/jwt-weak-hmac-secret/main.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,7 @@
package main

import (
"fmt"
"log"
"net/http"
"strings"

"github.com/golang-jwt/jwt/v5"
)
import "github.com/cerberauth/vulns-challenges/challenges/jwt-weak-hmac-secret/cmd"

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
w.WriteHeader(401)
return
}

parts := strings.Split(authorizationHeader, "Bearer")
if len(parts) != 2 {
w.WriteHeader(401)
return
}

tokenString := strings.TrimSpace(parts[1])
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}

return []byte("secret"), nil
})

if token != nil && token.Valid {
w.WriteHeader(204)
} else {
fmt.Println(err)
w.WriteHeader(401)
}
})

if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
cmd.Execute()
}
Loading

0 comments on commit eb66676

Please sign in to comment.