Web Security in
Node.js Applications
@scottksmith95
scottksmith.com
Slide 2
Slide 2 text
I’m Scott Smith
VP of Product
Development by Day
Full Stack Node & .NET
Developer by Night
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
• Injection
• Broken Authentication and Session
Management
• Cross Site Scripting (XSS)
• Cross Site Request Forgery (CSRF)
• Using Components with Known
Vulnerabilities
Slide 5
Slide 5 text
Injection
Slide 6
Slide 6 text
Attacker sends text-based attacks to
exploit the syntax of targeted interpreter
Slide 7
Slide 7 text
No content
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
Solution #1
Escape all user input
for SQL statements
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
No content
Slide 14
Slide 14 text
Solution #2
User parameterized SQL queries
Slide 15
Slide 15 text
No content
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
No content
Slide 18
Slide 18 text
eval(userInput) is dangerous
Slide 19
Slide 19 text
No content
Slide 20
Slide 20 text
No content
Slide 21
Slide 21 text
No content
Slide 22
Slide 22 text
Don’t use eval()
with user input
Slide 23
Slide 23 text
No content
Slide 24
Slide 24 text
No content
Slide 25
Slide 25 text
No content
Slide 26
Slide 26 text
No content
Slide 27
Slide 27 text
No content
Slide 28
Slide 28 text
No content
Slide 29
Slide 29 text
• Injection
• Broken Authentication and Session
Management
• Cross Site Scripting (XSS)
• Cross Site Request Forgery (CSRF)
• Using Components with Known
Vulnerabilities
Slide 30
Slide 30 text
Broken Authentication
and Session Management
Slide 31
Slide 31 text
Scenario #1
Attacker gains access to
database with plain text passwords
Slide 32
Slide 32 text
Solution
Always hash passwords
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
Scenario #2
Site supports session ids
within the URL
Slide 35
Slide 35 text
https://bank.com/account?sessionid=1234567
Slide 36
Slide 36 text
• Sharing of link grants others full access
https://bank.com/account?sessionid=1234567
Slide 37
Slide 37 text
• Sharing of link grants others full access
• Stored on cache servers
https://bank.com/account?sessionid=1234567
Slide 38
Slide 38 text
• Sharing of link grants others full access
• Stored on cache servers
• Stored in browser history
https://bank.com/account?sessionid=1234567
Slide 39
Slide 39 text
• Sharing of link grants others full access
• Stored on cache servers
• Stored in browser history
• Leaked through the Referer header
https://bank.com/account?sessionid=1234567
Slide 40
Slide 40 text
• Sharing of link grants others full access
• Stored on cache servers
• Stored in browser history
• Leaked through the Referer header
• Leaded through logs not properly protected
https://bank.com/account?sessionid=1234567
Slide 41
Slide 41 text
• Sharing of link grants others full access
• Stored on cache servers
• Stored in browser history
• Leaked through the Referer header
• Leaded through logs not properly protected
• Much more visible and dangerous
https://bank.com/account?sessionid=1234567
Slide 42
Slide 42 text
Solution
Store session ids in cookies
and never in the URL
Slide 43
Slide 43 text
No content
Slide 44
Slide 44 text
Scenario #3
Site employs long or
no session timeouts
Slide 45
Slide 45 text
Solution
Explicitly set expiration for session
Slide 46
Slide 46 text
Good
Slide 47
Slide 47 text
Better
Slide 48
Slide 48 text
Scenario #4
User accesses site on public
unencrypted wifi over HTTP
Slide 49
Slide 49 text
Solution #1
Run your site over HTTPS
Slide 50
Slide 50 text
Solution #2
Do not allow cookies to
be sent over HTTP
Slide 51
Slide 51 text
No content
Slide 52
Slide 52 text
Solution #3
Tell the browser to never make
requests over HTTP again
Slide 53
Slide 53 text
HTTP Strict Transport
Security (HSTS)
Response header telling user agent
to prevent HTTP requests to domain
Solution #4
Don’t let client scripts
read your cookies
Slide 57
Slide 57 text
No content
Slide 58
Slide 58 text
• Injection
• Broken Authentication and Session
Management
• Cross Site Scripting (XSS)
• Cross Site Request Forgery (CSRF)
• Using Components with Known
Vulnerabilities
Slide 59
Slide 59 text
Cross Site Scripting
(XSS)
Slide 60
Slide 60 text
Attacker takes advantage of
the user’s trust in websites
Slide 61
Slide 61 text
Non-persistent
Slide 62
Slide 62 text
Attacker Victim Site
Non-persistent
Slide 63
Slide 63 text
Attacker Victim Site
GET /index.html
Non-persistent
Solution #2
Tell the browser to allow content
from trusted sources only
Slide 79
Slide 79 text
Content Security
Policy (CSP)
Response header telling the browser
the domains it should consider as
valid sources of content
Slide 80
Slide 80 text
No content
Slide 81
Slide 81 text
* Newlines added for readability
Slide 82
Slide 82 text
• Injection
• Broken Authentication and Session
Management
• Cross Site Scripting (XSS)
• Cross Site Request Forgery (CSRF)
• Using Components with Known
Vulnerabilities
Slide 83
Slide 83 text
Cross Site Request
Forgery (CSRF)
Slide 84
Slide 84 text
Attacker takes advantage of
the websites’s trust in users
Slide 85
Slide 85 text
Scenario #1
Exploiting sites that support
changes via GET requests
Slide 86
Slide 86 text
Attacker Victim Bank
Slide 87
Slide 87 text
Attacker Victim Bank
POST /login
Slide 88
Slide 88 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
Slide 89
Slide 89 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
Slide 90
Slide 90 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
Slide 91
Slide 91 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
GET /transfer?to…
Cookie: SessionId=1234
Slide 92
Slide 92 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
HTTP/1.1 200 OK
GET /transfer?to…
Cookie: SessionId=1234
Slide 93
Slide 93 text
Solution
Never allow changes via GET
… only POST
Slide 94
Slide 94 text
Scenario #2
Tricking users into posting
exploited data to sites
Slide 95
Slide 95 text
Attacker Victim Bank
Slide 96
Slide 96 text
Attacker Victim Bank
POST /login
Slide 97
Slide 97 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
Slide 98
Slide 98 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
Slide 99
Slide 99 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
document.bad.submit()
Slide 100
Slide 100 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
document.bad.submit()
POST /transfer
Cookie: SessionId=1234
Slide 101
Slide 101 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
document.bad.submit()
HTTP/1.1 200 OK
POST /transfer
Cookie: SessionId=1234
Slide 102
Slide 102 text
Solution
Synchronizer token pattern
Slide 103
Slide 103 text
No content
Slide 104
Slide 104 text
No content
Slide 105
Slide 105 text
Scenario #3
Bypassing CSRF protections
with click-jacking and HTTP
parameter pollution
Slide 106
Slide 106 text
Attacker Victim Bank
Slide 107
Slide 107 text
Attacker Victim Bank
POST /login
Slide 108
Slide 108 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
Slide 109
Slide 109 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
Slide 110
Slide 110 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
Slide 111
Slide 111 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
GET /transfer?to=…
Cookie: SessionId=1234
Slide 112
Slide 112 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
GET /transfer?to=…
Cookie: SessionId=1234
HTTP/1.1 200 OK
<form method=“post”>
<input type=“text” name=“to”
value=“”>
<input type=“text” name=“dollars”
value=“”>
<input type=“hidden” name=“csrf”
value=“a0d73b12”>
</form>
Slide 113
Slide 113 text
Attacker Victim Bank
POST /login
HTTP/1.1 200 OK
Set-Cookie: SessionId=1234
GET /index.html
HTTP/1.1 200 OK
GET /transfer?to=…
Cookie: SessionId=1234
HTTP/1.1 200 OK
<form method=“post”>
<input type=“text” name=“to”
value=“”>
<input type=“text” name=“dollars”
value=“”>
<input type=“hidden” name=“csrf”
value=“a0d73b12”>
</form>
POST /transfer?to=…
via Clickjacking
Slide 114
Slide 114 text
No content
Slide 115
Slide 115 text
Solution #1
Explicitly set the form action
Slide 116
Slide 116 text
No content
Slide 117
Slide 117 text
Solution #2
Do not use query string
params for user input
Slide 118
Slide 118 text
No content
Slide 119
Slide 119 text
Solution #3
Use X-Frame-Options response header
Slide 120
Slide 120 text
No content
Slide 121
Slide 121 text
No content
Slide 122
Slide 122 text
• Injection
• Broken Authentication and Session
Management
• Cross Site Scripting (XSS)
• Cross Site Request Forgery (CSRF)
• Using Components with Known
Vulnerabilities
Slide 123
Slide 123 text
Using Components with
Known Vulnerabilities
Slide 124
Slide 124 text
Component vulnerabilities
can cause almost any type
of risk imaginable
Slide 125
Slide 125 text
Almost always run with
the full privilege of
the application
Other OWASP top 10
• Insecure Direct Object Reference
• Security Misconfigurations
• Sensitive Data Exposure
• Missing Function Level Access Control
• Unvalidated Redirects and Forwards
Slide 137
Slide 137 text
npm packages
• express-session
• bcrypt-nodejs
• helmet (check out Lusca as well)
• express-validator
• csurf
• nsp and grunt-nap-package
• david