• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Slides/Notes from my talk on Security Best Practices with Node.js https://www.youtube.com/watch?v=qBLgykeA3Mo

To view this as a slide deck:

npm install -g reveal-md

npm start


Security

### with

[email protected]

CJ on Denver Devs


Agenda

  • whoami
  • Why security?
  • Security with Node.JS/Express

whoami


CJ

Lead Instructor, Sr. Full Stack Developer

at


Why security?


Show of hands:

Who here develops web applications?


Show of hands:

Who here is a security engineer?


If you are a web developer you probably don't think of yourself as a security engineer.

"Our clients don't pay us for security; they want it pretty, they want it feature-complete, and most importantly they want it done yesterday."

A Gentle Introduction to Application Security


Fact:

The second your code is deployed in production, your code is the front line of defense for that entire system and quite possibly the entire network.


Logically, that means the software you produce must be made reasonably secure.


Application Security is Every Developer's Responsibility

You don't have to be an expert.

Anything you develop with security in mind will still move the needle in your organization as well as any clients you work with.


The topics discussed in this talk are heavily influenced by the [Web Application Security Testing Cheat Sheet](https://www.owasp.org/index.php/Web_Application_Security_Testing_Cheat_Sheet) maintained by [OWASP - Open Web Application Security Project](https://www.owasp.org/index.php/Main_Page) and the [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/) by RisingStack.


Security with Node.JS/Express

  • Mitigate common attacks by setting security related headers
  • Protect against brute force authentication attacks
  • Manage sessions using cookie best practices
  • Mitigate CSRF attacks
  • Validate Data to prevent XSS, SQL Injection and Command Injection
  • Ensure secure transmission by testing SSL and HSTS
  • Check NPM dependencies for known vulnerabilities

Mitigate common attacks by setting security related headers


Headers

Setting headers from the server is easy and often doesn't require any code changes. Once set, they can restrict modern browsers from running into easily preventable vulnerabilities.

OWASP Secure Headers Project


Helmet

Helmet helps you secure your Express apps by setting various HTTP headers. It's not a silver bullet, but it can help!

Helmet is a collection of 10 smaller middleware functions that set HTTP headers:


Helmet Usage

npm install -S helmet
const express = require('express');  
const helmet = require('helmet');

const app = express();

app.use(helmet());

Running app.use(helmet()) will include 7 of the 10, leaving out contentSecurityPolicy, hpkp, and noCache. You can also use each module individually.


Protect against brute force authentication attacks


Brute Force

In cryptography, a brute-force attack consists of an attacker trying many passwords or passphrases with the hope of eventually guessing correctly. The attacker systematically checks all possible passwords and passphrases until the correct one is found.

via Wikipedia

https://github.com/vanhauser-thc/thc-hydra


Rate Limiting

Limiting the number of requests a user can make can protect your application from brute force attacks.


express-bouncer

A simple and standalone middleware for express routes which attempts to mitigate brute-force attacks. It works by increasing the delay with each failed request using a Fibonacci formula. Requests are tracking via IP address and can be white-listed or reset on demand.

// Creates a new instance of our bouncer (args optional)
var bouncer = require ("express-bouncer")(500, 900000);

// Add white-listed addresses (optional)
bouncer.whitelist.push ("127.0.0.1");

// In case we want to supply our own error (optional)
bouncer.blocked = function (req, res, next, remaining) {
    res.send (429, "Too many requests have been made, " +
        "please wait " + remaining / 1000 + " seconds");
};

// Route we wish to protect with bouncer middleware
app.post ("/login", bouncer.block, function (req, res) {
    if (LoginFailed) {
        // Login failed
    } else {
        bouncer.reset (req);
        // Login succeeded
    }
});

// Clear all logged addresses
// (Usually never really used)
bouncer.addresses = { };

ratelimiter

ratelimiter is an abstract rate limiter for Node.js backed by redis.

npm install -S ratelimiter

Options

  • id - the identifier to limit against (typically a user id)
  • db - redis connection instance
  • max - max requests within duration [2500]
  • duration - of limit in milliseconds [3600000]

ratelimiter usage

Can be used as a middleware to protect ALL routes.

app.use((req, res, next) => {
  var id = req.user._id;
  var limit = new Limiter({ id: id, db: db });
  limit.get(function(err, limit){
    if (err) return next(err);

    res.set('X-RateLimit-Limit', limit.total);
    res.set('X-RateLimit-Remaining', limit.remaining - 1);
    res.set('X-RateLimit-Reset', limit.reset);

    // all good
    debug('remaining %s/%s %s', limit.remaining - 1, limit.total, id);
    if (limit.remaining) return next();

    // not good
    var delta = (limit.reset * 1000) - Date.now() | 0;
    var after = limit.reset - (Date.now() / 1000) | 0;
    res.set('Retry-After', after);
    res.send(429, 'Rate limit exceeded, retry in ' + ms(delta, { long: true }));
  });
});

Manage sessions using cookie best practices


Cookie Flags

There are several attributes that can be set on a cookie:

  • secure - this attribute tells the browser to only send the cookie if the request is being sent over HTTPS.
  • HttpOnly - this attribute is used to help prevent attacks such as cross-site scripting, since it does not allow the cookie to be accessed via JavaScript.

Cookie Scope

  • domain - this attribute is used to compare against the domain of the server in which the URL is being requested. If the domain matches or if it is a sub-domain, then the path attribute will be checked next.
  • path - in addition to the domain, the URL path that the cookie is valid for can be specified. If the domain and path match, then the cookie will be sent in the request.
  • expires - this attribute is used to set persistent cookies, since the cookie does not expire until the set date is exceeded

cookies in Express

In a newly generated express app, all options are off by default

app.use(cookieParser())

Set some sensible defaults:

app.use(cookieParser(process.env.COOKIE_SECRET, {
  secure: true,
  httpOnly: true,
  domain: process.env.DOMAIN,
  expires:
}));

cookie-parser on npm

cookie on npm


Mitigate CSRF attacks


CSRF

Cross-Site Request Forgery is an attack that forces a user to execute unwanted actions on a web application in which they're currently logged in. These attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request.

via OWASP

NodeGoat - an environment to learn how OWASP Top 10 security risks apply to Node.js

NodeGoat CSRF demo


csurf

Node.js CSRF protection middleware.

npm install -S csurf


csurf usage

var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')

var app = express()
app.use(cookieParser())

var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })

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 is being processed')
})

