Skip to:
Content

BuddyPress.org

Opened 5 weeks ago

Closed 4 weeks ago

Last modified 4 weeks ago

#9312 closed defect (bug) (fixed)

Avatar AJAX responses use esc_url() instead of esc_url_raw(), breaking JavaScript URL handling

Reported by: garyj's profile GaryJ Owned by: espellcaste's profile espellcaste
Milestone: 14.5.0 Priority: normal
Severity: normal Version:
Component: Media Keywords: has-patch
Cc: emaralive

Description

Several AJAX handlers in bp-core/bp-core-avatars.php use esc_url() to sanitize avatar URLs in JSON responses. This causes issues when JavaScript sets these URLs as image src attributes, because esc_url() converts & to & (HTML entity), which becomes malformed when used in JavaScript.

Steps to Reproduce

  1. Upload a profile avatar with crop parameters
  2. After cropping, inspect the avatar image element before page reload
  3. The src attribute contains & instead of &, making query parameters invalid

Before reload (broken):

src="...jpg?w=450&crop=113px,112px,225px,225px&resize=150,150"

After reload (correct):

src="...jpg?w=450&crop=113px,112px,225px,225px&resize=150,150"

Root Cause

esc_url() is designed for HTML output and converts & to &. When returned in a JSON response and used by JavaScript, the HTML entity is treated as literal characters, breaking the URL.

Affected Code

bp-core/bp-core-avatars.php:

  • Line 921 (bp_avatar_ajax_delete)
  • Line 1421 (bp_avatar_ajax_set - webcam)
  • Line 1485 (bp_avatar_ajax_set - crop)
  • Line 2502 (bp_avatar_ajax_recycle_previous_avatar)

Proposed Fix

Replace esc_url() with esc_url_raw() for all avatar URLs returned in AJAX/JSON responses. esc_url_raw() sanitizes without HTML entity encoding, which is correct for non-HTML contexts.

// Before
'avatar' => esc_url( bp_core_fetch_avatar( ... ) ),

// After
'avatar' => esc_url_raw( bp_core_fetch_avatar( ... ) ),


Environment

Attachments (2)

avatar-upload-broken.png (1.3 MB) - added by GaryJ 5 weeks ago.
Avatar instant preview/reload when querystring is incorrectly encoded - no crop or resizing.
avatar-upload-fixed.png (298.5 KB) - added by GaryJ 5 weeks ago.
Avatar instant preview when querystring is encoded correctly - crop and resize are applied

Download all attachments as: .zip

Change History (11)

#1 @emaralive
5 weeks ago

  • Cc emaralive added

#2 @espellcaste
5 weeks ago

  • Milestone changed from Awaiting Review to Under Consideration

@GaryJ Other than the urls being wrong, is there any UI issue you see?

This change has been in the plugin for while, since https://buddypress.trac.wordpress.org/changeset/12338. So I'm looking for possible related issues this is causing, besides confirming any UI issue you can share.

@GaryJ
5 weeks ago

Avatar instant preview/reload when querystring is incorrectly encoded - no crop or resizing.

@GaryJ
5 weeks ago

Avatar instant preview when querystring is encoded correctly - crop and resize are applied

#3 @GaryJ
5 weeks ago

Yes (screenshots of broken and fixed behaviour attached).

As you can see from the code examples, the AJAX-returned instant preview image is originally 450px wide, with a defined crop size and crop origin, which is then resized to be 150x150 per the default and expected layout. Since the querystring encoding is incorrect, and the querystring is ignored, the image shows up as the full 450x450 width (i.e. uncropped), which means the instant preview breaks the layout.

When the querystring encoding is correct, the fresh upload neatly replaces the existing 150x150px image.

This was experienced on a WordPress VIP site, which supports a system such that images can be manipulated (and cached) on the fly (hence the sizing being in the querystring args), but it would affect other hosts / applications than do something similar.

#4 @espellcaste
5 weeks ago

  • Milestone changed from Under Consideration to 14.5.0

Thanks. I'll do some more tests, but this is good. :)

Last edited 5 weeks ago by espellcaste (previous) (diff)

#5 @espellcaste
5 weeks ago

I do have a buddypress setup on a vip, local, instance but can't replicate it. :/ I'm familiar with VIP Proton CDN. But maybe I'm missing some plugin to hook the CDN locally.

My guess is that there are might be some code hooking into bp_core_fetch_avatar_url and changing the values to use query params instead. And our esc_url escaping is affecting that.

Which would make sense why this has not been an issue until now.

I'll create a patch. The change to esc_url_raw won't create an issue to everyone else.

This ticket was mentioned in PR #427 on buddypress/buddypress by renatonascalves.


4 weeks ago
#6

  • Keywords has-patch added; needs-patch removed

#7 @espellcaste
4 weeks ago

In 14155:

Replace esc_url() with esc_url_raw() for almost all avatar URLs returned in AJAX/JSON responses.

This change addresses an issue where a site modifies the url returned by bp_core_fetch_avatar, and those URLs are returned as image src attributes.

In the process of escaping the url, esc_url converts those attributes becoming malformed. esc_url_raw() sanitizes the url without HTML entity encoding, which is correct for non-HTML contexts.

Since BuddyPress DOES NOT return the image src attributes by default as part of the url, this change should have no impact to regular users. Unless the site is purposefully changing them (the use case here is an image CDN that returns the image [on demand] using the src attributes as image params in the avatar url).

Originally at [12338].

Props GaryJ.

See https://github.com/buddypress/buddypress/pull/427
See #9312 (14.0)

#8 @espellcaste
4 weeks ago

  • Owner set to espellcaste
  • Resolution set to fixed
  • Status changed from new to closed

In 14156:

Replace esc_url() with esc_url_raw() for almost all avatar URLs returned in AJAX/JSON responses.

This change addresses an issue where a site modifies the url returned by bp_core_fetch_avatar, and those URLs are returned as image src attributes.

In the process of escaping the url, esc_url converts those attributes becoming malformed. esc_url_raw() sanitizes the url without HTML entity encoding, which is correct for non-HTML contexts.

Since BuddyPress DOES NOT return the image src attributes by default as part of the url, this change should have no impact to regular users. Unless the site is purposefully changing them (the use case here is an image CDN that returns the image [on demand] using the src attributes as image params in the avatar url).

Originally at [12338].

Props GaryJ.

Closes https://github.com/buddypress/buddypress/pull/427
Fixes #9312 (trunk)

#9 @espellcaste
4 weeks ago

  • Component changed from Core to Media
Note: See TracTickets for help on using tickets.