Skip to content

[Security] Flask SECRET_KEY falls back to a public value, enabling session forgery #175

Description

@28Hus

Flask SECRET_KEY falls back to a public value, enabling session forgery

Hello ydf0509,

When FUNWEB_SECRET_KEY is unset, Funboost signs Flask session cookies with the public fallback mtfy54321. An attacker can forge a Flask-Login session for a configured account and bypass its password check.

Evidence

Image
  • funboost/funweb/app.py:58 sets app.secret_key = os.getenv('FUNWEB_SECRET_KEY', "mtfy54321"). The environment override exists, but startup does not reject a missing or default value.
  • start_funboost_web_manager defaults to host="0.0.0.0" and port=27018, exposing the manager on all interfaces when started with defaults.
  • load_user checks the supplied ID against the in-memory users list, then returns a User. It does not check whether the session was issued by a successful login or is still valid on the server. The default list contains the admin account.
  • The application and its management blueprints protect routes with @login_required, including /deploy/save and /deploy/<name>/start. The deploy handler stores the caller's start_cmd; _start_process executes it with subprocess.Popen(..., shell=True).
  • Flask's default session interface stores signed session data in the client cookie. The application does not configure a server-side session store or access-token revocation state.

Proof of concept

Static reproduction steps for a deployment using the fallback key (not run against a live deployment): sign a Flask-Login session for the default admin account, then use it on a protected route:

COOKIE=$(flask-unsign --sign \
  --cookie "{'_user_id':'admin','_fresh':True}" \
  --secret 'mtfy54321')

curl -i -H "Cookie: session=$COOKIE" http://<host>:27018/

The root route accepts the authenticated session. With the same cookie, an attacker can call /deploy/save to store a deployment command and /deploy/<name>/start to execute it as the Funboost web process. The deployment routes require the application's Redis-backed deploy configuration to be available.

Impact

An attacker who can reach the web manager and knows an account ID in its configured in-memory user list can bypass that account's password and use its authenticated routes. With the default account list, admin is a known ID. The deploy management routes can turn this into command execution with the web process's privileges when that feature's Redis backend is configured.

Remediation

The code already supports FUNWEB_SECRET_KEY. Require it at startup for deployments and reject mtfy54321 and other placeholders. Use a unique high-entropy value, and rotate it to invalidate cookies signed with the fallback.

Prior disclosure check

On September 28, 2026, I checked public open and closed Issues and pull requests, searched their indexed text for mtfy54321, FUNWEB_SECRET_KEY, Flask, session, and security terms, and checked the repository's published advisories and security policy files. I found no prior public report for this finding. GitHub Discussions are disabled; private disclosures are outside this check.

Related works

This report is part of my ongoing security research. Please feel free to @mention me if you have any questions. I would be glad to make a small contribution to the security of Funboost.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions