Sécurité dans les projets de développement

Retrouvez ce cours

https://grunk.github.io/sec_dev/

Qui suis-je ?

Olivier ROGER

Développeur & Architecte @ Pryntec

+15 XP

Expert PHP, Senior Android, JS, C++, SQL, etc ...

Dév web, Informatique industrielle, vidéo surveillance, ...

En ligne : oroger.fr / grunk @ dvp | stackoverflow | github

Tour de table

Sommaire

  1. Prologue
  2. S-SDLC
  3. Sécurité dans les différentes étapes du processus
  4. Frameworks
  5. Services Web
  6. Base de données
  7. Code
  8. Conclusion

Prologue

Cyber attaques

7 types

  • Malware
  • Phishing
  • Déni de service
  • Man in the middle
  • Cryptojacking
  • Injection SQL
  • Faille 0-day

Cyber attaques

Quelques exemples

La sécurité est primordiale

S-SDLC

Avant

  • Cycle traditionnel (cascade, V, agile, ...)
  • Sécurité au moment des tests finaux

Sécurité

Avant

Les problèmes

  • Effet de silo
  • Feedback long à venir
  • Beaucoup de vulnérabilités non traitées

=

Avant

Les compromis

A SEISMIC SHIFT IN APPLICATION SECURITY - Gitlab

On veux tout tester mais ... Donc on ... Mais ...
Pas les moyens test uniquement ce qu'on pense à risque les attaquants peuvent naviguer horizontalement
Manque d'expert se repose sur des tests externes ponctuels Les exploits évoluent très vite
Déjà trop à corriger réduits les tests De multiples test permettent de trouver différents type d'exploits

Définition S-SDLC

  • Méthodologie globale
  • Standard pour le développement
  • Défini les bonnes pratiques
  • Réduit les vulnérabilités

Qu'est ce qu'une vulnérabilité ?

Un défaut dans un logiciel

  • Élévation de privilèges
  • Compromission de données

TOP 3

  1. Buffer overflow (CWE-119)
  2. XSS (CWE-79)
  3. IIV (CWE-20)

Shift left

Liste des risques

Conception sûre

Analyse statique (white box)

Test auto, CI/CD

Audit (black box)

Monitoring

Prévention + Analyse des correctifs

DEVOPS

Avantage du S-SDLC

  • Détection/Résolution des vulnérabilités relativement tôt
  • Réduction des coûts
  • Prise de conscience de la sécurité par toutes les parties prenantes
  • Globalement moins de risque pour la société
  • Meilleure qualité globale

Comment ca marche ?

Ajout des notions de sécurité dans un process de développement

Ex : écrire les contraintes sécuritaires en même temps que le besoin fonctionnel

Comment le mettre en place ?

  • Formez toutes les parties prenantes
  • Utilisez l'existant (MS SDL, NIST 800-64, OWASP CLASP, ASVS)
  • S'outiller correctement et mutualiser
  • Outils : Analyse statique, revue de code , pen test, etc ...

Comment le mettre en place ? : Outils

 

  • DevOps : Gitlab / Github / Jenkis / Kubernete ...
  • Analyse statique : CppCheck, Lint, SonarQube, ...
  • Pen test / Audit : Nessus, nmap, Kali Linux

Sécurité dans les différentes étapes du processus

Les étapes

  • GO / NO GO
  • Conception
  • Tests unitaires *
  • Développement
  • Tests fonctionels *
  • Audit externe

GO/NO GO

 

  • Estimation des risques
  • Avons nous les compétences techniques ?
  • Se met-on en péril ?

Conception

  • Déterminer les données à protéger

  • Déterminer le type d'attaquant

Connaitre son environnement

Ex : Facebook et Impots.gouv.fr

Conception

 

Sécurité de l'information

  • Confidentialité
  • Intégrité
  • Accessibilité

Conception

 

Architecture

  • Doit couvrir le risque des usages normaux ET extrêmes
  • "On ne savait pas" est interdit
  • Pas d'architecture = pont sans étude
  • Le processus est il sûr ?
  • Comment je pourrais en abuser ?
  • Est-ce obligatoire par défaut ?

