Emoji Picker is not not using CDN URLs for custom emojis

AI-generated summary

The issue concerns the Emoji Picker not using CDN URLs for custom emojis, unlike admin emoji paths which are properly converted. lava identifies that standard emoji paths in the emojis_controller.rb lack CDN conversion, while admin paths use EmojiSerializer for this purpose. lava confirms that custom emojis in the post composer display S3 URLs directly instead of CDN URLs, as seen in the rendered output. sam notes the issue is specific to the emoji picker and not the UI, which already uses CDN URLs. j.jaffeux addresses the problem with a PR to enable CDN usage, but lava raises concerns about backend security, as the emojis.json endpoint exposes raw S3 URLs, which could lead to abuse and excessive billing. lava suggests returning CDN URLs directly, similar to non-custom emojis. j.jaffeux acknowledges the concern and plans to address it later. sam closes the issue, noting the risk is low due to the public and small nature of the assets, and suggests opening a new feature request for further improvements.

Description

Standard emoji paths aren’t converted to CDN URLs, while admin emoji paths are properly converted.

Evidence

Standard controller (no CDN conversion):

Admin controller (correct conversion using EmojiSerializer):

Standard emoji paths should be converted to CDN URLs like admin emoji paths.

3 Likes

Do you see these URLs being used somewhere in the UI? I suspect they are being converted to CDN URLs in the JS app before being displayed.

1 Like

I checked and can confirm the emojis use S3 URLs directly (starting with //) in the rendered output, not CDN URLs.

Which page do you see this on?

You can see this on the post composer page when using the emoji picker. When custom emojis are loaded, they use S3 endpoints directly, like:

https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/meta/original/3X/1/d/1de8f76096f76cf393640bdcff387ec9ae33dd3e.gif

This shows the paths aren’t being converted to CDN URLs as expected.


Testing custom emoji :awthanks:

:up_arrow: this is being shipped from the S3 CDN… We have an issue with the picker itself @j.jaffeux

Is not using the S3 CDN from custom emojis

This UI is using the S3 CDN

So this is very specific to the emoji picker, improving title here.

2 Likes

Thanks that should fix it:

https://github.com/discourse/discourse/pull/32494

4 Likes

Thank you for your PR that enables CDN usage for custom emojis.

While your frontend fix correctly requests emoji CDN addresses, I’m concerned about backend security.
The https://meta.discourse.org/emojis.json endpoint still exposes S3 source URLs like //cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/meta/original/3X/6/1/61e481320406f0f82ed780db3f04056128191613.png, which could potentially lead to malicious abuse and excessive S3 billing.

For better security, I suggest returning CDN addresses directly, similar to how non-custom emojis are handled.

Here’s my attempt at fixing the code:

class EmojisController < ApplicationController
  def index
    emojis = Emoji.allowed.group_by(&:group)
    
    emojis.each do |_, emoji_list|
      emoji_list.each do |emoji|
        emoji.url = Discourse.store.cdn_url(emoji.url) if emoji.url.present?
      end
    end
    
    render json: MultiJson.dump(emojis)
  end
  def search_aliases
    render json: MultiJson.dump(Emoji.search_aliases)
  end
end

Yes I know we do it directly for non custom emoji in emoji.rb which I would prefer than the controller. I want to ensure this is not toing to cause issues though, so I made the simplest fix for now, but will dig this in the future.

2 Likes

Closing cause the original issue is fixed, feel free to open another feature request for the followup.

These assets are tiny and generally public, risk feels low.

2 Likes