meteor meets mallory
DESCRIPTION
devshop talk 7/25/13TRANSCRIPT
![Page 1: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/1.jpg)
Meteor meets Mallory*Emily Stark, Meteor core [email protected]
* Mallory is usually the name of the bad guy in crypto/security stuff
![Page 2: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/2.jpg)
Meteor security model and best
practices
![Page 3: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/3.jpg)
Outline
1. Meteor security principles
2. Cross-site scripting
3. Mongo injections
![Page 4: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/4.jpg)
Meteor security principles
![Page 5: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/5.jpg)
Secure design principles
○ Data and code are separate
○ Easy to reason about client/server boundary
○ Stateful connections that must be deliberately authenticated
![Page 6: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/6.jpg)
Securely structuring your app
○ Server code is trusted, client code is not○ server/ or Meteor.settings for secrets○ Meteor.isServer doesn't make code private
○ Use publications and allow/deny to lock down database API○ Allow/deny rules not applied to server code
![Page 7: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/7.jpg)
Cross-site scripting
![Page 8: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/8.jpg)
Cross-site scripting (XSS)
![Page 9: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/9.jpg)
Cross-site scripting (XSS)
![Page 10: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/10.jpg)
Meteor foils some attacks
< > ' " ` &
< > ' " ` &
when inside {{ }}
(packages/handlebars/evaluate-handlebars.js)
![Page 11: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/11.jpg)
But not all
<a href="{{ userWebsite }}"> {{ username }}'s website</a>
![Page 12: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/12.jpg)
URL sanitization
<a href="javascript:alert(localStorage)"> {{ username }}'s website</a>
![Page 13: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/13.jpg)
URL sanitization
<a href="javascript:alert(localStorage)"> {{ username }}'s website</a>
Can you execute any damaging Javascript when quotes are escaped?
![Page 14: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/14.jpg)
URL sanitization
<a href="javascript:eval(String.fromCharCode(77, 101, ...))"> {{ username }}'s website</a>
![Page 15: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/15.jpg)
CSS sanitization<div style="background-color:{{ usersFavoriteColor }}"></div>
![Page 16: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/16.jpg)
CSS sanitization<div style="background-color:expression(alert(localStorage))"></div>
![Page 17: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/17.jpg)
Sanitize untrusted URLs and CSS
○ Don't try to filter out "javascript:", "expression", etc.
○ Do strict checking: urls start with http, css values come from a list of safe values
○ Use Content Security PolicyEx: Content-Security-Policy: default-src 'self'
![Page 18: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/18.jpg)
Mongo injections
![Page 19: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/19.jpg)
Mongo injections
Meteor.methods({ getUser: function(user, pwd) { return Users.findOne({ username: user, password: pwd }); }});
user: "Alice"pwd: {$ne: "foo"}
![Page 20: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/20.jpg)
Using check
Meteor.methods({ getUser: function (user, pwd) { check(user, String); check(pwd, String); return Users.findOne({ user: user, password: pwd }); }});
![Page 21: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/21.jpg)
check is versatile
check(usernames, [String])
check(profile, { admin: Boolean, location: Match.Optional(String)});
check(age, Match.OneOf(String, Number))
![Page 22: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/22.jpg)
Using audit-argument-checks
Meteor.methods({ insertName: function (name) { MyCollection.insert({ name: name
}); console.log("Inserted", {name: name});
}});
insertName({ foo: "bar"})
![Page 23: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/23.jpg)
Using audit-argument-checks
Inserted {"name": {"foo": "bar"}}insertName({
foo: "bar"})
![Page 24: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/24.jpg)
Using audit-argument-checks
meteor add audit-argument-checksinsertName({
foo: "bar"})
![Page 25: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/25.jpg)
Using audit-argument-checks
Inserted {"name": {"foo": "bar"}}Exception while invoking method 'insertName'Error: Did not check() all arguments during call to 'insertName'
insertName({ foo: "bar"})
![Page 26: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/26.jpg)
What was that Meteor 0.6.4.1 release all about?
Meteor.methods({ saveUser: function(profile) { delete profile.admin; Users.insert(profile); }});
<malicious input>
{"admin": "true!", "\x01...": null, ...}
![Page 27: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/27.jpg)
Conclusion
○ Meteor security design principles○ Securing boundary between client and server○ Data/code separation
○ Some attacks to watch out for○ Always validate untrusted user input
○ security-resources.meteor.com
![Page 28: Meteor Meets Mallory](https://reader033.vdocuments.mx/reader033/viewer/2022050906/554f8e29b4c9052a518b525c/html5/thumbnails/28.jpg)
Questions?