Conception

 

10 principes de sécurité

  • Minimiser la surface d'attaque
  • Sécuriser par défaut
  • Principe du moindre privilège
  • Sécurité par couche
  • Échouer de façon sûre
  • Ne pas avoir confiance dans les services
  • Séparation des rôles
  • Secret n'est pas sûr
  • Rester simple
  • Corriger de manière sûre
  • Connexion identifiant / mot de passe

  • Email de confirmation

  • Récupération de mot de passe

  • Connexion "permanente"

Exercice

Page de login

Tests

"White box testing"

  • Faille de sécurité interne
  • Chemins logiques
  • Workflow des inputs
  • Validité des outputs
  • Fonctionnement des boucles conditionnelles
  • Test de tous les objets, fonctions et déclarations

 

Tests

Tests unitaires

public function testPasswordSize()
{
    $login = new Login();
    $tooShort = 'toto';
    $tooWeak = 'jesuisunmotdepasse';
    $ok = 'Je$u!5u|\|M0†d3P4$$e';

    $this->boolean($login->checkPassword($tooShort))->isFalse();
    $this->boolean($login->checkPassword($tooWeak))->isFalse();
    $this->boolean($login->checkPassword($ok))->isTrue();
}

Failles internes

public function testDateOutput()
{
    $date = '2019-11-11 10:00:00';
    $util = new DateFormatter();

    $this->string($util->format($date,'d/m/Y'))
    	 ->isEqualTo('11/11/2019');
}

Validité des outputs

public function testLoop()
{
    $looper = new MyObj();
    $array = $looper->GenerateDatas(10);

    $this->integer(count($array))
          ->isEqualTo(10);
}

Boucle conditionnelle

Améliorer le test coverage

Développement

Standard

ASVS

Evaluer

Extraire

Règles pour un standard sécurisé

Outils

Tests

Revue de code

int MyClass::MySuperNewFeature() {
	auto obj = new MyObject();
    int r = obj->GetResult();
    return r;
}

Merge/Pull Request = code review

Intégration

int MyClass::MySuperNewFeature() {
	auto obj = new MyObject();
    int r = obj->GetResult();
    delete obj;
    return r;
}

"Fuite mémoire"

/**
* @brief Super fonctionnalité
*/
int MyClass::MySuperNewFeature() {
	auto obj = new MyObject();
    int r = obj->GetResult();
    delete obj;
    return r;
}

"Documentation"

Test d'intégration

Black box testing

  • Tests fonctionnels
  • Tests non fonctionnels
  • Tests de non régressions

Audit

Externe

Interne

  • Indépendant
  • Experts
  • Détaillé
  • Cher
  • Abordable
  • Expertise ?

 FRAMEWORKS

Software Security Assurance

Processus qui aide à concevoir et implémenter des logiciels qui protègent les données qu'ils manipulent

Software Security Assurance

Pour qui ?

  • Développeurs
  • Testeurs
  • Opérations

Les modèles

  • ISO 27034
  • NIST SP-800-64
  • M$ SDL
  • BSIMM
  • OSWAP SAMM

ISO 27034

  • Process de gestion du risque
  • Pas terminé
  • Pas gratuit

NIST SP-800-64

  • Un peu ancien
  • Pensé pour les gouvernement
  • Difficile à lire
  • Présente les choses plutôt bien

Microsoft SDL

  • Compréhensible
  • D'actualité
  • Pas une roadmap
  • Bon choix en environnement Microsoft

BSIMM

  • Pas un framework
  • Pas un guide
  • Etudes des initiatives de sécurité
  • + de 100 entreprises (Adobe, Paypal, Alibaba, Nivida, ...)
  • Mètre étalon

BSIMM

Résumé

  • Tout le monde est responsable de la sécurité d'un logiciel
  • C'est difficile pour tout le monde
  • La tendance est à l'amélioration (lente)

BSIMM

