CVE-2011-5097: Permissions, Privileges, and Access Controls (CWE-264)
value: chef-server-api/app/controllers/cookbooks.rb in Chef Server in Chef before 0.9.18, and 0.10.x before 0.10.2, does not require administrative privileges for the update and destroy methods, which allows remote authenticated users to (1) upload cookbooks via a knife cookbook upload command or (2) delete cookbooks via a knife cookbook delete command.
CWE description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
Published: 2012-08-08T10:26Z
Repository: https://github.com/opscode/chef
Language: Other
Files changed: chef-server-api/app/controllers/cookbooks.rb, features/api/cookbooks/delete_cookbooks.feature, features/api/cookbooks/upload_cookbooks.feature, features/support/env.rb
Commit date: 2011-06-28 20:13:10 -0700
Commit message: Do not allow non-admins to upload or delete cookbooks.
Diff: diff --git a/chef-server-api/app/controllers/cookbooks.rb b/chef-server-api/app/controllers/cookbooks.rb
index c19f118e..3c41cbfe 100644
--- a/chef-server-api/app/controllers/cookbooks.rb
+++ b/chef-server-api/app/controllers/cookbooks.rb
@@ -28,10 +28,11 @@ class Cookbooks < Application
 
   provides :json
 
   before :authenticate_every
   before :params_helper
+  before :is_admin, :only => [ :update, :destroy ]
 
   attr_accessor :cookbook_name, :cookbook_version
 
   def params_helper
     self.cookbook_name = params[:cookbook_name]
diff --git a/features/api/cookbooks/delete_cookbooks.feature b/features/api/cookbooks/delete_cookbooks.feature
index 1a08a2c0..95154319 100644
--- a/features/api/cookbooks/delete_cookbooks.feature
+++ b/features/api/cookbooks/delete_cookbooks.feature
@@ -50,5 +50,12 @@ Feature: CRUD cookbooks
   Scenario: I should not be able to delete a cookbook that doesn't exist'
     Given I am an administrator
      When I 'DELETE' to the path '/cookbooks/testcookbook_nonexistent/1.2.3'
      Then I should get a '404 "Not Found"' exception
 
+  @delete_cookbook_negative @cookbook_non_admin
+  Scenario: I should not be able to delete cookbook if I am not an admin
+    Given I am an administrator
+     When I fully upload a sandboxed cookbook named 'testcookbook_valid' versioned '0.1.0' with 'testcookbook_valid'
+    Given I am a non-admin
+     When I 'DELETE' to the path '/cookbooks/testcookbook_valid/0.1.0'
+     Then I should get a '403 "Forbidden"' exception
diff --git a/features/api/cookbooks/upload_cookbooks.feature b/features/api/cookbooks/upload_cookbooks.feature
index a8562d1e..4856a945 100644
--- a/features/api/cookbooks/upload_cookbooks.feature
+++ b/features/api/cookbooks/upload_cookbooks.feature
@@ -153,5 +153,24 @@ Feature: CRUD cookbooks
   Scenario: Cannot overwrite a frozen Cookbook Version
     Given I am an administrator
       And I have uploaded a frozen cookbook named 'testcookbook_valid' at version '0.1.0'
      When I upload a cookbook named 'testcookbook_valid' at version '0.1.0'
      Then I should get a '409 "Conflict"' exception
