# Sécurité des applications Web
## William Petit - S.C.O.P. Cadoles
---
## La fondation OWASP
> Open Web Application Security Project
- Fondé en 2001
- Organisation internationale à but non lucratif
---
## Quelques projets en particulier
- [OWASP Top Ten](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project) - Top 10 des failles impactant les applications Web
- [OWASP Code Review Guide](https://www.owasp.org/index.php/Category:OWASP_Code_Review_Project) - Guide de la revue de code appliquée à la sécurité
- [OWASP ASVS](https://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project) - Standard des vérifications de sécurité des applications Web
- [OWASP Webgoat](https://www.owasp.org/index.php/Category:OWASP_WebGoat_Project) - Application(s) volontairement faillible(s) illustrant les principales failles de sécurité actuelles.
---
## Les principales failles
---
## Epicfaild
https://forge.cadoles.com/wpetit/epicfaild
### Lancer avec Docker
```
docker run -it --rm -p 8888:8080 bornholm/epicfaild
# Puis ouvrir l'URL http://localhost:8888/
# dans votre navigateur
```
---
## OWASP WebGoat
https://github.com/WebGoat/WebGoat
### Lancer avec Docker
```
docker run -p 8080:8080 -it --rm webgoat/webgoat-8.0 /home/webgoat/start.sh
# Puis ouvrir l'URL http://localhost:8080/WebGoat/
# dans votre navigateur
```
---
## Injections SQL (SQLI)
### Pratique
> Epicfaild: Gate 3 et 4
> WebGoat: Injection Flaws (- XEE)
---
## Risques
- Vol de données
- Altération de données
- Prise de contrôle du serveur
---
## Mitigation
- Exécuter le moteur de base de données avec un utilisateur dédié.
- Valider TOUTES les entrées utilisateur.
- Utiliser des requêtes préparées.
- Installer un NIDS au niveau du serveur HTTP
---
## Contournement de la session
### Pratique
> Epicfaild: Gate 3
> WebGoat: Authentication Bypass
---
## Risques
- Vol de session
- Vol de données
- Prise de contrôle de l'application
---
## Mitigation
- Valider TOUTES les entrées utilisateurs
- Journaliser les origines des connexions
---
## Cross Site Scripting (XSS)
### Pratique
> Epicfaild: Gate 1
> WebGoat: Cross Site Scripting
---
## Risques
- Vol de sessions
- Hameçonnage
---
## Mitigation
- Valider TOUTES les entrées utilisateurs
- Assainir les données avant de faire leur rendu
---
## Mauvais contrôle des accès
### Pratique
> WebGoat: Access Control Flaws
---
## Risques
- Accès non autorisés à des fonctionnalités critiques
- Vol de données
- Prise de contrôle de l'application
---
## Mitigation
- Journaliser tous les accès à des ressources critiques (qui, quoi, quand, quel contexte ?)
- Utiliser une double authentification pour l'accès aux ressources critiques
> **Attention** L'obfuscation des accès n'est pas une méthode de sécurisation des points d'entrée.
---
## Fuite d'informations sensibles
### Pratique
```
Epicfaild: Gate 4/5
WebGoat: Insecure communication, Client Side/Client side filtering
```
---
## Risques
- Vol de données
---
## Mitigation
- Ne retourner à l'utilisateur que les données dont il a besoin (approche "frugale").
- Limiter la zone d'action de l'utilisateur à ses seuls besoins.
---
## Cross Site Request Forgery (CSRF)
### Pratique
> WebGoat: Request Forgeries
---
## Risques
- Hameçonnage
- Vol de session
- Vol d'identité
---
## Mitigation
- Utilisation de `nonce` (aussi appelé CSRF Token)
- Utilisation de requêtes `POST|PUT|DELETE` pour toutes les actions autres que la "consultation"
- S'assurer que les mécanismes de type "HTTP Method Override" ne sont pas activés en production ([Exemple pour Symfony3](http://symfony.com/doc/2.6/cookbook/routing/method_parameters.html#faking-the-method-with-method))
---
## Mauvaise politique de maintenance
### Pratique
> WebGoat: Vulnerable components
---
## Risques
Les risques dépendent du composant faillible...
---
## Mitigation
- Activer les mécanismes de mise à jour automatique
- Vérifier les mises à jour des librairies de manière automatisée.
- Suivre la publication des [CVE](https://cve.mitre.org/)/[NVD](https://nvd.nist.gov/)
---
## Métrologie applicative appliquée à la sécurité
### Méthodologie générale
### Modélisation de menace
### Identification des flux de données
### Les facteurs d'une bonne métrique
### Exemple d'outil: Prometheus
---
## Méthodologie générale
1. Définir le modèle de menace
2. Identifier et isoler les scénarios d'attaque pour les différentes menaces
3. Trouver les indicateurs "clés" pour ces scénarios i.e. identifier les métriques pertinentes pour la détection des comportements suspects
4. Mettre en place les sondes pour les métriques
5. Définir les seuils d'alerte et les réponses à apporter
---
## La modélisation de menace
- Identification des **dépendances externes**.
Exemple: _serveur GNU/Linux, base de données_
- Identification des **points d'entrées**
Exemple: _formulaire de contact, port de la base de données_
- Identification des **assets**
Exemple: _Comptes utilisateurs de l'application, données personnelles, droits d'accès_
- Identification des **niveaux de confiance**
Exemple: _Utilisateur anonyme, administrateur_
---
### Identification des flux de données
![center](./img/Data_flow2.jpg?)
---
## Les facteurs d'une bonne métrique
- **Concision** _Le domaine de mesure est il correctement défini ? La métrique n'essaye t-elle pas de mesurer trop de choses ?_
- **Fidélité** _La mesure est elle reproductible ? Mesure t-elle toujours la même chose ?_
- **Intégrité** _Le processus de mesure est il vulnérable à la falsification ?_
- **Utilité** _La métrique apporte elle une information utile au processus décisionnel ?_
---
## Exemple d'outil: Prometheus
### Téléchargement
https://prometheus.io/download/#prometheus
---
## Configuration générale
---
## Instrumentation de l'application
### Modèle de données
### Les différents types de métriques
### Les requêtes
---
## Modèle de données
Prometheus stocke des échantillons (mesures) sous la forme de **séries temporelles**. Il créait une nouvelle série pour chaque association **(nom_métrique, label1=value, label2=value, ...)**.
Chaque couple **(label, valeur)** est appelée **dimension** de la métrique.
**Représentation**
```
http_total_requests{ method="POST", path="/test" }
| name | labels |
```
---
## Les différents types de métriques
---
## Compteur (1)
Un compteur est une métrique dont la valeur ne peut faire qu'augmenter au cours du temps.
> **Exemple** Nombre total de connexions d'un compte sur un site
---
## Jauge
Une jauge est une métrique dont la valeur peut augmenter ou diminuer au cours du temps.
![center 50%](../img/jauge.jpg)
> **Exemple** La température d'une pièce
---
## Histogramme (1)
Un histogramme est une métrique répartissant les données dans des "seaux" (ou "buckets" en anglais) configurables et comptant le nombre total et par "paquet" d'échantillons ainsi que leur somme.
![center 70%](../img/histogram.png)
> **Exemple** Le temps de réponse des requêtes HTTP
---
## Histogramme (2)
### Scénario d'exemple
Soit la métrique `http_request_duration_seconds` un histogramme avec les "buckets" suivants: 0.5, 1, 2, 3, 5.
3 requêtes sont effectuées sur l'application avec des temps de 1s, 2s et 3s respectivements.
On aura sur `/metrics`:
```
http_request_duration_seconds_bucket{le="0.5"} 0
http_request_duration_seconds_bucket{le="1"} 1
http_request_duration_seconds_bucket{le="2"} 2
http_request_duration_seconds_bucket{le="3"} 3
http_request_duration_seconds_bucket{le="5"} 3
http_request_duration_seconds_bucket{le="+Inf"} 3
http_request_duration_seconds_sum 6
http_request_duration_seconds_count 3
```
---
## Les requêtes
---
## Types de données
- `scalar` _Un nombre à virgule flottante_
Exemple: `5.1`
- `instant vector` _Un ensemble de séries temporelles contenant un seul échantillon pour chaque série temporelle, toutes partageant le même horodatage._
Exemple: `http_request_duration_seconds`
- `range vector` _Un ensemble de séries temporelles contenant une gamme de points de données au fil du temps pour chaque série temporelle._
Exemple: `http_request_duration_seconds[5m]`
- `string` _Une chaine de caratères._
Exemple: `"hello world"`
---
## Les opérateurs
### Opérateurs arithmétiques
`+`, `-`, `*`, `/`, `%` (modulo), `^` (puissance)
### Opérateurs de comparaison
`==`, `!=`, `>`, `>=`, `<`, `<=`
### Opérateurs d'aggrégation
`sum`, `min`, `max`, `avg`, `stddev`, `stdvar`, `count`, `count_values`, `bottomk`, `topk`, `quantile`
### Opérateurs logiques
`and`, `or`, `unless`
_[Voir la documentation du projet](https://prometheus.io/docs/prometheus/latest/querying/operators/)_
---
## Fonctions
### Quelques exemples
- `rate(range vector)` Retourne la fréquence moyenne d'augmentation par seconde de la série temporelle dans l'espace de temps donné. À utiliser uniquement avec les compteurs.
- `time()` Retourne le nombre de secondes depuis l'Epoch Unix.
- `increase(range vector)` Retourne l'augmentation de la série temporelle dans l'interval de temps donné. À utiliser uniquement avec les compteurs.
Et aussi [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile), [predict_linear()](https://prometheus.io/docs/prometheus/latest/querying/functions/#predict_linear()),...
_[Voir la documentation du projet](https://prometheus.io/docs/prometheus/latest/querying/functions/)_
---
## Configuration de l'`alertmanager`
### Téléchargement
https://prometheus.io/download/#alertmanager
---
## Écriture de règles d'alertes
---
## Exercice: métrologie orientée sécurité d'une application Symfony3
1. Créer une nouvelle application Symfony3 et configure une authentification de type "Basic Auth" sur une route.
2. Implémenter une `Listener` pour l'évènement `security.authentication.failure` ([voir ce tutoriel](https://www.brainvire.com/create-authentication-listener-symfony2/))
3. Installer et configurer le bundle [tweedegolf/prometheus-bundle](https://github.com/tweedegolf/prometheus-bundle)
4. Mettre en place une sonde pour détecter les tentatives répétées d'authentification échouées pour une adresse IP donnée.
5. Mettre en place une alerte lorsque le nombre d'authentifications échouées dépasse un certain seuil dans un espace de temps donné.
---
## Sécurité de l'infrastructure pour l'hébergement Web
### Sécurité et configuration du serveur GNU/Linux
### Configuration du serveur HTTP
### Monitoring
---
## Sécurité et configuration du serveur GNU/Linux
### Installation du serveur
### Politique d'accès et configuration SSH
### Règles de pare-feu
### Politique de sauvegarde
---
## Installation du serveur
---
## Règles générales de partitionnement (1)
- Utiliser [LVM](https://wiki.ubuntu.com/Lvm)
- ~300/500M pour `/boot`
- Partition séparée pour `/var` ( via un volume logique)
- Partition séparée pour `/home` (via un volume logique)
- Partition séparée pour `/` (via un volume logique)
- Garder de l'espace pour pouvoir agrandir au besoin une partition LVM
---
### Règles générales de partitionnement (2)
**Exemple** Pour 10G de disque
|Point de montage|Système de fichier|Taille|
|:-|:-|:-|
|`/boot`|ext4 (Primaire)|500M
|`/`|ext4 (LVM)|4G (~30/40%)
|`/home`|ext4 (LVM)|1G (10%)|
|`/var`|ext4 (LVM)|3G (~30/40%)|
|`swap`|swap (LVM)| round(sqrt(RAM) < swap < 2*RAM |
Et garder ~10% d'espace libre pour pouvoir agrandir un volume logique au besoin.
---
## Activation des mises à jour automatiques
Si à l'installation l'option n'est pas proposée (sur Debian et dérivées)
```bash
apt-get install unattended-upgrades apt-listchanges
```
[Voir la documentation Debian pour plus d'informations](https://wiki.debian.org/UnattendedUpgrades)
---
## Politique d'accès et configuration SSH
---
## Installation du serveur OpenSSH
```bash
apt install openssh-server
```
---
## Désactivation de l'authentification SSH avec l'utilisateur `root`
```bash
vim /etc/ssh/sshd_config
# ...
# PermitRootLogin no
# ...
systemctl restart ssh
```
---
## Désactivation de la connexion SSH avec un mot de passe
```bash
vim /etc/ssh/sshd_config
# ...
# PasswordAuthentication no
# ...
systemctl restart ssh
```
---
## Restreindre les utilisateurs et/ou groupes autorisés à se connecter en SSH
```bash
vim /etc/ssh/sshd_config
# ...
# AllowUsers jdoe bob
# AllowGroups jdoe bob
# ...
systemctl restart ssh
```
---
## Augmenter la taille des clés SSH du serveur
```bash
vim /etc/ssh/sshd_config
# ...
# ServerKeyBits 2048
# ...
rm /etc/ssh/ssh_host_*
systemctl restart ssh
```
---
## Créer des comptes utilisateurs avec un mot de passe expiré (1)
```bash
adduser