Uploaded .js file for theme causes a rejection?

I have images, javascript, and css files uploaded to my theme. Without any reason, my theme’s dropdown stopped working because of an issue with my .js file. When I go to the direct uploaded link for my .js file, I get " The change you wanted was rejected. Maybe you tried to change something you didn’t have access to.". When I reupload my .js file I continue getting the error, but uploading other file formats works fine. Any Ideas? Thanks!

https://forum.milehighhub.com/uploads/default/original/1X/076f01c86dcb73d6a5ad2ca60bcaef8f1ac71512.js

1 Like

Do you have js in your theme authorized extensions site setting?

7 Likes

Yup, it is there. I never touched any settings prior to it causing the rejection either.

1 Like

It looks like the setting has been changed. It should contain js (not .js). The easiest solution is to click the “reset” button.

6 Likes

Yeah I added that “.js” after the rejection started because I was out of ideas. I went ahead and clicked reset anyways and added in “js”, but the rejection is still happening.

2 Likes

I just noticed this same problem while I was looking at a seasonal theme I made last year and wondered why it wasn’t working properly.

Going old school and making a post in Staff and uploading the .js there also didn’t work (after adding the extension to staff authorized extensions of course).

Spent some more time on this tonight.

In the Discourse error log this is generated when you GET the .js:

Security warning: an embedded tag on another site requested protected JavaScript. If you know what you’re doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.

ActionController::InvalidCrossOriginRequest (Security warning: an embedded tag on another site requested protected JavaScript. If you know what you’re doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/request_forgery_protection.rb:268:in `verify_same_origin_request’

Which is identical to this fixed bug from 2017:

I don’t have any discourse dev setup right now, but I did take a pcap from inside my testing container.
capture-10-6-2019.zip (1.9 KB)

My users have now taken notice that something is broken, so naturally I spent my Saturday night on this.

This problem started at commit 32b8a2ccffd50d78b8f7be6f0b524506cd2dbd7e.

Since this includes a Rails 6 upgrade, which is where this forgery protection comes from, I assume something has changed in Rails 6, but I couldn’t figure out what that specifically relates to this issue.

This doesn’t seem to be immediately related to the prior bug, as content disposition and content type are being set.

This problem only occurs if public_file_server.enabled/serve_static_assets is set to false (default in production). If set to true (default in development), the UploadsController is bypassed and the js is served normally.

Adding protect_from_forgery except: :show to the UploadsController class fixes the issue, as the forgery protection is bypassed for the show action in the uploads controller.

Adding location ~* (uploads)/.*\.(js)$ { } into the nginx config also fixes the issue.

2 Likes

@kris.kotlarek can you review this and see if you can repro on local / fix it?

3 Likes

Hey Jonathan,

Thank you for your investigation, it was very helpful. Based on your suggestions, I made a fix which was merged into master - FIX: Allow themes to upload and serve js files by lis2 · Pull Request #8188 · discourse/discourse · GitHub

4 Likes

Much obliged Kris, I’m glad I could be of assistance. Also pleased to know the answer to the mystery of why it failed. Annoyingly I had looked at that Rails’ request_forgery_protection.rb myself during my debug session, but didn’t clue in/forgot to diff against the prior version.
Thanks again for your hard work!

3 Likes