Security Concerns
Fairnopoly runs automated and manual security audits. When we learn lessons or notice issues that can be generalized we will document them here.
As far as security goes, it is always better to whitelist than to blacklist. Every controller action now has a before_filter :authenticate_user!
by default. For public actions that can be skipped with skip_before_filter :authenticate_user!, only: [ :{action1}, :{action2}, {...} ]
We use pundit for authorization. We configured that every action has to have a pundit verification. Exceptions can be added to ApplicationController#pundit_unverified_modules
or ApplicationController#pundit_unverified_classes
Manually comparing IDs in views to see if an element should be rendered is not only bad style but also holds the risk of being inconsistent. Please only check authorization in views based on the following list of methods. If you add a helper method, please also add it to this list.
user.is? current_user
article.owned_by? current_user
policy(resource).{action}?
To disable going back to a page that show sensitive user data after that user has logged out, we blacklist a few pages to prevent browser caching. This is done in a before filter: before_filter :dont_cache, only: [ :{action}, {...} ]
. This before_filter is defined in the ApplicationController.
We use arcane with refineries as addon for strong_parameters which is default in rails 4.
For form data sanitization we use an parser based on Nokogiri. We also wrote our own mini-DSL module to handle sanitization. This Sanitization module lives in lib/autoload
and provides an auto_sanitize
method. When it is defined in a model, it will automatically add a before_validation callback for that field. By default it does a paranoid sanitization, but with method: 'tiny_mce'
it will leave certain HTML tags allowed by TinyMCE.
Example:
class User < ActiveRecord::Base
auto_sanitize :nickname, :forename, :surname, :street, :city
auto_sanitize :about_me, :terms, :cancellation, :about, method: 'tiny_mce'
end
BEWARE where you use String.html_safe
in views. We had a case where output that just concatenated some L10n strings was marked html_safe, but these L10ns took names of other database fields. Through a mixture of missing sanitization and insecure use of html_safe that created an XSS vulnerability.