GHSA-xq32-9g7q-7297 — flaskbb
MEDIUMGHSA-xq32-9g7q-7297 is a medium-severity (CVSS 6.5) Server-Side Request Forgery (SSRF) vulnerability in flaskbb. No vendor fix is recorded yet; mitigation options are listed below.
FlaskBB: SSRF in get_image_info() via unrestricted avatar URL
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
Exploitation and automatability from CISA’s SSVC triage for GHSA-xq32-9g7q-7297.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
GHSA-xq32-9g7q-7297 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 382,205 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
flaskbbReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
###Summary A Server-Side Request Forgery (SSRF) vulnerability in get_image_info() allows any authenticated user to force the server to send HTTP requests to arbitrary internal endpoints, including cloud metadata services (e.g., AWS 169.254.169.254). This is a blind SSRF with confirmed internal port scanning and internal API triggering capabilities. CVSS 6.5 Medium.
###Details In flaskbb/utils/helpers.py (line 571), the url parameter is passed directly to requests.get(url, stream=True) without any validation of scheme, host, or IP address.
python# flaskbb/utils/helpers.py:571
def get_image_info(url: str):
r = requests.get(url, timeout=(3.05, 27), stream=True)
Attack chain:
POST /user/settings/user-details (avatar URL)
→ ValidateAvatarURL.validate() # validators.py:103
→ check_image(avatar) # helpers.py:628
→ get_image_info(url) # helpers.py:571
→ requests.get(url) # No domain/IP restriction
Entry points:
/user/settings/user-details (any authenticated user)
/admin/users/<id>/edit (admin only)
###PoC submit.zip
Log in to FlaskBB as any user Navigate to Settings → User Details Enter http://169.254.169.254/latest/meta-data/ as the avatar URL Submit the form The server sends a GET request to the internal metadata endpoint
Three exploitation channels confirmed:
Server-side request: Captured on mock metadata server Internal port scan: check_image() returns distinct errors (CONN_REFUSED, NO_CONTENT_LENGTH, TYPE_NOT_ALLOWED, SUCCESS) that map internal network topology Internal API triggering: Mock APIs on 127.0.0.1:9200 triggered via SSRF (deploy, shutdown, key dump endpoints)
###Impact Any authenticated user is impacted. Attackers can force the server to request internal services, cloud metadata endpoints, or private network resources. On cloud deployments (AWS/GCP/Azure), IAM credentials can be leaked. In production, any GET-triggered internal service is reachable: CI/CD webhooks, Elasticsearch, etcd, Consul, etc.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | flaskbb | all versions | No fix |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for flaskbb, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Remediation status
No patched version of flaskbb has shipped for GHSA-xq32-9g7q-7297 yet. Where your build allows, override or pin the dependency away from the vulnerable range, and apply any maintainer-recommended mitigation.
Mitigate without a patch
Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.
Frequently Asked Questions
Is GHSA-xq32-9g7q-7297 in your dependencies?
Find it across PyPI, including transitive dependencies.