Skip to content

fix: require a deployment-specific session signing secret - #1565

Open
28Hus wants to merge 12 commits into
apache:developfrom
28Hus:codex/fix-session-secret
Open

28Hus wants to merge 12 commits into
apache:developfrom
28Hus:codex/fix-session-secret

Conversation

@28Hus

@28Hus 28Hus commented Sep 21, 2026

Copy link
Copy Markdown

Summary

This pull request addresses Issue #1557.

Dubbo Admin uses a client-side signed session cookie for authentication. The signing key must therefore be deployment-specific and unpredictable. The current implementation still falls back to the publicly known value secret when no sessionSecret is configured. This leaves the default password-authentication path vulnerable to forged session cookies.

Root Cause

The OAuth/OIDC work in PR #1542 introduced the sessionSecret configuration field and changed the cookie store to use it. However, the same change also retained a legacy fallback:

const DefaultSessionSecret = "secret"

When the configuration does not contain a session secret, validation restores this public value. The minimum-length check is applied only to release deployments with external providers, so a password-only deployment can still start with the known signing key.

As a result, adding a configuration field alone does not remediate the original issue. The insecure fallback remains reachable in the default authentication path.

Changes

This pull request:

  • removes the hard-coded default session secret;
  • requires a deployment-specific session secret;
  • rejects missing or shorter-than-32-byte secrets during startup;
  • supports DUBBO_ADMIN_SESSION_SECRET for Kubernetes and secret-manager based deployments;
  • updates the local and OAuth/OIDC configuration examples;
  • updates the Kubernetes deployment example to read the secret from a Kubernetes Secret;
  • keeps the session secret masked in displayed configuration and startup logs;
  • adds regression tests for password authentication, missing secrets, short secrets, environment injection, and secret sanitization.

Security Behavior

After this change:

  • a deployment without a configured session secret fails closed during startup;
  • the historical public value secret is rejected because it is too short;
  • a valid session cookie remains usable across restarts when the same configured secret is retained;
  • changing the configured secret invalidates existing session cookies, which provides a straightforward key-rotation mechanism.

Usability and Future Improvements

The current change intentionally prioritizes a secure default over zero-configuration startup. Generating a new secret only in process memory would make sessions invalid after every restart and would cause authentication failures between replicas using different keys.

To improve usability in a future change, Dubbo Admin could provide an initialization command that generates a cryptographically secure secret once and persists it to a protected configuration file or external secret store. This would preserve stable sessions while keeping runtime startup fail-closed. Such an initialization flow should remain separate from the runtime fallback logic.

Scope

This pull request focuses on removing the predictable session signing key and preserving the existing signed-cookie session design. It does not redesign the application around a server-side session store or add session revocation. Those would be separate architectural changes.

Testing

The following checks pass locally:

go test ./...
go vet ./...
YAML configuration parsing
Frontend production build

Fixes #1557

This work is part of my ongoing research, and I am very pleased to make a small contribution to improving the security of Apache Dubbo Admin.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A console: null configuration bypasses validation and starts with an empty, forgeable signing key.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Hardens session-cookie signing by requiring a deployment-specific secret.

Changes:

  • Removes the insecure default and enforces a 32-byte minimum.
  • Supports environment-based secret injection.
  • Updates tests, examples, Kubernetes configuration, and documentation.
File Description
pkg/​config/​console/​auth/​config.go Validates and loads session secrets.
pkg/​config/​console/​auth/​config_test.go Tests secret validation and environment loading.
pkg/​config/​console/​config.go Removes the default signing secret.
pkg/​config/​console/​config_test.go Tests password and provider configurations.
app/​dubbo-admin/​dubbo-admin.yaml Documents required local configuration.
app/​dubbo-admin/​dubbo-admin-oauth-example.yaml Updates the OAuth example.
release/​kubernetes/​dubbo-system/​dubbo-admin.yaml Injects a Kubernetes Secret.
docs/​server-develop.md Documents secret generation and configuration.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/config/console/auth/config.go
Comment thread pkg/config/console/auth/config_test.go
Comment thread pkg/config/console/config_test.go
@robocanic

Copy link
Copy Markdown
Contributor

@28Hus please resolve the comments the copilot left and give feedbacks to me if there are any problems.

@28Hus

28Hus commented Sep 26, 2026

Copy link
Copy Markdown
Author

Copilot review overview

🟡 Changes recommended

A console: null configuration bypasses validation and starts with an empty, forgeable signing key.

Review effort: Balanced Findings: 1 High severity · 2 Medium severity

Open (3)

What changed in this PR
Hardens session-cookie signing by requiring a deployment-specific secret.

Changes:

  • Removes the insecure default and enforces a 32-byte minimum.
  • Supports environment-based secret injection.
  • Updates tests, examples, Kubernetes configuration, and documentation.

