CVE-2013-5036: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: The Square Squash allows remote attackers to execute arbitrary code via a YAML document in the (1) namespace parameter to the deobfuscation function or (2) sourcemap parameter to the sourcemap function in app/controllers/api/v1_controller.rb.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
Published: 2014-05-27T14:55Z
Repository: https://github.com/SquareSquash/web
Language: Ruby
Files changed: Gemfile.d/development.rb, Gemfile.d/utilities.rb, Gemfile.lock, app/assets/javascripts/application.js, app/controllers/api/v1_controller.rb, app/controllers/bugs_controller.rb, app/controllers/occurrences_controller.rb, app/controllers/sessions_controller.rb, app/models/additions/ldap_authentication.rb, app/models/blame.rb, app/models/bug.rb, app/models/environment.rb, app/models/event.rb, app/models/observers/comment_observer.rb, app/models/occurrence.rb, app/models/slug.rb, app/models/symbolication.rb, app/models/user.rb, config/application.rb, config/environment.rb, config/preinitializers/safe_yaml.rb
Commit date: 2013-06-24 20:05:30 -0700
Commit message: CodeClimate-recommended security fixes

Diff: diff --git a/Gemfile.d/development.rb b/Gemfile.d/development.rb
index e855ac3..4469f9d 100644
--- a/Gemfile.d/development.rb
+++ b/Gemfile.d/development.rb
@@ -1,7 +1,9 @@
 group :development do
   gem 'yard', require: nil
   gem 'redcarpet', require: nil, platform: :mri
+
+  gem 'json-schema', '< 2.0.0' # version 2.0 breaks fdoc
   gem 'fdoc'
 end
 
 gem 'sql_origin', groups: [:development, :test]
diff --git a/Gemfile.d/utilities.rb b/Gemfile.d/utilities.rb
index d2785e0..9a604a1 100644
--- a/Gemfile.d/utilities.rb
+++ b/Gemfile.d/utilities.rb
@@ -1,3 +1,5 @@
 gem 'json'
 gem 'git', github: 'RISCfuture/ruby-git'
 gem 'user-agent'
+
+gem 'safe_yaml'
diff --git a/Gemfile.lock b/Gemfile.lock
index b086b16..a306f77 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -86,19 +86,19 @@ GEM
       json-schema (>= 1.0.1)
       kramdown
       thor
     find_or_create_on_scopes (1.3.0)
       activerecord (>= 3.1)
-    font-awesome-rails (3.1.1.2)
+    font-awesome-rails (3.2.1.1)
       railties (>= 3.2, < 5.0)
-    hike (1.2.2)
+    hike (1.2.3)
     httpi (2.0.2)
       rack
     i18n (0.6.1)
     jdbc-postgres (9.2.1002.1)
     journey (1.0.4)
-    jquery-rails (3.0.0)
+    jquery-rails (3.0.1)
       railties (>= 3.0, < 5.0)
       thor (>= 0.14, < 2.0)
     json (1.8.0)
     json (1.8.0-java)
     json-schema (1.1.1)
@@ -117,11 +117,11 @@ GEM
       activesupport (>= 3.0)
     mail (2.5.4)
       mime-types (~> 1.16)
       treetop (~> 1.4.8)
     mime-types (1.23)
-    multi_json (1.7.5)
+    multi_json (1.7.7)
     pg (0.15.1)
     plist (3.1.0)
     polyglot (0.3.3)
     rack (1.4.5)
     rack-cache (1.2)
@@ -145,11 +145,11 @@ GEM
       activesupport (= 3.2.13)
       rack-ssl (~> 1.3.2)
       rake (>= 0.8.7)
       rdoc (~> 3.4)
       thor (>= 0.14.6, < 2.0)
-    rake (10.0.4)
+    rake (10.1.0)
     rdoc (3.12.2)
       json (~> 1.4)
     redcarpet (2.3.0)
     ref (1.0.5)
     rspec-core (2.13.1)
@@ -161,10 +161,11 @@ GEM
       activesupport (>= 3.0)
       railties (>= 3.0)
       rspec-core (~> 2.13.0)
       rspec-expectations (~> 2.13.0)
       rspec-mocks (~> 2.13.0)
