pgadmin-org / pgadmin-org/pgadmin4

Dead `usr` query parameter passed to sqleditor.connect_server never reaches the backend

Open Beginner friendly
#10,418 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
Dominant language
Python
Stars
3.8k
Forks
891
Avg merge
4d 7h
Merged PRs (30d)
8

Description

Please note that security bugs or issues should be reported to security@pgadmin.org.
(Not applicable here — this is not a security issue.)

Describe the bug

Three frontend call sites build the URL for sqleditor.connect_server with an extra
usr value, apparently intending to tell the backend which database user a password
retry is for:

  • web/pgadmin/tools/sqleditor/static/js/components/connectServer.js:40
  • web/pgadmin/misc/workspaces/static/js/AdHocConnection.jsx:362
  • web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx:235

All three call url_for('sqleditor.connect_server', {'sid': sid, ...(user ? {'usr': user} : {})}).

url_for() (web/pgadmin/static/js/url_for.js) only substitutes <...> placeholders that
appear in the Flask route template:

module.exports = function(endpoint, substitutions) {
  let rawURL = endpoints[endpoint];
  let substitutionGroupsRegExp = /(<)([^:^>]*:)?([^>]+)(>)/g,
    interpolated = rawURL;
  if (!rawURL) return rawURL;
  interpolated = interpolated.replace(substitutionGroupsRegExp, function(_origin, _1, _2, substitutionName) {
    if (substitutionName in substitutions) {
      return substitutions[substitutionName];
    }
    return _origin;
  });
  return interpolated;
};

Any key in substitutions that doesn't match a <placeholder> in the route template is
silently dropped — it is never appended as a query string, unlike Flask's own server-side
url_for(), which appends unmatched kwargs as ?key=value. The Flask route itself is:

@blueprint.route('/connect_server/<int:sid>', methods=["POST"], endpoint="connect_server")

— only <int:sid> is a placeholder, so usr is discarded before the request is even sent.
The backend's connect_server(sid) handler never reads a usr parameter either way.

To Reproduce

  1. In any of the three flows above (password re-prompt in the Query Tool, the ad-hoc
    Workspace "Existing Server" dialog, or the in-tool "New Connection" dialog), trigger a
    call to connectServer(...) with a user argument set.
  2. Inspect the actual outgoing request (e.g. browser DevTools Network tab, or add a
    console.log(url_for('sqleditor.connect_server', {sid, usr: 'someuser'}))).

Expected behavior

Either:

  • the constructed URL includes the intended user information (e.g. as a real query
    string parameter, with matching support added to url_for() and read server-side), or
  • the dead usr key is removed from all three call sites, since it currently does
    nothing and reads as though the backend is user-aware when it is not.

Error message

No error is raised — this is silent dead code, not a crash. console.log(url_for('sqleditor.connect_server', {sid: 6, usr: 'test'})) returns /sqleditor/connect_server/6 with no trace of usr.

Screenshots

N/A — not a visual bug.

Desktop (please complete the following information):

  • OS: N/A (code-level issue, reproducible on any platform)
  • pgAdmin version: confirmed present on master (commit 81edb68b, 2026-09-14)
  • Mode: Desktop and Server (affects both — the code path is shared)
  • Browser (if running in server mode): N/A
  • Package type: N/A

Additional context

Found while investigating an authentication bug in a downstream product built on
pgAdmin (Postgres Enterprise Manager / PEM-6245), where a fix initially assumed this
usr parameter reached the backend and could be used to route a password retry to the
correct database role. It doesn't, in either codebase — the actual fix there had to use
a different mechanism. Filing here since the same dead parameter exists unmodified in
pgAdmin itself. Low severity: it doesn't currently cause any incorrect behavior in
pgAdmin's own flows (upstream's ad-hoc connections clone the server per-role, so the
retry path works without needing usr), but the parameter is misleading dead code that
should either be wired up or removed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the three listed call sites—connectServer.js, AdHocConnection.jsx, and NewConnectionDialog.jsx—and compare them with static/js/url_for.js and the sqleditor.connect_server route. Reproduce the generated URL with a usr value, then confirm the selected outcome consistently removes the dead argument or wires it through the route and handler.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, javascript, python
Domain
api, full-stack
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.