diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8f71793 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,55 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + list-challenges: + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + steps: + - uses: actions/checkout@v4 + + - id: set-matrix + run: echo "matrix=$(ls challenges/ | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT + + docker-build-push: + needs: list-challenges + runs-on: ubuntu-latest + + permissions: + packages: write + + strategy: + matrix: + challenge: ${{ fromJson(needs.list-challenges.outputs.matrix) }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: ./challenges/${{ matrix.challenge }} + push: ${{ github.ref == 'refs/heads/main' }} + tags: ghcr.io/cerberauth/api-vulns-challenges/${{ matrix.challenge }}:latest + cache-from: type=registry,ref=ghcr.io/cerberauth/api-vulns-challenges/${{ matrix.challenge }}:latest + cache-to: type=inline diff --git a/challenges/jwt-alg-none-bypass/Dockerfile b/challenges/jwt-alg-none-bypass/Dockerfile new file mode 100644 index 0000000..bac1489 --- /dev/null +++ b/challenges/jwt-alg-none-bypass/Dockerfile @@ -0,0 +1,23 @@ +FROM golang:1.21 AS builder + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . ./ + +RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -o /jwt-alg-none-bypass . + +FROM gcr.io/distroless/static-debian11:nonroot AS runner + +WORKDIR / + +COPY --from=builder --chown=nonroot:nonroot /jwt-alg-none-bypass /usr/bin/jwt-alg-none-bypass + +EXPOSE 8080 + +USER nonroot:nonroot + +ENTRYPOINT ["jwt-alg-none-bypass", "serve"] +CMD ["jwt-alg-none-bypass"] diff --git a/challenges/jwt-alg-none-bypass/serve/server.go b/challenges/jwt-alg-none-bypass/serve/server.go index a6dad43..4624a8e 100644 --- a/challenges/jwt-alg-none-bypass/serve/server.go +++ b/challenges/jwt-alg-none-bypass/serve/server.go @@ -31,7 +31,7 @@ func RunServer() { } if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { - return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte("my_secret_key"), nil @@ -45,6 +45,5 @@ func RunServer() { } }) - log.Println("starting server") log.Fatal(http.ListenAndServe(":8080", nil)) } diff --git a/challenges/jwt-weak-hmac-secret/Dockerfile b/challenges/jwt-weak-hmac-secret/Dockerfile new file mode 100644 index 0000000..09e7450 --- /dev/null +++ b/challenges/jwt-weak-hmac-secret/Dockerfile @@ -0,0 +1,23 @@ +FROM golang:1.21 AS builder + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . ./ + +RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -o /jwt-weak-hmac-secret . + +FROM gcr.io/distroless/static-debian11:nonroot AS runner + +WORKDIR / + +COPY --from=builder --chown=nonroot:nonroot /jwt-weak-hmac-secret /usr/bin/jwt-weak-hmac-secret + +EXPOSE 8080 + +USER nonroot:nonroot + +ENTRYPOINT ["jwt-weak-hmac-secret", "serve"] +CMD ["jwt-weak-hmac-secret"] diff --git a/challenges/jwt-weak-hmac-secret/serve/server.go b/challenges/jwt-weak-hmac-secret/serve/server.go index 21b201d..b1fae8d 100644 --- a/challenges/jwt-weak-hmac-secret/serve/server.go +++ b/challenges/jwt-weak-hmac-secret/serve/server.go @@ -26,7 +26,7 @@ func RunServer() { 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 nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte("secret"), nil @@ -40,6 +40,5 @@ func RunServer() { } }) - log.Println("starting server") log.Fatal(http.ListenAndServe(":8080", nil)) }