# 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](https://github.com/presidentbeef/brakeman)

## Structure d'un projet RoR

```bash
.
├── 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

```markdown
/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:

* [https://api.rubyonrails.org/v7.0.3.1/classes/ActionDispatch/Routing/Mapper.html](https://api.rubyonrails.org/v7.0.3.1/classes/ActionDispatch/Routing/Mapper.html)
* [https://guides.rubyonrails.org/routing.html](https://guides.rubyonrails.org/routing.html)

### 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](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é

```ruby
#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:

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

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

Permet ceci,

```ruby
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` :&#x20;

* 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

```markdown
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:

```sql
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.