+    safe_yaml (0.9.3)
     sass (3.2.9)
     sass-rails (3.2.6)
       railties (~> 3.2.0)
       sass (>= 3.1.10)
       tilt (~> 1.3)
@@ -196,21 +197,21 @@ GEM
       squash_ruby
     squash_ruby (1.2.0)
       json
     squash_uploader (1.0.1)
       json
-    stringex (2.0.2)
+    stringex (2.0.3)
     therubyracer (0.11.4)
       libv8 (~> 3.11.8.12)
       ref
     therubyrhino (2.0.2)
       therubyrhino_jar (>= 1.7.3)
     therubyrhino_jar (1.7.4)
     thor (0.18.1)
     tilt (1.4.1)
     timeliness (0.3.7)
-    treetop (1.4.12)
+    treetop (1.4.14)
       polyglot
       polyglot (>= 0.3.1)
     tzinfo (0.3.37)
     uglifier (2.1.1)
       execjs (>= 0.3.0)
@@ -244,19 +245,21 @@ DEPENDENCIES
   font-awesome-rails
   git!
   has_metadata_column!
   jquery-rails
   json
+  json-schema (< 2.0.0)
   json_serialize
   kramdown
   less-rails
   libv8 (~> 3.11.8)
   pg
   rack-cors
   rails (>= 3.2.0)
   redcarpet
   rspec-rails
+  safe_yaml
   sass-rails
   slugalicious
   sql_origin
   squash_ios_symbolicator
   squash_java
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 7bf8333..fd14bbc 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -24,11 +24,10 @@
 // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
 // GO AFTER THE REQUIRES BELOW.
 //
 //= require jquery
 //= require jquery_ujs
-//= require jquery-ui
 //
 //= require jquery-cookie
 //= require jquery-leanModal
 //= require jquery-timers
 //
diff --git a/app/controllers/api/v1_controller.rb b/app/controllers/api/v1_controller.rb
index a50f420..bf1e862 100644
--- a/app/controllers/api/v1_controller.rb
+++ b/app/controllers/api/v1_controller.rb
@@ -119,11 +119,11 @@ class Api::V1Controller < ActionController::Base
   # * `POST /api/1.0/deobfuscation`
 
   def deobfuscation
     require_params :api_key, :environment, :build, :namespace
 
-    map = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['namespace'])))
+    map = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['namespace'])), safe: true, deserialize_symbols: false)
     return head(:unprocessable_entity) unless map.kind_of?(Squash::Java::Namespace)
 
     deploy = Project.find_by_api_key!(params['api_key']).
         environments.with_name(params['environment']).first!.
         deploys.find_by_build!(params['build'])
@@ -143,11 +143,11 @@ class Api::V1Controller < ActionController::Base
   # * `POST /api/1.0/sourcemap`
 
   def sourcemap
     require_params :api_key, :environment, :revision, :sourcemap
 
-    sourcemap = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['sourcemap'])))
+    sourcemap = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['sourcemap'])), safe: true, deserialize_symbols: false)
     return head(:unprocessable_entity) unless sourcemap.kind_of?(Squash::Javascript::SourceMap)
 
     Project.find_by_api_key!(params['api_key']).
         environments.with_name(params['environment']).find_or_create!({name: params['environment']}, as: :worker).
         source_maps.create({map: sourcemap, revision: params['revision']}, as: :api)
diff --git a/app/controllers/bugs_controller.rb b/app/controllers/bugs_controller.rb
index ff7c72f..6f6631c 100644
--- a/app/controllers/bugs_controller.rb
+++ b/app/controllers/bugs_controller.rb
@@ -113,11 +113,11 @@ class BugsController < ApplicationController
         query = filter.delete('search')
 
         sort_column, default_dir = SORTS[params[:sort]]
 
         dir = if params[:dir].kind_of?(String) then
-                SORT_DIRECTIONS.include?(params[:dir].upcase) ? params[:dir] : default_dir
+                SORT_DIRECTIONS.include?(params[:dir].upcase) ? params[:dir].upcase : default_dir
               else
                 default_dir
               end
 
         @bugs = @environment.bugs.where(filter).order("#{sort_column} #{dir}, bugs.number #{dir}").limit(PER_PAGE)
