{"id":"CVE-2026-46556","aliases":["GHSA-xq32-9g7q-7297","PYSEC-2026-2479"],"title":"FlaskBB: SSRF in get_image_info() via unrestricted avatar URL","summary":"FlaskBB: SSRF in get_image_info() via unrestricted avatar URL","severity":"medium","cvss":6.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","vendor":"flaskbb","product":"flaskbb","ecosystem":"pip","affected":["flaskbb <= 2.2.0"],"published":"2026-05-21","updated":"2026-07-13","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-xq32-9g7q-7297","references":[{"url":"https://github.com/flaskbb/flaskbb/security/advisories/GHSA-xq32-9g7q-7297"},{"url":"https://github.com/flaskbb/flaskbb"}],"tags":["osv","pip"],"ingestedAt":"2026-07-13T18:58:05.277Z","epss":0.00354,"epssPercentile":0.29137,"slug":"CVE-2026-46556","body":"## Overview\n\n###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.\n\n## Affected packages\n\n- `flaskbb <= 2.2.0`\n\n## Remediation\n\nRefer to the advisory for the patched release.","depth":"sunlit","depthScore":36,"depthScoreParts":{"impact":35.8,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}