From c5aac88bf460ea2a42698267543f5949ab76c7d7 Mon Sep 17 00:00:00 2001 From: Subbu Allamaraju Date: Mon, 13 Feb 2012 15:50:50 -0800 Subject: [PATCH 1/8] Retrofit version numbers --- modules/app/package.json | 8 ++++---- modules/engine/package.json | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/app/package.json b/modules/app/package.json index 4f880872..691cc6a7 100644 --- a/modules/app/package.json +++ b/modules/app/package.json @@ -15,10 +15,10 @@ "dependencies": { "cluster": "0.7.7", "commander": "0.0.5", - "ql.io-console": "", - "ql.io-compiler": "", - "ql.io-mon": "", - "ql.io-ecv": "", + "ql.io-console": "<0.4.0", + "ql.io-compiler": "<0.4.0", + "ql.io-mon": "<0.4.0", + "ql.io-ecv": "<0.4.0", "express": "2.4.7", "winston": "0.3.5", "ejs": "0.4.3", diff --git a/modules/engine/package.json b/modules/engine/package.json index 83409b8c..72e285d8 100644 --- a/modules/engine/package.json +++ b/modules/engine/package.json @@ -14,9 +14,9 @@ "winston": "0.3.5", "underscore": "1.2.1", "xml2json": "", - "ql.io-compiler": "", - "ql.io-mutable-uri": "", - "ql.io-uri-template": "", + "ql.io-compiler": "<0.4.0", + "ql.io-mutable-uri": "<0.4.0", + "ql.io-uri-template": "<0.4.0", "JSONPath": "latest", "uri": ">=0.1.0", "headers": "0.9.6", From 27045c81ee1c39dd69bf2c34b0574bb8ab9bf3bc Mon Sep 17 00:00:00 2001 From: Subbu Allamaraju Date: Mon, 13 Feb 2012 15:52:03 -0800 Subject: [PATCH 2/8] One more retrofit --- modules/console/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/console/package.json b/modules/console/package.json index 0d909861..282e920c 100755 --- a/modules/console/package.json +++ b/modules/console/package.json @@ -15,7 +15,7 @@ "express": "2.4.7", "ejs": "0.4.3", "underscore": "1.2.1", - "ql.io-engine": "", + "ql.io-engine": "<0.4.0", "winston": "0.3.5", "browserify": "1.7.6", "uglify-js": "1.1.1", From f931f0cacb66f6a10126a0a996b17012d93fc9e2 Mon Sep 17 00:00:00 2001 From: Subbu Allamaraju Date: Tue, 14 Feb 2012 07:31:33 -0800 Subject: [PATCH 3/8] XSS fix for 404 responses --- CHANGES.md | 2 + modules/console/app.js | 40 +++++++ modules/console/package.json | 2 +- modules/console/test/test-console-sanity.js | 109 +++++++++++++++++++- 4 files changed, 151 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 59fe1842..36cf3fab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,5 @@ +## Feb 14, 2012 +* XSS issue for 404 response fixed. ## Feb 13, 2012 diff --git a/modules/console/app.js b/modules/console/app.js index 7ff06b63..30569832 100644 --- a/modules/console/app.js +++ b/modules/console/app.js @@ -284,6 +284,46 @@ var Console = module.exports = function(config) { } ); + // 404 Handling + app.use(function (req, res, next) { + var msg = 'Cannot GET ' + sanitize(req.url).xss(); + var accept = (req.headers || {}).accept || ''; + if (accept.search('json') > 0) { + res.writeHead(404, { + 'content-type':'application/json' + }); + res.write(JSON.stringify({ error:msg })); + res.end(); + return; + } + res.writeHead(404, { + 'content-type':'text/plain' + }); + res.write(msg); + res.end(); + }); + + // Error-handling middleware + app.use(function (err, req, res, next) { + // TODO call next() if recoverable, else next(err). + var status = err.status || 500; + var msg = "Server Error - " + err.msg || err; + var accept = (req.headers || {}).accept || ''; + if (accept.search('json') > 0) { + res.writeHead(status, { + 'content-type':'application/json' + }); + res.write(JSON.stringify({ error:msg })); + res.end(); + return; + } + res.writeHead(status, { + 'content-type':'text/plain' + }); + res.write(msg); + res.end(); + }); + // Also listen to WebSocket requests var emitter; var server = new WebSocketServer({ diff --git a/modules/console/package.json b/modules/console/package.json index 282e920c..dfa4e100 100755 --- a/modules/console/package.json +++ b/modules/console/package.json @@ -1,7 +1,7 @@ { "author": "ql.io", "name": "ql.io-console", - "version": "0.3.5", + "version": "0.3.6", "repository": { "type": "git", "url": "https://github.com/ql-io/ql.io" diff --git a/modules/console/test/test-console-sanity.js b/modules/console/test/test-console-sanity.js index b14196dd..e3723620 100644 --- a/modules/console/test/test-console-sanity.js +++ b/modules/console/test/test-console-sanity.js @@ -61,5 +61,112 @@ module.exports = { }); req.end(); }); + }, + '404-text':function (test) { + var c = new Console({ + tables:__dirname + '/tables', + routes:__dirname + '/routes/', + 'enable console':false, + connection:'close' + }); + c.app.listen(3000, function () { + var options = { + host:'localhost', + port:3000, + path:'/notfound.pl?\">', + method:'GET', + headers:{ + host:'localhost', + connection:'close' + } + }; + var req = http.request(options, function (res) { + test.equals(res.statusCode, 404); + test.equals(res.headers['content-type'], 'text/plain'); + var data = ''; + res.on('data', function (chunk) { + data = data + chunk; + }); + res.on('end', function () { + test.ok(data === "Cannot GET /notfound.pl?\">[removed]alert(73541);[removed]"); + c.app.close(); + test.done(); + }); + }); + req.end(); + }); + }, + '404-json':function (test) { + var c = new Console({ + tables:__dirname + '/tables', + routes:__dirname + '/routes/', + 'enable console':false, + connection:'close' + }); + c.app.listen(3000, function () { + var options = { + host:'localhost', + port:3000, + path:'/notfound.pl?\">', + method:'GET', + headers:{ + host:'localhost', + connection:'close', + accept:'application/json' + } + }; + var req = http.request(options, function (res) { + test.equals(res.statusCode, 404); + test.equals(res.headers['content-type'], 'application/json'); + var data = ''; + res.on('data', function (chunk) { + data = data + chunk; + }); + res.on('end', function () { + test.ok(data === '{"error":"Cannot GET /notfound.pl?\\\">[removed]alert(73541);[removed]"}'); + c.app.close(); + test.done(); + }); + }); + req.end(); + }); + }, + '5xx-json':function (test) { + var c = new Console({ + tables:__dirname + '/tables', + routes:__dirname + '/routes/', + 'enable console':false, + connection:'close' + }); + c.app.get('/500', function (req, res, next) { + next(new Error('test error!')); + }); + c.app.listen(3000, function () { + var options = { + host:'localhost', + port:3000, + path:'/500', + method:'GET', + headers:{ + host:'localhost', + connection:'close', + accept:'application/json' + } + }; + var req = http.request(options, function (res) { + test.equals(res.statusCode, 500); + test.equals(res.headers['content-type'], 'application/json'); + var data = ''; + res.on('data', function (chunk) { + data = data + chunk; + }); + res.on('end', function () { + test.ok(data.indexOf('{"error":"Server Error') === 0); + c.app.close(); + test.done(); + }); + }); + req.end(); + }); } -} \ No newline at end of file +} From 55a14e2e5eca69d172d02dd41cde49ffc20e4e6c Mon Sep 17 00:00:00 2001 From: Cylus Penkar Date: Tue, 21 Feb 2012 12:58:16 -0800 Subject: [PATCH 4/8] Bug fix for handling duplicate routes with different query params --- modules/console/app.js | 14 ++++-- .../test/routes/a-useritems-withDelete.ql | 13 +++++ modules/console/test/test-route.js | 49 ++++++++++++++++++- 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 modules/console/test/routes/a-useritems-withDelete.ql diff --git a/modules/console/app.js b/modules/console/app.js index 30569832..1b16b8ee 100644 --- a/modules/console/app.js +++ b/modules/console/app.js @@ -197,10 +197,16 @@ var Console = module.exports = function(config) { collectHttpQueryParams(req, holder, false); // find a route (i.e. associated cooked script) - var route = _.detect(verbRouteVariants, function(verbRouteVariant) { - return _.isEqual(_.intersection(_.keys(holder.params), _.keys(verbRouteVariant.query)), - _.keys(verbRouteVariant.query)); - }); + var route = _(verbRouteVariants).chain() + .filter(function (verbRouteVariant) { + return _.isEqual(_.intersection(_.keys(holder.params), _.keys(verbRouteVariant.query)), + _.keys(verbRouteVariant.query)) + }) + .reduce(function (match, route) { + return match == null ? + route : route.length > match.length ? route : match; + }, null) + .value(); if (!route) { res.writeHead(400, 'Bad input', { diff --git a/modules/console/test/routes/a-useritems-withDelete.ql b/modules/console/test/routes/a-useritems-withDelete.ql new file mode 100644 index 00000000..146ef953 --- /dev/null +++ b/modules/console/test/routes/a-useritems-withDelete.ql @@ -0,0 +1,13 @@ +-- Type ql script here - all keywords must be in lower case +item = select * from ebay.shopping.singleitem where itemId = '260852758792'; +profile = select * from ebay.shopping.userprofile where includeSelector = "{selector}" and userId = "260852758792"; +tradingItem = select * from ebay.trading.getitem where itemId = '260852758792'; +bidders = select * from ebay.trading.getallbidders where itemId = '260852758792'; +bestOffers = select * from ebay.trading.bestoffers where itemId = '260852758792'; +return { +"user" : "{profile}", +"item" : "{item}", +"tradingItem" : "{tradingItem}", +"bidders" : "{bidders}", +"bestOffers" : "{bestOffers}" +} via route "/del/foo/bar/{selector}?userid={userId}" using method delete; \ No newline at end of file diff --git a/modules/console/test/test-route.js b/modules/console/test/test-route.js index 48d536b2..f767ae5b 100644 --- a/modules/console/test/test-route.js +++ b/modules/console/test/test-route.js @@ -24,7 +24,7 @@ var _ = require('underscore'), url = require('url'); module.exports = { - 'check delete call' : function(test) { + 'check delete /del/foo/bar/{selector}?userid={userId}&itemid={itemId}' : function(test) { var c = new Console({ tables : __dirname + '/tables', routes : __dirname + '/routes/', @@ -71,6 +71,53 @@ module.exports = { }); }) }, + 'check delete /del/foo/bar/{selector}?userid={userId}' : function(test) { + var c = new Console({ + tables : __dirname + '/tables', + routes : __dirname + '/routes/', + config : __dirname + '/config/dev.json', + 'enable console' : false, + connection : 'close' + }); + c.app.listen(3000, function() { + var testHttpapp = express.createServer(); + testHttpapp.post('/ping/pong', function(req, res) { + var data = ''; + req.on('data', function(chunk) { + data += chunk; + }); + req.on('end', function() { + res.send(data); + }); + }); + + testHttpapp.listen(80126, function() { + var options = { + host : 'localhost', + port : 3000, + path : '/del/foo/bar/Details?userid=sallamar', + method : 'DELETE' + }; + var req = http.request(options); + req.addListener('response', function(resp) { + var data = ''; + resp.addListener('data', function(chunk) { + data += chunk; + }); + resp.addListener('end', function() { + var json = JSON.parse(data); + test.ok(json.user, 'missing user data'); + test.ok(json.user.Ack, 'missing user Ack'); + test.equal(json.user.Ack, 'Success'); + c.app.close(); + testHttpapp.close(); + test.done(); + }); + }); + req.end(); + }); + }) + }, 'check post json call' : function(test) { var c = new Console({ tables : __dirname + '/tables', From bc30f45297463929c9b0d91d1bc7f0b607aae20e Mon Sep 17 00:00:00 2001 From: shimonchayim Date: Tue, 21 Feb 2012 13:06:29 -0800 Subject: [PATCH 5/8] Update modules/console/package.json --- modules/console/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/console/package.json b/modules/console/package.json index dfa4e100..d88e75de 100755 --- a/modules/console/package.json +++ b/modules/console/package.json @@ -1,7 +1,7 @@ { "author": "ql.io", "name": "ql.io-console", - "version": "0.3.6", + "version": "0.3.7", "repository": { "type": "git", "url": "https://github.com/ql-io/ql.io" From 221a55f4acab63fda639ae9610de87835fefbb21 Mon Sep 17 00:00:00 2001 From: shimonchayim Date: Tue, 21 Feb 2012 13:08:22 -0800 Subject: [PATCH 6/8] Update CHANGES.md --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 36cf3fab..54f875e4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +## Feb 14, 2012 +* Bug fix for https://github.com/ql-io/ql.io/issues/286 + ## Feb 14, 2012 * XSS issue for 404 response fixed. From 20dc7fcd8dd461bd5fcf1191256d820f5150aaa8 Mon Sep 17 00:00:00 2001 From: shimonchayim Date: Tue, 21 Feb 2012 13:08:59 -0800 Subject: [PATCH 7/8] Update CHANGES.md --- CHANGES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 54f875e4..990774bc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,5 @@ -## Feb 14, 2012 -* Bug fix for https://github.com/ql-io/ql.io/issues/286 +## Feb 21, 2012 +* Bug fix for https://github.com/ql-io/ql.io/issues/286 for 0.3 ## Feb 14, 2012 * XSS issue for 404 response fixed. From 8c09f6b6b4eab33e84ed8c2cf5ee913f6d0b1548 Mon Sep 17 00:00:00 2001 From: Cylus Penkar Date: Sun, 26 Feb 2012 19:52:16 -0800 Subject: [PATCH 8/8] Propogate fix for Issue #286 --- CHANGES.md | 3 +++ modules/console/app.js | 2 +- modules/console/package.json | 2 +- modules/console/test/routes/a-useritems-withDelete.ql | 2 +- modules/console/test/test-route.js | 1 + 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 990774bc..8a336b46 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,9 @@ ## Feb 21, 2012 * Bug fix for https://github.com/ql-io/ql.io/issues/286 for 0.3 +## Feb 21, 2012 +* Bug fix for https://github.com/ql-io/ql.io/issues/286 for 0.3 + ## Feb 14, 2012 * XSS issue for 404 response fixed. diff --git a/modules/console/app.js b/modules/console/app.js index 1b16b8ee..e3a8dd5c 100644 --- a/modules/console/app.js +++ b/modules/console/app.js @@ -204,7 +204,7 @@ var Console = module.exports = function(config) { }) .reduce(function (match, route) { return match == null ? - route : route.length > match.length ? route : match; + route : _.keys(route.query).length > _.keys(match.query).length ? route : match; }, null) .value(); diff --git a/modules/console/package.json b/modules/console/package.json index d88e75de..ff4452c8 100755 --- a/modules/console/package.json +++ b/modules/console/package.json @@ -1,7 +1,7 @@ { "author": "ql.io", "name": "ql.io-console", - "version": "0.3.7", + "version": "0.3.8", "repository": { "type": "git", "url": "https://github.com/ql-io/ql.io" diff --git a/modules/console/test/routes/a-useritems-withDelete.ql b/modules/console/test/routes/a-useritems-withDelete.ql index 146ef953..f0db4a6a 100644 --- a/modules/console/test/routes/a-useritems-withDelete.ql +++ b/modules/console/test/routes/a-useritems-withDelete.ql @@ -3,7 +3,7 @@ item = select * from ebay.shopping.singleitem where itemId = '260852758792'; profile = select * from ebay.shopping.userprofile where includeSelector = "{selector}" and userId = "260852758792"; tradingItem = select * from ebay.trading.getitem where itemId = '260852758792'; bidders = select * from ebay.trading.getallbidders where itemId = '260852758792'; -bestOffers = select * from ebay.trading.bestoffers where itemId = '260852758792'; +bestOffers = "Fixed Value"; return { "user" : "{profile}", "item" : "{item}", diff --git a/modules/console/test/test-route.js b/modules/console/test/test-route.js index f767ae5b..53dd3ad4 100644 --- a/modules/console/test/test-route.js +++ b/modules/console/test/test-route.js @@ -109,6 +109,7 @@ module.exports = { test.ok(json.user, 'missing user data'); test.ok(json.user.Ack, 'missing user Ack'); test.equal(json.user.Ack, 'Success'); + test.equal(json.bestOffers, 'Fixed Value'); c.app.close(); testHttpapp.close(); test.done();