Skip to content

Bug: OAuth client secret inconsistency between UI copy value, request payload, and persisted DB value #3337

@hatsuyuki280

Description

@hatsuyuki280

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
  • Please do not modify this template :) and fill in all the required fields.

Cloudreve version

4.14.1 #50349bf

Pro or Community Edition

Pro

Database type

MySQL

Browser and operating system

Chrome 145.0.7632.76

Steps to reproduce

Describe the bug

When creating a custom OAuth client from the admin web UI, the secret value is inconsistent across different stages:

  1. Secret shown/copied in UI
  2. Secret sent in request payload (PUT /api/v4/admin/oauthClient, client.secret)
  3. Secret persisted in DB (oauth_clients.secret)

These values should represent one final secret for the same client, but they differ.
As a result, using the UI-copied secret can fail token exchange with Invalid client secret.

To Reproduce

  1. Go to Admin -> OAuth -> New.
  2. Click Refresh for secret and copy the displayed value.
  3. Submit creation.
  4. In browser network tab, inspect:
    • PUT /api/v4/admin/oauthClient request body (client.secret present)
    • GET /api/v4/admin/oauthClient/{id} response (metadata only, no secret)
  5. Query DB table oauth_clients for the created row by guid.
  6. Compare values from UI copy / request payload / DB persisted secret.

Environment

  • Cloudreve version: v4.14.1 Pro
  • Browser: Chrome 145 on macOS
  • DB: MySQL
  • Reverse proxy/CDN: Cloudflare

Additional context

  • I can provide HAR/timestamps privately.
  • Secrets/tokens are redacted in this report for security.
  • This appears to be a server-side consistency issue in create/refresh/persist flow, not a client OAuth parameter typo.

✔️ Expected Behavior

For one created OAuth client, secret must be deterministic and consistent:

  • either backend persists submitted client.secret,
  • or backend generates one and returns that exact persisted value once for copy.

In all cases, the secret users copy from UI should be the same value used by server validation.

❌ Actual Behavior

For a newly created client:

  • UI copied secret != request payload secret OR
  • request payload secret != DB persisted secret

Observed created client example:

  • id=6
  • guid=32bea26d-43c9-40d9-8493-31405c4cb557
  • PUT /api/v4/admin/oauthClient succeeded (code=0)
  • DB row exists, but persisted oauth_clients.secret does not match expected copied value

Addition context information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions