DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Rake Task To Check Mass Assignment Protection Status And Output Possible Unsafe Method

12.11.2008
| 4108 views |
  • submit to reddit
        // description of your code here
Rake task to check mass assignment protection status and output possible unsafe method.
Create a rake file under lib/tasks and run rake security:model_protection

sample output 

==Business | attr_accessible==============================
ALLOWED: group_membership_ids=
==Coupon==================================================
POSSIBLE UNSAFE: redeemed_coupon_ids=
POSSIBLE UNSAFE: billing_group_id=
POSSIBLE UNSAFE: person_ids=
==Entry===================================================
==Group | attr_protected==================================
NOT INCLUDED: survey_ids=
NOT INCLUDED: membership_ids=
NOT INCLUDED: business_ids=
NOT INCLUDED: person_ids=
 
$terminal = %x(echo $TERM).strip!
$unsafe_methods_pattern = /(_id=|_ids=|_type=|admin=)$/

def puts_in_color(text, options = {})
  if $terminal == 'xterm-color'
    case options[:color]
    when :red
      puts "\033[31m#{text}\033[0m"
    when :green
      puts "\033[32m#{text}\033[0m"
    else
      puts text
    end
  else
    puts text
  end
end

def green(text)
  puts_in_color text, :color => :green
end

def red(text)
  puts_in_color text, :color => :red
end

namespace :security do
  
  desc "Check mass-assignment protection status for all models"
  task :model_protection => :environment do

    models = Dir[RAILS_ROOT + "/app/models/**/*.rb"].map { |model| File.basename(model, '.rb') }.compact.map { |model| model.camelize.constantize rescue nil }.compact
    
    models.each do |model|
      black_list = model.read_inheritable_attribute("attr_protected")
      white_list = model.read_inheritable_attribute("attr_accessible")
      
      output = if black_list
        "#{model} | attr_protected" 
      elsif white_list
        "#{model} | attr_accessible" 
      else
        model
      end
      
      puts "==#{output}".ljust(58, '=')
      
      begin 
        unsafe_methods = model.new.public_methods.select { |method| method =~ $unsafe_methods_pattern } 
      
        if unsafe_methods.any?
          unsafe_methods.each do |method|
            if black_list 
              unless black_list.include?(method.chop)
                red "NOT INCLUDED: #{method}"
              end
            elsif white_list
              if white_list.include?(method.chop)
                green "ALLOWED: #{method}"
              end
            else
              red "POSSIBLE UNSAFE: #{method}"
            end
          end
        end
      rescue
        red "FAILED TO INITIALIZE"
      end
    end
  end
  
end