CVE-2022-36068 (published 2022-09-29T20:15Z)

Discourse is an open source discussion platform. In versions prior to 2.8.9 on the `stable` branch and prior to 2.9.0.beta10 on the `beta` and `tests-passed` branches, a moderator can create new and edit existing themes by using the API when they should not be able to do so. The problem is patched in version 2.8.9 on the `stable` branch and version 2.9.0.beta10 on the `beta` and `tests-passed` branches. There are no known workarounds.

CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/discourse/discourse
commit_details: repo_url: https://github.com/discourse/discourse
author: Jarek Radosz
author_date: 2022-09-29 20:00:20+02:00
msg: SECURITY: moderator shouldn't be able to import a theme via API (#18418)

* SECURITY: moderator shouldn't be able to import a theme via API.
* DEV: apply `AdminConstraint` for all the "themes" routes.

Co-authored-by: Vinoth Kannan <svkn.87@gmail.com>
repository: repo_url: https://github.com/discourse/discourse
repo_name: discourse/discourse
description: A platform for community discussion. Free, open, simple.
repo_language: Ruby
owner: discourse
file_changes: filename: themes_controller.rb
change_type: ModificationType.MODIFY
diff: @@ -5,6 +5,7 @@ require 'base64'
 class Admin::ThemesController < Admin::AdminController
 
   skip_before_action :check_xhr, only: [:show, :preview, :export]
+  before_action :ensure_admin
 
   def preview
     theme = Theme.find_by(id: params[:id])

programming_language: Ruby
filename: routes.rb
change_type: ModificationType.MODIFY
diff: @@ -206,13 +206,17 @@ Discourse::Application.routes.draw do
       get "customize/embedding" => "embedding#show", constraints: AdminConstraint.new
       put "customize/embedding" => "embedding#update", constraints: AdminConstraint.new
 
-      resources :themes, constraints: AdminConstraint.new
-
-      post "themes/import" => "themes#import"
-      post "themes/upload_asset" => "themes#upload_asset"
-      post "themes/generate_key_pair" => "themes#generate_key_pair"
-      get "themes/:id/preview" => "themes#preview"
-      put "themes/:id/setting" => "themes#update_single_setting"
+      resources :themes, constraints: AdminConstraint.new do
+        member do
+          get "preview" => "themes#preview"
+          put "setting" => "themes#update_single_setting"
+        end
+        collection do
+          post "import" => "themes#import"
+          post "upload_asset" => "themes#upload_asset"
+          post "generate_key_pair" => "themes#generate_key_pair"
+        end
+      end
 
       scope "/customize", constraints: AdminConstraint.new do
         resources :user_fields, constraints: AdminConstraint.new

programming_language: Ruby
filename: themes_controller_spec.rb
change_type: ModificationType.MODIFY
diff: @@ -160,6 +160,13 @@ RSpec.describe Admin::ThemesController do
       expect(response.status).to eq(201)
     end
 
+    it 'should not be able to import a theme by moderator' do
+      sign_in(Fabricate(:moderator))
+
+      post "/admin/themes/import.json", params: { theme: theme_json_file }
+      expect(response.status).to eq(404)
+    end
+
     it 'imports a theme' do
       post "/admin/themes/import.json", params: { theme: theme_json_file }
       expect(response.status).to eq(201)

programming_language: Ruby