Skip to content

fix(security): resolve profile update validation bypass and SSRF#507

Open
prince-shakyaa wants to merge 1 commit into
GenAI-Security-Project:mainfrom
prince-shakyaa:fix/profile-avatar-ssrf
Open

fix(security): resolve profile update validation bypass and SSRF#507
prince-shakyaa wants to merge 1 commit into
GenAI-Security-Project:mainfrom
prince-shakyaa:fix/profile-avatar-ssrf

Conversation

@prince-shakyaa
Copy link
Copy Markdown

@prince-shakyaa prince-shakyaa commented May 19, 2026

fix(security): resolve profile update validation bypass and SSRF via insecure avatar URLs

Description

Fixes #506
This Pull Request resolves a high-severity security vulnerability in the user profile and sharing module.

The Problem

Previously, the ProfileUpdateRequest allowed updating fields optionally. The route only validated that the avatar_url started with https:// if avatar_type was explicitly set to "url" in the current request payload:

if request.avatar_type == "url" and request.avatar_url:
    ...

If a user's profile already had avatar_type = "url" in the database, they could bypass this security check by sending a PUT request containing only avatar_url (omitting avatar_type entirely). The backend successfully saved the insecure URL (e.g. http://127.0.0.1:8500/ or http://169.254.169.254/).

When generating the profile sharing card (/share/profile/{username}/card.png), the backend issued an asynchronous httpx.get request directly to this user-supplied insecure URL to fetch and base64-encode the image. This resulted in a Server-Side Request Forgery (SSRF) vulnerability, enabling attackers to scan local ports, query intranet systems, or access cloud metadata services.

The Fix

This PR updates the validation check in profile.py to validate the avatar_url based on the effective (resolved) avatar type (taking the incoming request's type, or falling back to the existing profile's saved type in the database if omitted).


Key Changes

  • Modified: finbot/apps/ctf/routes/profile.py
    • Updated update_profile route validation to compute the effective_avatar_type and effective_avatar_url before validating the schema.
    • Enforced that if the effective avatar type is "url", the effective avatar URL must use the https:// protocol.

Verification & Testing

Manual Verification

  1. Created a user profile and set the avatar type to url with a valid secure URL:
    {
      "avatar_type": "url",
      "avatar_url": "https://secure-avatar.com/image.png"
    }
  2. Attempted to update only the avatar_url to an insecure address (http://127.0.0.1:8000 or http://169.254.169.254) while omitting the avatar_type field:
    {
      "avatar_url": "http://127.0.0.1:8000"
    }
  3. Verified that the server successfully blocks the request with a 400 Bad Request ("Avatar URL must use HTTPS"), closing the validation bypass.

@prince-shakyaa prince-shakyaa force-pushed the fix/profile-avatar-ssrf branch from 17c86b3 to 40740ff Compare May 19, 2026 19:47
@prince-shakyaa
Copy link
Copy Markdown
Author

Hi @saikishu @e2hln ,
Fixed a validation bypass in profile.py where omitting avatar_type in a profile update request skipped the HTTPS check on avatar_url, allowing insecure HTTP URLs to be saved and triggering blind SSRF via the profile share card endpoint. The fix resolves this by checking the effective avatar type from both the request and the existing database profile before validating the URL. Added 4 unit tests covering the bypass and edge cases.
Thank You.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] HTTPS Validation Bypass in User Profile Updates Leads to SSRF via Insecure Avatar URLs

1 participant