pgadmin-org / pgadmin-org/pgadmin4
LLM API requests followed HTTP redirects past the ALLOWED_LLM_API_URLS check
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.8k
- Forks
- 891
- Avg merge
- 4d 7h
- Merged PRs (30d)
- 8
Description
Summary
pgAdmin 4 validates the configured LLM API endpoint against ALLOWED_LLM_API_URLS, but the providers then issued the request through urllib.request.urlopen(), whose default handler follows a Location header. The allowlist was therefore applied only to the URL pgAdmin was configured with, not to any destination a redirect led on to.
No legitimate LLM API replies with a redirect, so redirects are now refused outright rather than each hop being re-validated. urlopen_no_redirect() installs a handler that raises HTTPError instead, and the outbound calls in all four providers and in the model-refresh endpoints go through it.
A follow-up in the same change maps http_error_308 onto http_error_301, exactly as Python 3.11 itself does. HTTPRedirectHandler only gained http_error_308() in 3.11, so on the 3.9 and 3.10 interpreters pgAdmin still supports a 308 was never recognised as a redirect and surfaced as a bare HTTP Error 308: Permanent Redirect. The redirect was still not followed, so this was never a security gap, but the caller got no explanation of why the request had failed.
Not a CVE
This is hardening rather than a fix for an exploitable flaw: returning the redirect in the first place requires control of a host that is already on the operator's allowlist. No CVE has been requested.
Affected versions
pgAdmin 4 >= 9.15, < 9.18. ALLOWED_LLM_API_URLS was introduced in 9.15, so there was no allowlist for a redirect to bypass before then.
Fix
Fixed in pgAdmin 4 9.18 by commit 9a009fd2b.
Credit
Reported by Ziya Abdullayev.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating urlopen_no_redirect(), the outbound calls in the four providers, and the model-refresh endpoints described in the issue. Verify that redirects are refused and that HTTP 308 errors receive the same handling as HTTP 301 on the supported Python versions; the issue states this was fixed in commit 9a009fd2b.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100