https://blog.wishtack.com
Slides de la présentation au Meetup LyonJS #47
https://www.meetup.com/LyonJS/events/241197981/
https://www.facebook.com/lyonjs/videos/939104122896487/
7. Les 4 principaux
concepts de la sécurité
• Confidentialité : rejet des accès non autorisés.
• Intégrité : rejet des modifications non autorisées.
• Disponibilité : lutte contre les dénis de service.
• Non répudiation : capacité à fournir des preuves.
8. Les impacts
• Image de marque.
• Impact financier.
2011: DigiNotar ferme boutique après une intrusion.
https://en.wikipedia.org/wiki/DigiNotar
• Violation de conformité.
• Impacts légaux, sociaux, politiques, écologiques etc…
• Toutes les applications sont concernées sauf celles qui n’ont
jamais existé.
• La sécurité doit faire partie du Minimum Viable Product.
10. OWASP Top 10
• Top 10 des vulnérabilités web classées en fonction du
risque associé.
• Une version tous les 3 ans depuis 2004.
• La 2017 RC1 a été rejetée et la version finale est prévue
pour novembre (2017 ?).
12. Identification,
Authentification
et Autorisation
• Identification : On identifie une entité sans pouvoir en vérifier l’authenticité.
• Authentification : Il est possible de vérifier l’authenticité d’un message,
d’une action etc…
Cela n’implique pas forcément une identification.
Ex. : Enregistrement d’un pseudo sur IRC.
Ex. : Facebook’s Anonymous Login.
Ex. : Clés SSH.
• Autorisation : Détermine si une entité a accès à une ressource en fonction
des règles définis dans les A.C.L. (Access Control Lists).
Ex. : Accès autorisé / refusé à une ressource sur une API.
Ex. : Accès autorisé / masqué / refusé à une propriété d’une ressource.
• Les règles A.C.L. ne sont pas forcément associées à une entité.
Le porteur d’un “token” n’est donc pas forcément identifié.
Ex. : Un “token” temporaire partagé avec plusieurs utilisateurs pour accéder à un document.
13. Identification, Authentification
et Autorisation :
Vulnérabilités classiques
• Authentification et autorisation absentes ou insuffisantes.
• Authentification sans autorisation.
• Autorisations trop permissives sur les propriétés en
lecture ou en écriture.
14. Identification, Authentification
et Autorisation :
Best Practices
• “Separation of Concerns” : Séparez les logiques
d’identification, d’authentification, d’autorisation et business
dans des composants différents de votre architecture.
• Unit-testez l’accès à toutes les ressources (surtout les cas
d’erreur !).
• Evitez la sécurité par l’obscurité : obfuscation, protocoles
custom etc…
• Implémentez des logiques de filtrage par whitelist plutôt que
par blacklist.
15. Validation
• Les “inputs” et “outputs” de l’API doivent être “serialized” et
“parsed” de façon stricte pour éviter des accès non autorisés…
• … autrement, c’est la fête !
let {username, password} = req.body;
userCollection.findOne({
username: username,
password: password
});
• … et si password vaut {$ne: 'GOTCHA!!!'} ?
16. Validation
• Les “inputs” et “outputs” de l’API doivent être validés à
base de whitelists et côté API.
• La validation “client-side” n’est utile que pour l’UX.
17. Validation :
Best Practices
• Utilisez des couches dédiées à la “serialization”.
• Il est recommandé d’utiliser des “serializers” spécifiques
en fonction de l’autorisation accordée.
Ex.: ProductPublicSerializer, ProductAdminSerializer.
Ex. pythonic http://www.django-rest-framework.org/api-guide/serializers/
• La validation doit se faire pour tous les “inputs” et
“outputs” provenant de sources extérieures : utilisateurs,
partenaires etc…
18. C.S.R.F.
Cross-Site Request Forgery
smurf.com gargamel.com
1 - Log In 2 - Set-Cookie :
3 - Open app
( Smurfette is still signed in to
smurf.com even if she closes
smurf.com windows)
4 - Under the hood GET / POST / … requests
The browser adds the smurf.com Cookie.
DELETE /mushrooms
Cookie:
404
MushroomDB
19.
20. C.O.R.S.
Cross-Origin Resource Sharing
• “Origin” : scheme + FQDN + port.
https://www.wishtack.com(:443)
• Le client envoie une preflight request (méthode OPTIONS) indiquant l’”origin”, la méthode,
les headers si nécessaire :
• Méthode autre que GET / HEAD / POST.
• POST avec un media type autre que text/plain ou application/x-www-form-urlencoded ou multipart/
form-data.
• “Headers” modifiés autres que Accept / Accept-Language / Content-Type (Cf. condition
précédente) / Content-Language.
• Le serveur répond avec les headers :
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
21.
22. Comment introduire une
vulnérabilité C.S.R.F.
step by step en suivant StackOverflow
• http://stackoverflow.com/questions/20035101/no-access-
control-allow-origin-header-is-present-on-the-requested-
resource
• https://stackoverflow.com/questions/26411480/angularjs-
a-wildcard-cannot-be-used-in-the-access-control-allow-
origin-he
• Cookies, Basic Auth et Client Certificate sont tous CSRF-
friendly.
23. C.O.R.S.
Best Practices
• Configurez vos W.A.F. (Web Application Firewall) pour refuser
la valeur true pour le header Access-Control-Allow-
Credentials et supervisez ce comportement.
• En attendant la migration vers une authentification par token,
vérifiez que la valeur du header Access-Control-Allow-
Origin est définie à partir d’une whitelist stricte (pas de
regex).
• Attention au respect du ReST !
Les requêtes GET ne déclenchent pas forcément de preflight
request.
Ex. d’API vulnérable : GET /mushrooms?action=delete
24.
25. C.O.R.S.
Media Type gotchas
• Rejetez toutes les requêtes dont le Content-Type est
différent d’application/json ou le media type de
votre application.
• Si votre API utilise des credentials pour l’authentification
alors elle est automatiquement vulnérable dans les deux
cas suivants :
• L’API accepte le média type application/x-www-form-urlencoded.
• L’API ne vérifie pas le média type et suppose que le contenu est de type
application/json.
26. C.O.R.S.
Media Type gotchas
• Pour le fun, même pas besoin de JS :
<form
action="http://api.smurf.com/mushrooms"
enctype="text/plain"
method="POST"
target="_blank">
<input
hidden
name='{"name": "Amanita muscaria", "type": "poisonous", "extra": "'
value='"}'>
…
• Ce qui nous donne :
POST /mushrooms
Content-Type: text/plain
{"name": "Amanita muscaria", "type": "poisonous", "extra": "="}
27. J.W.T.
JSON Web Token
• J.O.S.E. : Un framework pour échanger des “claims” de
manière sécurisée.
• J.W.K. : JSON Web Key.
• J.W.E. : JSON Web Encryption.
• J.W.S. : JSON Web Signature.
• J.W.T. : JSON Web Token.
29. J.W.T.
Exemple d’utilisation
smurf.comidentity-provider.py
6 - Get Public Key
if not in cache
1 - Signin
request
2 - Redirect
3 - Authenticate
& Authorize
5 - Redirect with
J.W.T.
7 - Verify J.W.T.
with public key
8 - Send flowers
4 - Create J.W.T.
and sign with private key
30. J.W.T.
ou cryptographie
sans “Key Management”
• La cryptographie sans “Key Management”, c’est comme
une voiture sans freins, tant qu’on ne cherche qu’à rouler
en ligne droite sans s’arrêter, ça répond plutôt bien au
besoin…
• Analysons d’abord la sécurité de nos clés TLS.
31. Quand on vole
une clé T.L.S.
TLS Endpoint
@1.1.1.1
@2.2.2.2
AppD.N.S.
1 - Exploit Vulnerability
on TLS Endpoint
and steal Key2 - Cache Poisoning
(or ARP Spoofing etc…)
smurf.com => @2.2.2.2
3 - smurf.com ???
4 - GET https://smurf.com
C.A.
5 - Revoke
32. Quand on vole
une clé J.W.T.
App
1 - Exploit Vulnerability on App and steal Key
2 - Create arbitrary but valid JWT tokens and use them
D’OH! I’m smurfed up!
If I replace the key,
I will invalidate all previous JWTs
33. J.W.T.
Vulnérabilités classiques
• Stockage non sécurisé.
• data = jwt.decode(token, key)
vs.
data = jwt.verify(token, key)
•Signature stripping: {alg: 'none'}
• asymétrique ?
• HS256 nécessite une clé de longueur supérieure ou égale à :
256 bits / 32 bytes / 64 caractères hexadécimaux.
• HS256 vs RS256.
• Selon NIST :
1024 : RIP 2006
2048 : RIP 2030
4096 : ???
34. J.W.T.
Exemple RS256
• Et hop, 1/2 kilo de token :
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJqb2
huZG9lIiwiaWF0IjoxMzk3MzgzOTA4LCJrZXlpZCI6IjEyMyJ9.
b0cBt45NzbdAi21VNv_mVtGwYNWRJBkkWNyk_IQDTt6las
PvXUmbPU-6ou1Yj9FElRCDr7aqjvm7IaQHs0cx0aU5CmBY
EcvbTo7kNxJkhOtWl2XRU7Mk2zCNJgNK2eEEOHDTT48_U
MCkHcCGADYzJ5H9mPySeMGTYq4cHGHVbw5v6LRjXYaB
Xa1jgDfqjTqy5RL2hS19YYaKsoCm5Vsk1tsHAyz4TdqM-
Ctbuk6AnA57TL_-
zcx2XbXqv_ztTpdZSA9hLzXVJyFQOj-8hDmNHpZTTFLKfeC
Ha7HSZfQ1kUGD6AX-
Kn5Gk3nmaRv7Ox0Dtl-2v15BELiFCLAOFp1acw
35. J.W.T. Key Rotation
• Les clés doivent être générées et remplacées
dynamiquement et régulièrement.
• Les clés ne peuvent pas avoir une durée de vie inférieure
à celles des tokens générés.
• Chez Google, une durée moyenne de 3 jours : https://
www.googleapis.com/oauth2/v3/certs
36. WebSheep
• Inspiré de WebGoat, une application volontairement
vulnérable conçue pour le fun et l’apprentissage.
https://github.com/WebGoat/WebGoat
• WebSheep essaie de compléter WebGoat sur la partie
APIs ReST, NodeJS, J.W.T., …
https://github.com/wishtack/wishtack-websheep
37. Keep In Touch
• Pensez à vous inscrire à la newsletter pour recevoir les
picks of the week.
• https://blog.wishtack.com
• https://github.com/wishtack
• younes@wishtack.com
• @yjaaidi @wishtack