csurf usage

<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="{{csrfToken}}">

  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>

Validate Data to prevent XSS, SQL Injection and Command Injection


Always filter and sanitize user input.


Input comes from many places

  • Query parameters
  • URL path
  • PUT/POST parameters
  • Cookies
  • Headers
  • File uploads
  • Emails
  • Form fields
  • etc.

XSS

There are 2 types of XSS attacks:

Reflected Cross site scripting

The attacker injects executable JavaScript code into the HTML response with specially crafted links.

http://example.com/?user=<script>alert('pwned')</script>

Stored Cross site scripting

The application stores user input which is not correctly filtered. It runs within the user’s browser under the privileges of the web application.

NodeGoat Stored XSS Demo


SQL Injection

Injection of a partial or complete SQL query via user input. It can read sensitive information or be destructive as well.

select title, author from books where id=$id  

$id is coming from the user - what if the user enters 2 or 1=1? The query becomes the following:

select title, author from books where id=2 or 1=1

The easiest way to defend against these kind of attacks is to use parameterized queries or prepared statements.

If you are using PostgreSQL from Node.js then you probably using the node-postgres module. To create a parameterized query:

var q = 'SELECT name FROM books WHERE id = $1';  
client.query(q, ['3'], function(err, result) {});  

SQL Injection Testing

http://sqlmap.org/


Command Injection

A technique used by an attacker to run OS commands on the remote web server.

For example:

https://example.com/downloads?file=user1.txt

https://example.com/downloads?file=%3Bcat%20/etc/passwd

In this example %3B becomes the semicolon, so multiple OS commands can be run.


A few take aways for data validation:


Always filter and sanitize user input.


Always filter and sanitize user input.


Always filter and sanitize user input.


Always filter and sanitize user input.


Ensure secure transmission by testing SSL and HSTS


Secure Transmission

SSL Version, Algorithms, Key length

As HTTP is a clear-text protocol it must be secured via SSL/TLS tunnel, known as HTTPS. Nowadays high grade ciphers are normally used, misconfiguration in the server can be used to force the use of a weak cipher - or at worst no encryption.

You have to test:

  • ciphers, keys and renegotiation is properly configured
  • certificate validity

Checking for Certificate information

nmap

nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995 www.example.com  

Testing SSL/TLS vulnerabilities with sslyze