+
+  @create_cookbook_negative @cookbook_non_admin
+  Scenario: Should not be able to create a cookbook if I am not an admin
+    Given I am an administrator
+     When I create a sandbox named 'sandbox1' for cookbook 'testcookbook_valid'
+     Then the inflated responses key 'uri' should match '^http://.+/sandboxes/[^\/]+$'
+     Then I upload a file named 'metadata.json' from cookbook 'testcookbook_valid' to the sandbox
+     Then the response code should be '200'
+     Then I upload a file named 'metadata.rb' from cookbook 'testcookbook_valid' to the sandbox
+     Then the response code should be '200'
+     Then I upload a file named 'attributes/attributes.rb' from cookbook 'testcookbook_valid' to the sandbox
+     Then the response code should be '200'
+     Then I upload a file named 'recipes/default.rb' from cookbook 'testcookbook_valid' to the sandbox
+     Then the response code should be '200'
+     When I commit the sandbox
+     Then I should not get an exception
+    Given I am a non-admin
+     When I create a versioned cookbook named 'testcookbook_valid' versioned '0.1.0' with 'testcookbook_valid'
+     Then I should get a '403 "Forbidden"' exception
diff --git a/features/support/env.rb b/features/support/env.rb
index 8a2dfd1e..4c40efc4 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -133,12 +133,15 @@ def create_databases
   Chef::Certificate.gen_validation_key
   Chef::Certificate.gen_validation_key(Chef::Config[:web_ui_client_name], Chef::Config[:web_ui_key])
   Chef::Environment.create_default_environment
   system("cp #{File.join(Dir.tmpdir, "chef_integration", "validation.pem")} #{Dir.tmpdir}")
   system("cp #{File.join(Dir.tmpdir, "chef_integration", "webui.pem")} #{Dir.tmpdir}")
+  c = Chef::ApiClient.cdb_load(Chef::Config[:web_ui_client_name])
+  c.admin(true)
+  c.cdb_save
 
-  cmd = [KNIFE_CMD, "cookbook", "upload", "-a", "-o", INTEGRATION_COOKBOOKS, "-u", "validator", "-k", File.join(Dir.tmpdir, "validation.pem"), "-c", KNIFE_CONFIG]
+  cmd = [KNIFE_CMD, "cookbook", "upload", "-a", "-o", INTEGRATION_COOKBOOKS, "-u", Chef::Config[:web_ui_client_name], "-k", File.join(Dir.tmpdir, "webui.pem"), "-c", KNIFE_CONFIG]
   Chef::Log.info("Uploading fixture cookbooks with #{cmd.join(' ')}")
   cmd << {:timeout => 120}
   shell_out!(*cmd)
 end
 

Vulnerable code:   cmd = [KNIFE_CMD, "cookbook", "upload", "-a", "-o", INTEGRATION_COOKBOOKS, "-u", "validator", "-k", File.join(Dir.tmpdir, "validation.pem"), "-c", KNIFE_CONFIG]
Fixed code:   before :is_admin, :only => [ :update, :destroy ]
  @delete_cookbook_negative @cookbook_non_admin
  Scenario: I should not be able to delete cookbook if I am not an admin
    Given I am an administrator
     When I fully upload a sandboxed cookbook named 'testcookbook_valid' versioned '0.1.0' with 'testcookbook_valid'
    Given I am a non-admin
     When I 'DELETE' to the path '/cookbooks/testcookbook_valid/0.1.0'
     Then I should get a '403 "Forbidden"' exception

  @create_cookbook_negative @cookbook_non_admin
  Scenario: Should not be able to create a cookbook if I am not an admin
    Given I am an administrator
     When I create a sandbox named 'sandbox1' for cookbook 'testcookbook_valid'
     Then the inflated responses key 'uri' should match '^http://.+/sandboxes/[^\/]+$'
     Then I upload a file named 'metadata.json' from cookbook 'testcookbook_valid' to the sandbox
     Then the response code should be '200'
     Then I upload a file named 'metadata.rb' from cookbook 'testcookbook_valid' to the sandbox
     Then the response code should be '200'
     Then I upload a file named 'attributes/attributes.rb' from cookbook 'testcookbook_valid' to the sandbox
     Then the response code should be '200'
     Then I upload a file named 'recipes/default.rb' from cookbook 'testcookbook_valid' to the sandbox
     Then the response code should be '200'
     When I commit the sandbox
     Then I should not get an exception
    Given I am a non-admin
     When I create a versioned cookbook named 'testcookbook_valid' versioned '0.1.0' with 'testcookbook_valid'
     Then I should get a '403 "Forbidden"' exception
  c = Chef::ApiClient.cdb_load(Chef::Config[:web_ui_client_name])
  c.admin(true)
  c.cdb_save
  cmd = [KNIFE_CMD, "cookbook", "upload", "-a", "-o", INTEGRATION_COOKBOOKS, "-u", Chef::Config[:web_ui_client_name], "-k", File.join(Dir.tmpdir, "webui.pem"), "-c", KNIFE_CONFIG]