Ruby On Rails

Outil

Brakeman

Brakeman est un scanner de vulnรฉrabilitรฉ pour application Ruby On Rails.

Utilisation:

$ brakeman /path/to/rubyapp

ressource: https://github.com/presidentbeef/brakeman

Structure d'un projet RoR

.
โ”œโ”€โ”€ Dockerfile #software version, hardcoded credentials
โ”œโ”€โ”€ Gemfile #software versions
โ”œโ”€โ”€ Gemfile.lock #software versions
โ”œโ”€โ”€ app
โ”‚ย ย  โ”œโ”€โ”€ assets # images, video etc
โ”‚ย ย  โ”œโ”€โ”€ controllers #all application logic located here
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ admin_controller.rb
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ users_controller.rb
โ”‚ย ย  โ”œโ”€โ”€ helpers #helper - method that is (mostly) used to share reusable code
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ admin_helper.rb
โ”‚ย ย  โ”œโ”€โ”€ mailers #allows send emails from your application using mailer classes
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ user_mailer.rb
โ”‚ย ย  โ”œโ”€โ”€ models #Ruby class that is used to represent data 
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ user.rb
โ”‚ย ย  โ””โ”€โ”€ views # HTML templates
โ”‚ย ย      โ”œโ”€โ”€ admin
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ get_all_users.html.erb
โ”œโ”€โ”€ config #app configuration, should be reviewed because developers can disable security features
โ”‚ย ย  โ”œโ”€โ”€ application.rb #application configuration
โ”‚ย ย  โ”œโ”€โ”€ boot.rb
โ”‚ย ย  โ”œโ”€โ”€ database.yml #database config, may contain hard-coded creds
โ”‚ย ย  โ”œโ”€โ”€ environment.rb
โ”‚ย ย  โ”œโ”€โ”€ environments
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ development.rb #application configuration
โ”‚ย ย  โ”œโ”€โ”€ initializers
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ constants.rb #hardcoded credentials
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ filter_parameter_logging.rb #logging
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ html_entities.rb #Enables or disables the escaping of HTML entities in JSON serialization
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ key.rb #hardcoded credentials
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ secret_token.rb #cookie signing
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ session_store.rb #how session store is organized
โ”‚ย ย  โ”œโ”€โ”€ locales
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ en.yml #hardcoded credentials
โ”‚ย ย  โ”œโ”€โ”€ routes.rb #First thing to investigate, application routing
โ”‚ย ย  โ”œโ”€โ”€ secrets.yml #Is credentials/secrets encrypted?
โ”‚ย ย  โ””โ”€โ”€ secrets2.yml #Is credentials/secrets encrypted?
โ”œโ”€โ”€ db
โ”‚ย ย  โ”œโ”€โ”€ schema.rb #database schema
โ”‚ย ย  โ””โ”€โ”€ seeds.rb #database data, may contain hard-coded creds
โ”œโ”€โ”€ lib #extended modules
โ”‚ย ย  โ”œโ”€โ”€ encryption.rb #encryption
โ”œโ”€โ”€ log #log files
โ”œโ”€โ”€ public #static files and compiled assets
โ”‚ย ย  โ”œโ”€โ”€ 404.html
โ”‚ย ย  โ””โ”€โ”€ robots.txt
โ”œโ”€โ”€ script
โ”œโ”€โ”€ spec #for testing purposes
โ””โ”€โ”€ vendor #third-party code

Points d'interet

/config/database.ymlย -ย ย Peut contenir des identifiants de production
/config/initializers/secret_token.rbย -ย Contient les secrets utilisรฉs pour hash les cookies
/db/seeds.rbย -ย Peut contenir des donnรฉes de dรฉpart, y compris l'utilisateur administrateur bootstrap.
/db/development.sqlite3ย -ย ย Peut contenir des donnรฉes sensibles

Routing

Permet de mapper des routes avec ses gestionnaires pour comprendre la structure API de l'application. Le routeur dรฉtermine quel type de contrรดleur et d'action doit rรฉellement exรฉcuter le code. Le routage des applications est dรฉcrit dans le fichier /config/routes.rb.