sslyze

./sslyze.py --regular example.com:443

HSTS

The Strict-Transport-Security header enforces secure (HTTP over SSL/TLS) connections to the server. Take the following example from Twitter:

strict-transport-security:max-age=631138519

Here the max-age defines the number of seconds that the browser should automatically convert all HTTP requests to HTTPS.

Testing for it is pretty straightforward:

curl -s -D- https://twitter.com/ | grep -i Strict


Check NPM dependencies for known vulnerabilities


Any dildo can publish something to npm.

-Kyle Coberly


NPM

With great power comes great responsibility - NPM has lots of packages what you can use instantly, but that comes with a cost: you should check what you are requiring to your applications. They may contain security issues that are critical.


Node Security Platform

Check your npm dependencies for known vulnerabilities.

npm install -g nsp
nsp check # audit package.json

Snyk

Snyk is similar to the Node Security Platform, but its aim is to provide a tool that can not just detect, but fix security related issues in your codebase.

npm install -g snyk
snyk test # audit node_modules directory

Review


Mitigate common attacks by setting security related headers


Protect against brute force authentication attacks


Manage sessions using cookie best practices


Mitigate CSRF attacks


Validate Data to prevent XSS, SQL Injection and Command Injection


Ensure secure transmission by testing SSL and HSTS


Check NPM dependencies for known vulnerabilities


Final Thoughts


Knowing is half the battle!


Application Security is Every Developer's Responsibility

This doesn't mean you have to be an expert. You can take one step forward on the path towards expertise and stop, and it will still move the needle in your organization as well as any clients you work with.


Security is a mindset, checklist/Top 10 is a place to start, but don't stop there!


Resources


is Hiring!

gjobs.link/ByTeam


Thank you!

Security

##### with

[email protected]

CJ on Denver Devs

More Repositories

1

express-api-starter

A basic starter for an express.js API
JavaScript
438
star
2

express-api-starter-ts

A basic starter for an express.js API with Typescript
TypeScript
379
star
3

hono-open-api-starter

A starter template for building fully documented type-safe JSON APIs with Hono and Open API
TypeScript
220
star
4

bytedash

TypeScript
183
star
5

dotfiles

Shell
144
star
6

next-start

A basic Next.js starter.
TypeScript
140
star
7

create-express-api

A CLI to automatically clone the Express API Starter
JavaScript
118
star
8

vscode-settings

All of the settings / extensions I use in VS Code.
108
star
9

openfreemap-examples

Examples for react, vue, svelte and vanilla js using OpenFreeMap.org tiles with MapLibre GL JS libraries.
TypeScript
104
star
10

stoker

Utilities for hono and @hono/zod-openapi
TypeScript
85
star
11

Full-Stack-JavaScript-CRUD

This is the code to accompany my videos on youtube where I build a full stack application with JavaScript.
49
star
12

CRUD-stickers-server

JavaScript
46
star
13

materialize-themes

Pre-generated materialize css color combinations. https://w3cj.github.io/materialize-themes/
HTML
46
star
14

vue-in-depth

A Recap of the Vue In Depth workshop by Evan You from VueConf New Orleans 2018
HTML
36
star
15

vanilla-js-mvc

A small JS component framework built LIVE from scratch during the Frontend Framework Face Off.
JavaScript
32
star
16

users-stickers-CRUD

JavaScript
25
star
17

front-end-face-off-vanilla-js

JavaScript
23
star
18

intro-vuetify-crud

This is the code for my live stream on intro to Vuetify.js
JavaScript
17
star
19

deno_grant

Minimalistic pre-configured OAuth 2.0 client for Deno. Inspired by grant.
TypeScript
17
star
20

prisma-erd-generator-markdown

TypeScript
16
star
21

intro-full-stack

CSS
16
star
22

vue-vs-react

TypeScript
16
star
23

product-CRUD-server

JavaScript
13
star
24

use-x

Practice implementing custom react hooks with full test suites and examples.
TypeScript
12
star
25

hono-node-deployment-examples

Examples for deploying hono to various platforms
TypeScript
10
star
26

solid-vs-react

This repo has a few apps built with react and solid for comparison.
TypeScript
9
star
27

my-full-stack-app

JavaScript
8
star
28

null.computer

A web log by me. http://null.computer
JavaScript
8
star
29

wikipedia-clean-dark-green

A clean dark theme with green accents based on the "Wikipedia Clean Dark" theme.
CSS
8
star
30