Quelques stats

  • 89.3% font du pen test externe
  • 63% forme à la sécurité (sensibilisation)
  • 59.8% éduque les dirigeants
  • 29.5% identifie les attaquants potentiels
  • 10% bug bounty

OSWAP SAMM

OSWAP SAMM

Gouvernance

Stratégie et métrique

Conformité

Formation

  • Comment aborder les risques
  • Comment se plier aux règles
  • Comment garder tlm à jour

OSWAP SAMM

Construction

Exigences en matière de sécurité

Évaluation de la menace

Architecture sécuritaire

  • Défini les exigences pour être sûr
  • Qui ? Pourquoi ? Comment ?
  • Sûr par défaut

OSWAP SAMM

Vérification

Design review

Revue de code

Test de sécurité

  • Défini les surfaces d'attaque du logiciel
  • Analyse les choix face aux menaces connues
  • Etablir les process pour effectuer les tests de sécurité
  • Assure la qualité du code

OSWAP SAMM

Déploiement

Gestion des vulnérabilités

Durcissement de l’environnement

Operational enablement

  • Quelles réactions face aux vulnérabilités
  • Comment avoir une bonne communication entre dév et utilisateurs
  • Patching
  • Monitoring

OSWAP SAMM

Comment démarrer

SAMM Assessment toolbox

Roadmap

Work !

OSWAP SAMM

Exercice : EG 0 à EG3

https://opensamm.org/downloads/SAMM-1.0-en_US.pdf

Services WEB

4 fondamentaux

  • Authentification
  • Confidentialité
  • Intégrité
  • Non répudiation

Authentification

Client

Serveur

  • Login/mdp
  • Certificat x509
  • SAML/OAuth

"je suis : xxxx"

"Données de : xxxx"

Attaquant

Confidentialité

Client

Serveur

Attaquant

Donnée

secrète

Chiffrement

Déchiffrement

TUNNEL

Intégrité

Client

Serveur

Attaquant

1€

100€

100€

Signature

bc32a

af44

bc32a != af44

Non répudiation

Client

Attaquant

1€

Serveur

REST vs SOAP

  • Simple à mettre en place
  • Facile à utiliser
  • Sécurité à la charge du développeur
  • Compliqué
  • XML
  • WS-Security
  • SAML

Dans la pratique

  • Login/mot de passe
  • Clé API
  • HTTPS
  • Journalisation des actions
  • Mécanisme de bannissement
  • Adapté la sécurité à votre environnement

Utiliser l'architecture

  • VPN quand c'est possible
  • Préférer https aux solutions persos
  • Avoir des protections DDOS

Base de données

Top 5

  • Abus de privilège excessif
  • Abus de privilège légitime
  • Défaut de configuration ou màj
  • Elévation de privilège
  • Injection SQL

 

Bonnes pratiques

Compartimenter

App 1

R

App 2

RW

App 2

RW+Admin

UserApp1

UserApp2

UserApp3

UserAdmin

Bonnes pratiques

Architecture

App distante

Webservice

Offline

Bonnes pratiques

Journalisation

  • Externaliser les journaux
  • Journaliser les requêtes importantes
  • Eviter le bruit dans les journaux

Bonnes pratiques

En vrac

  • Identifier et protéger
  • Mot de passe robuste
  • Anonymiser
  • Changer config par défaut
  • Préserver l’intégrité

Injections SQL

Introduction

  • Exécution de code SQL non prévu
  • Origine = construction de requête dynamique
SELECT password FROM users WHERE login = 'admin'
$user = $_POST['user'];
$req = 'SELECT password FROM users WHERE login = '.$user

Injection impossible

Risque d'injection

Injections SQL

Contournement d'une identification

$login = $_GET['login'];
$password = $_GET['password'];

$query = '
	 SELECT id, login 
     FROM users 
     WHERE login = '.$login.' AND password ='.$password;

Injections SQL

Contournement d'une identification

http://monsite.com/connect?login=admin&password=12345

SELECT id, login 
     FROM users 
WHERE login = 'admin' AND password ='12345';

password=unknown' or '1'='1

SELECT id, login 
     FROM users 