File Description
pkg/​config/​console/​auth/​config.go Validates and loads session secrets.
pkg/​config/​console/​auth/​config_test.go Tests secret validation and environment loading.
pkg/​config/​console/​config.go Removes the default signing secret.
pkg/​config/​console/​config_test.go Tests password and provider configurations.
app/​dubbo-admin/​dubbo-admin.yaml Documents required local configuration.
app/​dubbo-admin/​dubbo-admin-oauth-example.yaml Updates the OAuth example.
release/​kubernetes/​dubbo-system/​dubbo-admin.yaml Injects a Kubernetes Secret.
docs/​server-develop.md Documents secret generation and configuration.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@28Hus please resolve the comments the copilot left and give feedbacks to me if there are any problems.

@robocanic Thanks for the reminder; I am looking into it and planning to make changes.

@28Hus

28Hus commented Sep 26, 2026

Copy link
Copy Markdown
Author

@robocanic
Thanks for the review. I pushed follow-up commits addressing the configuration handling and test concerns.

Regarding the console: null finding: the claimed authentication bypass is inaccurate. In the reviewed revision, config.Load() calls AdminConfig.PreProcess() before Validate(), so a nil Console panics before execution can reach cookie.NewStore. Also, Gorilla securecookie rejects an empty hash key for cookie encoding and decoding. Nevertheless, I updated the code to handle this configuration explicitly and safely: missing or null console now fails closed during preprocessing, and an empty console object fails validation.

I also made the missing-secret tests deterministic by explicitly clearing DUBBO_ADMIN_SESSION_SECRET. Regression tests cover these cases. The full Go test suite, go vet, and local startup and authentication checks pass.

volumeMounts:
image: apache/dubbo-admin:0.7.0
imagePullPolicy: IfNotPresent
env:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: There is no secret defined in the deploy manifests. I think the secret defined in the ConfigMap is just fined, and if there is need to put it into secret, you need to bring up a new Secret Resource Definition.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. The dubbo-admin-auth Secret is created separately using the kubectl create secret generic command at the top of this manifest, before applying the Deployment. That command creates the Secret resource with a unique key for each installation. The Deployment then reads its session-secret key through secretKeyRef. We intentionally do not commit a Secret manifest containing a fixed signing key, since that would recreate the shared-key issue this PR fixes. Storing the signing key in the ConfigMap would also expose it as ordinary configuration data.
Of course, I have only considered the security aspect; regarding usability, we could later implement a feature that generates a strong, random key if the secret is missing from the YAML file.

@robocanic robocanic Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could later implement a feature that generates a strong, random key if the secret is missing from the YAML file.

Agree with that. The manifests in the directory is a one-stop deployment solution, so can you provide a solution more smoothly?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback. I pushed a one-command Kubernetes deployment flow: ./release/kubernetes/dubbo-system/deploy.sh. It generates a unique session signing Secret on first install, preserves it across redeployments, rejects an invalid existing Secret, and applies the manifests.
I verified fresh installation and redeployment in a local Kind cluster using an image built from this PR. The services became ready, authentication behaved as expected, and go test ./... passes.
The published apache/dubbo-admin:0.7.0 image does not contain this fix. The manifest must be updated to a newly published fixed image before this deployment flow is recommended to users.

@28Hus

28Hus commented Sep 30, 2026

Copy link
Copy Markdown
Author

@robocanic Hello, could you please let us know if this PR of ours can be approved? Feel free to contact me at any time; we are very willing to continue working on Dubbo-admin's security!

@robocanic
robocanic requested a balanced review from Copilot September 30, 2026 07:40
@robocanic

Copy link
Copy Markdown
Contributor

@robocanic Hello, could you please let us know if this PR of ours can be approved? Feel free to contact me at any time; we are very willing to continue working on Dubbo-admin's security!

please merge the develop branch and resolve the conflicts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The Kubernetes deployment still pins an image that does not use the injected signing secret.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (3)

image: apache/dubbo-admin:0.7.0
imagePullPolicy: IfNotPresent
volumeMounts:
image: apache/dubbo-admin:0.7.0
@sonarqubecloud

sonarqubecloud Bot commented Oct 1, 2026

Copy link
Copy Markdown

@28Hus

28Hus commented Oct 1, 2026

Copy link
Copy Markdown
Author

@robocanic Hello, could you please let us know if this PR of ours can be approved? Feel free to contact me at any time; we are very willing to continue working on Dubbo-admin's security!

please merge the develop branch and resolve the conflicts

@robocanic Thanks for the review. I’ve pushed a follow-up fix and merged the latest develop branch.
Copilot’s image finding was valid: injecting a Secret does not fix the published 0.7.0 image. Until an official image containing this fix is available, deploy.sh now requires an explicit image built from the fixed source. It rejects a missing image, 0.7.0, and latest before changing the cluster, then renders the supplied image into the Deployment before applying it. The README also warns against directly applying the manifest, which would bypass this check.
I tested the flow locally in Kind with an image built from this PR. The Deployment used the supplied image, the generated Secret remained stable across redeployments, valid login and session requests succeeded, and unauthenticated or invalid-cookie requests returned 401. go test ./... also passes. Once a fixed official image is published, the deployment can use that image as its safe default.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hard-coded session signing key allows authentication bypass in Go-based Dubbo Admin

3 participants