diff --git a/app/controllers/occurrences_controller.rb b/app/controllers/occurrences_controller.rb
index e590ee8..6b40f32 100644
--- a/app/controllers/occurrences_controller.rb
+++ b/app/controllers/occurrences_controller.rb
@@ -86,11 +86,11 @@ class OccurrencesController < ApplicationController
 
   def index
     respond_to do |format|
       format.json do
         dir = params[:dir]
-        dir = 'desc' unless SORT_DIRECTIONS.include?(dir.try(:upcase))
+        dir = 'DESC' unless SORT_DIRECTIONS.include?(dir.try(:upcase))
 
         @occurrences = @bug.occurrences.order("occurred_at #{dir}").limit(50)
 
         last = params[:last].present? ? @bug.occurrences.find_by_number(params[:last]) : nil
         @occurrences = @occurrences.where(infinite_scroll_clause('occurred_at', dir, last, 'occurrences.number')) if last
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 1751214..0d3d773 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -14,11 +14,11 @@
 
 # Controller for logging in and logging out of the application. See
 # {AuthenticationHelpers} for more information on how authentication works.
 
 class SessionsController < ApplicationController
-  skip_before_filter :login_required, except: :destroy
+  skip_before_filter :login_required, only: [:new, :create]
   before_filter :must_be_unauthenticated, except: :destroy
 
   respond_to :html
 
   # Displays a page where the user can enter his/her credentials to log in.
diff --git a/app/models/additions/ldap_authentication.rb b/app/models/additions/ldap_authentication.rb
index 5ebdcc4..bd85840 100644
--- a/app/models/additions/ldap_authentication.rb
+++ b/app/models/additions/ldap_authentication.rb
@@ -14,10 +14,15 @@
 
 # Adds LDAP-based authentication to the {User} model. Mixed in if this
 # Squash install is configured to use LDAP-based authentication.
 
 module LdapAuthentication
+  extend ActiveSupport::Concern
+
+  included do
+    attr_accessible :first_name, :last_name, as: :system
+  end
 
   # @return [String] This user's LDAP distinguished name (DN).
 
   def distinguished_name
     "#{Squash::Configuration.authentication.ldap.search_key}=#{username},#{Squash::Configuration.authentication.ldap.tree_base}"
diff --git a/app/models/blame.rb b/app/models/blame.rb
index c3721bd..f5a2f43 100644
--- a/app/models/blame.rb
+++ b/app/models/blame.rb
@@ -28,11 +28,11 @@
 
 class Blame < ActiveRecord::Base
   validates :repository_hash, :revision, :blamed_revision,
             presence: true,
             length:   {is: 40},
-            format:   {with: /[0-9a-f]+/}
+            format:   {with: /\A[0-9a-f]+\z/}
   validates :file,
             presence: true,
             length:   {maximum: 255}
   validates :line,
             presence:     true,
diff --git a/app/models/bug.rb b/app/models/bug.rb
index 0784879..e31ac34 100644
--- a/app/models/bug.rb
+++ b/app/models/bug.rb
@@ -157,16 +157,16 @@ class Bug < ActiveRecord::Base
   validates :line,
             presence:     true,
             numericality: {only_integer: true, greater_than: 0}
   validates :blamed_revision, :resolution_revision,
             length:    {is: 40},
-            format:    {with: /[0-9a-f]+/},
+            format:    {with: /\A[0-9a-f]+\z/},
             allow_nil: true
   validates :revision,
             presence: true,
             length:   {is: 40},
-            format:   {with: /[0-9a-f]+/}
+            format:   {with: /\A[0-9a-f]+\z/}
   #validates :first_occurrence,
   #          presence: true
   #validates :latest_occurrence,
   #          presence: true
   #validates :occurrences_count,
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 9e4b61b..7cfa183 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -64,11 +64,11 @@ class Environment < ActiveRecord::Base
             presence: true
   validates :name,
             presence:   true,
             length:     {maximum: 100},
             uniqueness: {case_sensitive: false, scope: :project_id},
