Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
A console: null configuration bypasses validation and starts with an empty, forgeable signing key.
Review effort: Balanced
Findings: 1
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.
| if strings.TrimSpace(c.SessionSecret) == "" { | ||
| c.SessionSecret = os.Getenv(SessionSecretEnvVar) | ||
| } | ||
| if strings.TrimSpace(c.SessionSecret) == "" || len([]byte(c.SessionSecret)) < MinimumSessionSecretLength { | ||
| return fmt.Errorf("auth: sessionSecret must contain at least %d bytes", MinimumSessionSecretLength) |
There was a problem hiding this comment.
Thanks for flagging this. However, the claimed authentication bypass is a false positive. In the reviewed revision, config.Load() invokes AdminConfig.PreProcess() before Validate(). With console: null, c.Console.PreProcess() panics on the nil pointer, so execution never reaches cookie.NewStore. In addition, Gorilla securecookie treats an empty hash key as unset and rejects cookie encoding and decoding; it cannot be used to forge a session.
I have since changed this path to fail closed explicitly: missing or null console configuration is rejected during preprocessing, and an empty console object is rejected during validation. Regression tests cover these cases, including when a valid session-secret environment variable is set.
| } | ||
|
|
||
| func TestConfigValidateRequiresSessionSecret(t *testing.T) { | ||
| cfg := validConfig() |
| } | ||
|
|
||
| func TestPasswordAuthenticationRequiresStrongSessionSecret(t *testing.T) { | ||
| cfg := DefaultConsoleConfig() |
|
@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. |
|
|
@robocanic 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: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?





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
secretwhen nosessionSecretis configured. This leaves the default password-authentication path vulnerable to forged session cookies.Root Cause
The OAuth/OIDC work in PR #1542 introduced the
sessionSecretconfiguration field and changed the cookie store to use it. However, the same change also retained a legacy fallback: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:
DUBBO_ADMIN_SESSION_SECRETfor Kubernetes and secret-manager based deployments;Security Behavior
After this change:
secretis rejected because it is too short;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:
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.