WHERE login = 'admin' AND password ='unknown' or '1'='1;

Accès autorisé !

http://oroger.fr/labs/injection/

Injections SQL

Contournement d'une identification

SELECT id, login 
     FROM users 
WHERE login = 'unknown' or '1'='1' AND password = 'unknown' or '1'='1';

login = unknown' or '1'='1

password = unknown' or '1'='1

Injections SQL

Extraction de données

SELECT info,... FROM activites WHERE user_id = 1

http://monsite.com/list?id=1 

SELECT info,... FROM activites WHERE user_id = 1 UNION SELECT username, password FROM users

Vol de toute la liste des utilisateurs et mots de passe

UNION SELECT username, password FROM users

Injections SQL

Backdoor

SELECT info,... FROM activites WHERE user_id = 1
SELECT info,aff FROM activites WHERE user_id = 1 
UNION 
SELECT null,'ici du code dangereux' 
INTO OUTFILE '/var/www/backdoor.php'

http://monsite.com/backdoor.php

Injections SQL

Protection

2 solutions possibles : 

 

  1. Échapper / caster toutes les données
  2. Utiliser les requêtes préparées

Injections SQL

Requêtes préparées

  • Stockées en mémoire
  • Meilleures performances si appelées plusieurs fois
  • Sécurisées

Injections SQL

Requêtes préparées : principe

SELECT id, login 
     FROM users 
WHERE login = $1 AND password = $2;

PREPARE

BIND ('admin')

BIND ('12345')

EXECUTE()

Injections SQL

Requêtes préparées : injection

SELECT id, login 
     FROM users 
WHERE login = $1 AND password = $2;

PREPARE

BIND ("admin'#")

BIND ('12345')

SELECT id, login 
     FROM users 
WHERE login = "admin'#" AND password ="12345";

Le code

Never trust user input

Risques

Solutions

Saisie de données innatendues

Crash application

Comportements aléatoires

Validation de saisie

cast,filtre,regex ...

$email = filter_var($email, FILTER_VALIDATE_EMAIL);
const regex = /^((\+|00)33\s?|0)[67](\s?\d{2}){4}$/;
if ((m = regex.exec(str)) !== null) {
	// OK
}

Vol de données (xss)

Never trust user input

Saisie de données innatendues

  • Validation serveur uniquement !

  • Aucune donnée n'est sûre

Masquer ce qui est sensible

Mot de passe , clé de chiffrement, clé API, données sensibles

Risques

Solutions

Usurpation d'identité

Vol de données

Prise de contrôle

Obfuscation

Délocaliser*

Masquer ce qui est sensible

Exemple

std::string codeSecret = "MYPassword";
[...]
if(login == codeSecret) {
  DisplayAdminWindow();
}

Quelles solutions ?

Échouer de manière sûre

isAdmin = true;
try {
  codeWhichMayFail();
  isAdmin = isUserInRole( “Administrator” );
}
catch (Exception ex) {
  log.write(ex.toString());
}

Chiffrer

Utiliser des chiffrements ou hash fort.

https://blog.codinghorror.com/your-password-is-too-damn-short/

Exercice : trouver la valeur de : d0763edaa9d9bd2a9516280e9044d885

Mots de passe durcis

  • 12 caractères mini
  • mixer les types
  • Interdire le top 1000
  • Ceciestmonmotdepasse > !fOp$4ù!

Bruteforce

  • Désactiver les comptes après trop de tentatives
  • Ralentir les actions (captcha, api)
  • Eviter les configs par défaut (port)
  • Page de connexion unique
  • Logs monitoring (fail2ban)

Ne pas trop en dire

  • Ne pas donner trop d'informations
  • Particulièrement sur les messages d'erreur (ex mauvais mdp)
  • On peut éventuellement sacrifier un peu l'UX

Attention aux dépendances

  • Own your code
  • Limiter les dépendances
  • Choisir avec soin les dépendances
const num = 5;
num.isNaN();
  • Un projet n'est jamais sûr à 100%
  • Toujours mesurer le ratio risque / temps
  • Etre en veille perpétuelle