-            format:     {with: /[a-z0-9\-_]+/}
+            format:     {with: /\A[a-z0-9\-_]+\z/}
 
   scope :with_name, ->(name) { where("LOWER(name) = ?", name.downcase) }
 
   # @private
   def to_param() name end
diff --git a/app/models/event.rb b/app/models/event.rb
index bf2f548..685293f 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -42,10 +42,11 @@
 class Event < ActiveRecord::Base
   belongs_to :bug, inverse_of: :events
   belongs_to :user, inverse_of: :events
   has_many :user_events, dependent: :delete_all, inverse_of: :event
 
+  attr_accessible :bug, :user, :kind, :data
   attr_readonly :bug, :user, :kind, :data
 
   include JsonSerialize
   json_serialize data: {}
 
diff --git a/app/models/observers/comment_observer.rb b/app/models/observers/comment_observer.rb
index e263cdd..09fbebe 100644
--- a/app/models/observers/comment_observer.rb
+++ b/app/models/observers/comment_observer.rb
@@ -28,11 +28,16 @@ class CommentObserver < ActiveRecord::Observer
   end
 
   private
 
   def create_event(comment)
-    Event.create! bug_id: comment.bug_id, kind: 'comment', data: {'comment_id' => comment.id}, user_id: comment.user_id
+    Event.create! do |event|
+      event.bug_id  = comment.bug_id
+      event.kind    = 'comment'
+      event.data    = {'comment_id' => comment.id}
+      event.user_id = comment.user_id
+    end
   end
 
   def watch_bug(comment)
     comment.user.watches.where(bug_id: comment.bug_id).find_or_create
   end
diff --git a/app/models/occurrence.rb b/app/models/occurrence.rb
index 048d1cd..cc6ddde 100644
--- a/app/models/occurrence.rb
+++ b/app/models/occurrence.rb
@@ -376,12 +376,10 @@ class Occurrence < ActiveRecord::Base
   belongs_to :bug, inverse_of: :occurrences
   belongs_to :symbolication, primary_key: 'uuid', inverse_of: :occurrences
   belongs_to :redirect_target, class_name: 'Occurrence', foreign_key: 'redirect_target_id', inverse_of: :redirected_occurrence
   has_one :redirected_occurrence, class_name: 'Occurrence', foreign_key: 'redirect_target_id', inverse_of: :redirect_target, dependent: :destroy
 
-  attr_readonly :bug, :revision, :number, :occurred_at
-
   include HasMetadataColumn
   has_metadata_column(
       # Universal
       message:                {presence: true, length: {maximum: 1000}},
       backtraces:             {type: Array, presence: true},
@@ -464,10 +462,13 @@ class Occurrence < ActiveRecord::Base
       window_width:           {type: Integer, allow_nil: true},
       window_height:          {type: Integer, allow_nil: true},
       color_depth:            {type: Integer, allow_nil: true}
   )
 
