impress/app/controllers/swf_assets_controller.rb
Emi Matchu 5b2062754d swf_assets/show action to embed a canvas movie in a sandboxed iframe
Not using this on the item page preview yet, but we will!

I like this approach over e.g. a web component specifically for the
sandboxing: while I don't exactly *distrust* JS that we're loading from
Neopets.com, I don't like the idea of *any* part of the site that
executes arbitrary JS unsafely at runtime, even if we theoretically
trust where it theoretically came from. I don't want any failure
upstream to have effects on us!

I copied basically all of the JS from a related project
`impress-media-server` that I had spun up at one point, to investigate
similar embed techniques. Easy peasy drop-in-squeezy!
2024-07-03 19:50:41 -07:00

44 lines
1.1 KiB
Ruby

class SwfAssetsController < ApplicationController
# We're very careful with what content is allowed to load. This is because
# asset movies run arbitrary JS, and, while we generally trust content from
# Neopets.com, let's not be *allowing* movie JS to do whatever it wants! This
# is a good default security stance, even if we don't foresee an attack.
content_security_policy do |policy|
policy.sandbox "allow-scripts"
policy.default_src "none"
policy.img_src -> {
src_list(
helpers.image_url("favicon.png"),
@swf_asset.image_url,
*@swf_asset.canvas_movie_sprite_urls,
)
}
policy.script_src_elem -> {
src_list(
helpers.javascript_url("lib/easeljs.min"),
helpers.javascript_url("lib/tweenjs.min"),
helpers.javascript_url("swf_assets/show"),
@swf_asset.canvas_movie_library_url,
)
}
policy.style_src_elem -> {
src_list(
helpers.stylesheet_url("swf_assets/show"),
)
}
end
def show
@swf_asset = SwfAsset.find params[:id]
render layout: nil
end
private
def src_list(*urls)
urls.filter(&:present?).map { |url| url.sub(/\?.*\z/, "") }.join(" ")
end
end