Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.sh text eol=lf
.github.workflows.trivy-analysis.yaml text eol=lf
51 changes: 51 additions & 0 deletions .github/workflows/trivy-analysis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Trivy Analysis

permissions:
contents: read
actions: read
security-events: write

on:
pull_request:
workflow_dispatch:
push:
schedule:
- cron: '0 0 1 */3 *'

env:
SARIF_FILE: 'trivy-results.sarif'

jobs:
build:
name: Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Run Trivy vulnerability scanner on the cloned repository files
uses: aquasecurity/trivy-action@0.33.1
with:
version: 'v0.67.2'
scan-type: 'fs'
scanners: 'vuln,misconfig,secret,license'
ignore-unfixed: true
format: 'sarif'
output: ${{ env.SARIF_FILE }}
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'

- name: Check Trivy scan results existence
run: |
if [ ! -f "${{ env.SARIF_FILE }}" ]; then
echo "Error: ${{ env.SARIF_FILE }} does not exist."
exit 1
fi
ls -lash ${{ env.SARIF_FILE }}

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4.31.6
with:
sarif_file: ${{ env.SARIF_FILE }}



21 changes: 17 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
FROM n0madic/alpine-gcc:9.2.0
RUN apk add --quiet --no-cache libressl-dev
FROM frolvlad/alpine-gcc:latest
# Update packages to get latest security fixes for OpenSSL (CVE-2025-9230, CVE-2025-9231, CVE-2025-9232)
RUN apk update && apk upgrade --no-cache && apk add --quiet --no-cache libressl-dev make

# Create non-root user and group
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

COPY ./*.h /opt/src/
COPY ./*.c /opt/src/
COPY Makefile /opt/src/
COPY entrypoint.sh /
#RUN apt-get install libssl-dev

WORKDIR /opt/src
# Note: Only need one make command on Alpine Linux (macOS paths removed)
RUN make
RUN make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib
RUN ["chmod", "+x", "/entrypoint.sh"]
RUN ["chmod", "+x", "/opt/src/jwtcrack"]

# Change ownership to non-root user
RUN chown -R appuser:appgroup /opt/src /entrypoint.sh

USER appuser

HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 CMD ["/opt/src/jwtcrack", "--version"] || exit 1

ENTRYPOINT ["/entrypoint.sh"]
22 changes: 22 additions & 0 deletions Dockerfile.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM frolvlad/alpine-gcc:latest
# Update packages to get latest security fixes for OpenSSL (CVE-2025-9230, CVE-2025-9231, CVE-2025-9232)
RUN apk update && apk upgrade --no-cache && apk add --quiet --no-cache libressl-dev make valgrind bash coreutils

# Create non-root user for security (AVD-DS-0002)
RUN addgroup -S testgroup && adduser -S testuser -G testgroup

COPY ./*.h /opt/src/
COPY ./*.c /opt/src/
COPY Makefile /opt/src/
COPY test_security.sh /opt/src/

WORKDIR /opt/src

# Build with debug symbols for better Valgrind output
RUN make CFLAGS="-g -O0"
RUN chmod +x /opt/src/test_security.sh
RUN chown -R testuser:testgroup /opt/src

USER testuser

CMD ["/opt/src/test_security.sh"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CC = gcc
OPENSSL = /usr/include/openssl
OPENSSL_LIB = -lssl

CFLAGS += -I $(OPENSSL) -g -std=gnu99 -O3
CFLAGS += -I $(OPENSSL) -g -std=gnu99 -O3 -march=native -mtune=native
LDFLAGS += $(OPENSSL_LIB) -lcrypto -lpthread

NAME = jwtcrack
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ docker build . -t jwtcrack
docker run -it --rm jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
```

## Testing with Docker

Build and run the test image which includes Valgrind for memory leak detection:

```
docker build -f Dockerfile.test -t jwtcrack-test .
docker run --rm jwtcrack-test
```

This runs a functional test with 20 threads and a Valgrind memory check.

## Manual Compilation

Make sure you have openssl's headers installed.
Expand Down Expand Up @@ -78,6 +89,6 @@ $ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJyb2xlIjoiYWRtaW4ifQ.31xCH
## IMPORTANT: Known bugs

The base64 implementation I use (from Apple) is sometimes buggy because not every Base64 implementation is the same.
So sometimes, decrypting of your Base64 token will only work partially and thus you will be able to find a secret to your token that is not the correct one.
So sometimes, decrypting your Base64 token will only work partially and thus you will be able to find a secret to your token that is not the correct one.

If someone is willing to implement a more robust Base64 implementation, that would be great :)
6 changes: 4 additions & 2 deletions base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@
#include "base64.h"

/* aaaack but it's fast and const should make it shared text page. */
/* Modified to support both Base64 (+/) and Base64URL (-_) per RFC 4648 */
static const unsigned char pr2six[256] =
{
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 63,
/* sp ! " # $ % & ' ( ) * + , - . / */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 62, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63,
Expand Down Expand Up @@ -149,7 +151,7 @@ int Base64decode(char *bufplain, const char *bufcoded)
nprbytes -= 4;
}

/* Note: (nprbytes == 1) would be an error, so just ingore that case */
/* Note: (nprbytes == 1) would be an error, so just ignore that case */
if (nprbytes > 1) {
*(bufout++) =
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
Expand Down
4 changes: 2 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
/opt/src/jwtcrack $@
#!/bin/sh
/opt/src/jwtcrack "$@"
Loading