+  attr_accessible :revision, :occurred_at, :client, :crashed, *metadata_column_fields.keys
+  attr_readonly :bug, :revision, :number, :occurred_at
+
   # Fields that cannot be used by the aggregation view. These are fields with a
   # a continuous range of possible values, or fields with unusual data types.
   NON_AGGREGATING_FIELDS = %w( number message backtraces ivars arguments env_vars
                                user_data parent_exceptions headers params fragment
                                session flash cookies id bug_id metadata lat lon
@@ -480,11 +481,11 @@ class Occurrence < ActiveRecord::Base
   validates :bug,
             presence: true
   validates :revision,
             presence: true,
             length:   {is: 40},
-            format:   {with: /[0-9a-f]+/}
+            format:   {with: /\A[0-9a-f]+\z/}
   #validates :number,
   #          presence:     true,
   #          numericality: {only_integer: true, greater_than: 0},
   #          uniqueness:   {scope: :bug_id}
   validates :occurred_at,
@@ -835,12 +836,13 @@ class Occurrence < ActiveRecord::Base
 
   def recategorize!
     blamer = Blamer.new(self)
     new_bug    = blamer.find_or_create_bug!
     if new_bug.id != bug_id
-      copy            = new_bug.occurrences.build
-      copy.attributes = attributes.except('number', 'id', 'bug_id')
+      copy = new_bug.occurrences.build
+      copy.assign_attributes attributes.except('number', 'id', 'bug_id'),
+                             without_protection: true
       copy.save!
       blamer.reopen_bug_if_necessary! new_bug
       redirect_to! copy
     end
   end
diff --git a/app/models/slug.rb b/app/models/slug.rb
index 9311ea2..90d5273 100644
--- a/app/models/slug.rb
+++ b/app/models/slug.rb
@@ -66,10 +66,12 @@ class Slug < ActiveRecord::Base
   
   after_save :invalidate_cache
   after_destroy :invalidate_cache
   set_nil_if_blank :scope
 
+  attr_accessible :sluggable, :slug, :active, :scope
+
   # Marks a slug as active and deactivates all other slugs assigned to the
   # record.
 
   def activate!
     self.class.transaction do
diff --git a/app/models/symbolication.rb b/app/models/symbolication.rb
index 2ce5b28..deedca3 100644
--- a/app/models/symbolication.rb
+++ b/app/models/symbolication.rb
@@ -61,11 +61,11 @@ class Symbolication < ActiveRecord::Base
   self.primary_key = 'uuid'
 
   validates :uuid,
             presence:   true,
             uniqueness: true,
-            format:     {with: /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i}
+            format:     {with: /\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\z/i}
 
   after_commit(on: :create) do |sym|
     BackgroundRunner.run SymbolicationWorker, sym.id
   end
 
diff --git a/app/models/user.rb b/app/models/user.rb
index 17f3a60..3a57522 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -76,11 +76,11 @@ class User < ActiveRecord::Base
   )
 
   validates :username,
             presence:   true,
             length:     {maximum: 50},
-            format:     {with: /[a-z0-9_\-]+/},
+            format:     {with: /\A[a-z0-9_\-]+\z/},
             uniqueness: true
 
   before_validation(on: :create) { |obj| obj.username = obj.username.downcase if obj.username }
   after_create :create_primary_email
 
diff --git a/config/application.rb b/config/application.rb
index c734685..238f0b7 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -25,10 +25,13 @@ if defined?(Bundler)
   Bundler.require(*Rails.groups(assets: %w(development test)))
   # If you want your assets lazily compiled in production, use this line
   # Bundler.require(:default, :assets, Rails.env)
 end
 
+# Load preinitializers
+Dir.glob(File.expand_path('../preinitializers/**/*.rb', __FILE__)).each { |f| require f }
+
 module Squash
   class Application < Rails::Application
     # Settings in config/environments/* take precedence over those specified here.
     # Application configuration should go into files in config/initializers
     # -- all .rb files in that directory are automatically loaded.
@@ -70,11 +73,11 @@ module Squash
 
     # Enforce whitelist mode for mass assignment.
     # This will create an empty whitelist of attributes available for mass-assignment for all models
     # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
     # parameters by using an attr_accessible or attr_protected declaration.
-    # config.active_record.whitelist_attributes = true
+    config.active_record.whitelist_attributes = true
 
     # Enable the asset pipeline
     config.assets.enabled = true
 
     # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
diff --git a/config/environment.rb b/config/environment.rb
index a5d0ee4..1e283e8 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -10,12 +10,10 @@
 #    distributed under the License is distributed on an "AS IS" BASIS,
 #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 
-Dir.glob(File.expand_path('../preinitializers/**/*.rb', __FILE__)).each { |f| require f }
-
 # Load the rails application
 require File.expand_path('../application', __FILE__)
 
 # Initialize the rails application
 Squash::Application.initialize!
diff --git a/config/preinitializers/safe_yaml.rb b/config/preinitializers/safe_yaml.rb
new file mode 100644
index 0000000..ac72d8d
--- /dev/null
+++ b/config/preinitializers/safe_yaml.rb
@@ -0,0 +1,7 @@
+# Let's make SafeYAML act exactly like YAML by default, to avoid surprising
+# behavior.
+SafeYAML::OPTIONS[:default_mode]        = :unsafe
+SafeYAML::OPTIONS[:deserialize_symbols] = true
+
+# And let's whitelist the things we transmit over YAML
+SafeYAML.whitelist! Squash::Javascript::SourceMap, Squash::Java::Namespace