ressources:

Controllers

Views

Les vues sont stockรฉes dans le chemin de modรจle suivant:

app/views/[controller]/[view_name].html.erb

Une vue est une simple page HTML gรฉrรฉe par le moteur de modรจle ERB, qui affiche les valeurs renvoyรฉes par le contrรดleur.

ressource: https://guides.rubyonrails.org/layouts_and_rendering.html

Models

Un modรจle est une classe Ruby utilisรฉe pour reprรฉsenter des donnรฉes. De plus, les modรจles peuvent interagir avec la base de donnรฉes de l'application via une fonctionnalitรฉ de Rails appelรฉe Active Record.

Mauvaises pratiques

SSL forcรฉ dรฉsactivรฉ

#config/environments/production.rb
config.force_ssl = true

Crypto

Cookies

La bonne pratique est:

Rails.application.config.action_dispatch.signed_cookie_digest = "SHA256"

Env

Les environnements doivent utiliser une clรฉ alรฉatoire prรฉsente dans config/credentials.yml.enc et la clรฉ doit รชtre chiffrรฉe.

Mass assignement

Whitelist_attributes doit รชtre sur false:

config.active_record.whitelist_attributes=false

Tout paramรจtre peut รชtre utilisรฉ lors dโ€™un appel de mass assignment lorsque .permit! est utilisรฉ.

Exemple:

def create
  user = User.new(user_params)
...
...

def user_params
  params.require(:user).permit!
end

Permet ceci,

User.new(
  :email => "email@email.com",
  :admin => "true", # Or la valeur de admin ne devrait pas รชtre modifiable
  :password => "password",
  :first_name => "John",
  :last_name => "Doe"
)

XSS

Si ActiveSupport::escape_html_entities_in_json = false :

  • to_json() = potentielle XSS

RoR รฉchape le code html par dรฉfaut mais certaines mรฉthode dรฉprรฉciรฉes permettent d'outrepasser cette protection:

  • raw

  • html_save

  • content_tag

Exemples

  • html = "<div>#{name}</div>".html_safe

  • content_tag :p, "Hello, #{name}โ€

  • raw @user.name

Contourner le moteur de template:

  • ERB.new("<div>#{@user.name}</div>").result

  • render inline: "<div>#{@user.name}</div>โ€

  • render text: "<div>#{@user.name}</div>โ€

Variables explicitements unescaped:

  • <%= name.html_safe %>

  • <%= content_tag :p, "Hello, #{name}" %>

  • <%= raw @user.name =>

  • <%== @user.name %>

Template placรฉ ร  un endroit dangereux:

  • <div class=<%= classes %></div>

  • <a href="<%= link %>"></a>

  • <%= link_to "Here", @link %>

  • <script>var name = <%= name %>;</script>

OS injection

eval("ruby code here")
system("os command here")
`ls -al /` # (backticks contain os command)
exec("os command here")
spawn("os command here")
open("| os command here")
URI#open from open-uri
Process.exec("os command here")
Process.spawn("os command here")
IO.binread("| os command here")
IO.binwrite("| os command here", "foo")
IO.foreach("| os command here") {}
IO.popen("os command here")
IO.read("| os command here")
IO.readlines("| os command here")
IO.write("| os command here", "foo")
syscall
%x() %x %x{} %x-os-
popen<n>
exec
Open3.popen3()
fork()
PTY.spawn()
constantize

SQLi

La concatรฉnation de l'entrรฉe utilisateur avec le paramรจtre de requรชte SQL peut entraรฎner une injection SQL.

Exemple:

User.where("name = '#{params[:name]}'") #Vulnรฉrable

#Parametrized
User.where(["name = ?", "#{params[:name]}"]) #Pas vulnรฉrable
User.where({ name: params[:name] }) #Pas vulnรฉrable

SSTI

ERB.new("<div>#{@user.name}</div>").result

Insecure deserialization

Vรฉrifier que Marshal.load n'est pas utilisรฉ pour dรฉserialiser des donnรฉes apportรฉes par les utilisateurs.

Derniรจre mise ร  jour

Cet article vous a-t-il รฉtรฉ utile ?