c.js

A simple JavaScript MVC framework that no-one should use.
JavaScript
6
star
31

vue-workshop

Vue
6
star
32

imdb-scraper-server

JavaScript
6
star
33

react-barkwire

JavaScript
6
star
34

intro-feathers

JavaScript
6
star
35

pokemon-cacher

Cache pokemon from the Poke API
TypeScript
6
star
36

vue-fn-api

Vue
5
star
37

basic-vue-vuetify-starter

A basic Vue.js app with Vuetify.js and no webpack required. Supports .vue files
Vue
5
star
38

NetflixSearch

Search netflix. Uses YQL to parse instantwatcher.com results. Requires jQuery.
JavaScript
4
star
39

vue.js-appstravaganza

JavaScript
4
star
40

desktop-webcam-preview

JavaScript
4
star
41

OverVue

JavaScript
3
star
42

vue-composition-api-feathersjs

JavaScript
3
star
43

react-animated-climacons

JavaScript
3
star
44

git-fly

A command line tool to temporarily clone, run and open git repos on the fly.
JavaScript
3
star
45

ChickTech-Robotics

JavaScript
3
star
46

ez-fetch

JavaScript
3
star
47

auth-github-org

Add github login to your express app restricted to specific github organization(s). Powered by passport and passport-github2.
JavaScript
3
star
48

api-keyper

A node.js API proxy that keeps your API keys out of client side code.
JavaScript
3
star
49

server-side-requests

The code for my video here: https://www.youtube.com/watch?v=UkNR_6oZ5XM
JavaScript
3
star
50

craigslist-scraper

A craigslist scraper built by myself and a newb live on my channel.
JavaScript
3
star
51

nightwatch-starter

A simple starter project for nightwatch end to end tests. No dependency on Java or Selenium.
JavaScript
3
star
52

api-baby-maker

Mix and match APIs to create beautiful API babies.
JavaScript
3
star
53

backpack-debuggers

An API that serves up monsters from the Backpack Debuggers game.
TypeScript
3
star
54

banana

HTML
2
star
55

full-stack-workflow-client

JavaScript
2
star
56

JSFunctions

JavaScript Basic Functions
CSS
2
star
57

avocado.fun

https://avocado.fun
CSS
2
star
58

express-zero-config

JavaScript
2
star
59

prototyping-vue-overnight

Code and Notes from our Denver Startup Week Talk
2
star
60

basic-jquery-SPA

HTML
2
star
61

es-explained

ECMAScript, TC39 and The Future of JavaScript. Slides/notes/links from my meetup talk at DenverScript https://www.meetup.com/DenverScript/events/233376991/
JavaScript
2
star
62

github-pull

JavaScript
2
star
63

pair-react-practice

JavaScript
1
star
64

meetup-talks

Abstracts/Synopsis and links to slides/videos of Meetup Talks by CJ
1
star
65

next-js-example

TypeScript
1
star
66

testing-with-mocha-chai

JavaScript
1
star
67

express-pdf-generator

HTML
1
star
68

giphy-swr-scraper

JavaScript
1
star
69

local-storage-demo

HTML
1
star
70

basic-vue-starter

Vue
1
star
71

tdd-game

JavaScript
1
star
72

poll.coding.garden

JavaScript
1
star
73

async-await

JavaScript
1
star
74

w3cj

1
star
75

product-CRUD-client

JavaScript
1
star
76

vue-rockets-example

JavaScript
1
star
77

s3-image-upload

JavaScript
1
star
78

imdb-scraper-client

JavaScript
1
star
79

vue-share-data

A basic example of sharing data between vue components.
JavaScript
1
star
80

fortune-node

A CLI wrapper for adage, a js implementation of fortune (unix).
JavaScript
1
star
81

express-hapi

Add a route method to an express app or router to create routes in a similar fashion to hapi.js
JavaScript
1
star
82

dcc-2017-api

JavaScript
1
star
83

hound-config

Creates a config for use with Hound - https://github.com/etsy/hound, by finding all repos for a given organization.
JavaScript
1
star
84

share-data-react

JavaScript
1
star
85

rainbow-topics-issue-viewer

A sorted filterable view of the issues on the 🌈 Coding Train 🚂 Rainbow Topics repo.
Vue
1
star
86

notlocalhost.net

HTML
1
star
87

t3-example

TypeScript
1
star