Vulnerable code:     font-awesome-rails (3.1.1.2)
    hike (1.2.2)
    jquery-rails (3.0.0)
    multi_json (1.7.5)
    rake (10.0.4)
    stringex (2.0.2)
    treetop (1.4.12)
//= require jquery-ui
    map = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['namespace'])))
    sourcemap = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['sourcemap'])))
                SORT_DIRECTIONS.include?(params[:dir].upcase) ? params[:dir] : default_dir
        dir = 'desc' unless SORT_DIRECTIONS.include?(dir.try(:upcase))
  skip_before_filter :login_required, except: :destroy
            format:   {with: /[0-9a-f]+/}
            format:    {with: /[0-9a-f]+/},
            format:   {with: /[0-9a-f]+/}
            format:     {with: /[a-z0-9\-_]+/}
    Event.create! bug_id: comment.bug_id, kind: 'comment', data: {'comment_id' => comment.id}, user_id: comment.user_id
  attr_readonly :bug, :revision, :number, :occurred_at

            format:   {with: /[0-9a-f]+/}
      copy            = new_bug.occurrences.build
      copy.attributes = attributes.except('number', 'id', 'bug_id')
            format:     {with: /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i}
            format:     {with: /[a-z0-9_\-]+/},
    # config.active_record.whitelist_attributes = true
Dir.glob(File.expand_path('../preinitializers/**/*.rb', __FILE__)).each { |f| require f }

Fixed code: 
  gem 'json-schema', '< 2.0.0' # version 2.0 breaks fdoc

gem 'safe_yaml'
    font-awesome-rails (3.2.1.1)
    hike (1.2.3)
    jquery-rails (3.0.1)
    multi_json (1.7.7)
    rake (10.1.0)
    safe_yaml (0.9.3)
    stringex (2.0.3)
    treetop (1.4.14)
  json-schema (< 2.0.0)
  safe_yaml
    map = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['namespace'])), safe: true, deserialize_symbols: false)
    sourcemap = YAML.load(Zlib::Inflate.inflate(Base64.decode64(params['sourcemap'])), safe: true, deserialize_symbols: false)
                SORT_DIRECTIONS.include?(params[:dir].upcase) ? params[:dir].upcase : default_dir
        dir = 'DESC' unless SORT_DIRECTIONS.include?(dir.try(:upcase))
  skip_before_filter :login_required, only: [:new, :create]
  extend ActiveSupport::Concern

  included do
    attr_accessible :first_name, :last_name, as: :system
  end
            format:   {with: /\A[0-9a-f]+\z/}
            format:    {with: /\A[0-9a-f]+\z/},
            format:   {with: /\A[0-9a-f]+\z/}
            format:     {with: /\A[a-z0-9\-_]+\z/}
  attr_accessible :bug, :user, :kind, :data
    Event.create! do |event|
      event.bug_id  = comment.bug_id
      event.kind    = 'comment'
      event.data    = {'comment_id' => comment.id}
      event.user_id = comment.user_id
    end
  attr_accessible :revision, :occurred_at, :client, :crashed, *metadata_column_fields.keys
  attr_readonly :bug, :revision, :number, :occurred_at

            format:   {with: /\A[0-9a-f]+\z/}
      copy = new_bug.occurrences.build
      copy.assign_attributes attributes.except('number', 'id', 'bug_id'),
                             without_protection: true
  attr_accessible :sluggable, :slug, :active, :scope

            format:     {with: /\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\z/i}
            format:     {with: /\A[a-z0-9_\-]+\z/},
# Load preinitializers
Dir.glob(File.expand_path('../preinitializers/**/*.rb', __FILE__)).each { |f| require f }

    config.active_record.whitelist_attributes = true
# Let's make SafeYAML act exactly like YAML by default, to avoid surprising
# behavior.
SafeYAML::OPTIONS[:default_mode]        = :unsafe
SafeYAML::OPTIONS[:deserialize_symbols] = true

# And let's whitelist the things we transmit over YAML
SafeYAML.whitelist! Squash::Javascript::SourceMap, Squash::Java::Namespace