{"id":"CVE-2026-46556","aliases":["GHSA-xq32-9g7q-7297","PYSEC-2026-2479"],"url":"https://o3.security/vulnerability/CVE-2026-46556","summary":"FlaskBB: SSRF in get_image_info() via unrestricted avatar URL","details":"###Summary\nA 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.\n\n###Details\nIn 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.\n```\npython# flaskbb/utils/helpers.py:571\ndef get_image_info(url: str):\n    r = requests.get(url, timeout=(3.05, 27), stream=True)\n```\n\nAttack chain:\n\n```\nPOST /user/settings/user-details (avatar URL)\n→ ValidateAvatarURL.validate()    # validators.py:103\n→ check_image(avatar)             # helpers.py:628\n→ get_image_info(url)             # helpers.py:571\n→ requests.get(url)               # No domain/IP restriction\nEntry points:\n\n/user/settings/user-details (any authenticated user)\n/admin/users/<id>/edit (admin only)\n\n```\n\n###PoC\n[submit.zip](https://github.com/user-attachments/files/26301527/submit.zip)\n\nLog in to FlaskBB as any user\nNavigate to Settings → User Details\nEnter http://169.254.169.254/latest/meta-data/ as the avatar URL\nSubmit the form\nThe server sends a GET request to the internal metadata endpoint\n\nThree exploitation channels confirmed:\n\nServer-side request: Captured on mock metadata server\nInternal port scan: check_image() returns distinct errors (CONN_REFUSED, NO_CONTENT_LENGTH, TYPE_NOT_ALLOWED, SUCCESS) that map internal network topology\nInternal API triggering: Mock APIs on 127.0.0.1:9200 triggered via SSRF (deploy, shutdown, key dump endpoints)\n\n###Impact\nAny 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.","published":"2026-07-21T20:34:23.536Z","modified":"2026-08-12T03:51:26.031805549Z","cvss":{"score":6.5,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"},"epss":{"score":0.00209,"percentile":0.11273,"asOf":"2026-08-18"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"flaskbb","fixedVersion":null}],"fix":{"url":"https://github.com/flaskbb/flaskbb/commit/e87e585f54bbe36694e91d52ee9b2d2e65dd4ab5","label":"flaskbb/flaskbb@e87e585"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46556.json"},{"type":"ADVISORY","url":"https://github.com/flaskbb/flaskbb/security/advisories/GHSA-xq32-9g7q-7297"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46556"},{"type":"FIX","url":"https://github.com/flaskbb/flaskbb/commit/e87e585f54bbe36694e91d52ee9b2d2e65dd4ab5"},{"type":"PACKAGE","url":"https://github.com/flaskbb/flaskbb"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:26.031805549Z"}}