0.0.11 • Published 7 years ago

jscsrf v0.0.11

Weekly downloads
1
License
Unlicense
Repository
github
Last release
7 years ago

jscsrf

Node package to create and verify time based, request tokens. Prevents CSRF, Spam, & resource abuse by ensuring the traffic originates from the same domain (ie: cookie based, same origin policy) and requires the triggering of javascript events (click, submit, etc) on HTML elements.

Examples:

Basic example

const jscsrf = require('jscsrf');

// Token expires in 2 seconds.
jscsrf.setConfig({
  'expires': 2,
  'cookieName': 'jscsrf',
  'alg': 'aes-256-ctr',
  'salt': 'some random string'
});

console.log('salt:', jscsrf.conf('salt')); // salt: some random string

// Get a new token.
let token = jscsrf.getToken();
console.log('token:', token); // token: da0cb6d623bb948f2d32

// Wait 2.1 seconds.
setTimeout(function(){
  let valid = jscsrf.isValidToken(token);
  console.log('valid:', valid); // valid: FALSE
}, 2100);

Express Example

const express = require('express');
const cookieParser = require('cookie-parser');
const jscsrf = require('jscsrf');

// Token expires in 2 seconds.
jscsrf.setConfig({
  'expires': 2
});

const app = express();
app.use(cookieParser());

/**
 * Route middleware to validate a token.
 * @date   2017-06-30
 * @return mixed
 */
function validateCSRFToken(req, res, next) {

  // Get the token from req.cookes (ie: cookie-parser). 
  let token = req.cookies[jscsrf.conf('cookieName')];

  // Missing or empty
  if (typeof token == 'undefined' || token == '') {
  	return next(new Error('Request token missing.'));
  }

  // Check whether token exists and has not expired. 
  if( ! jscsrf.isValidToken(token)) {
    return next(new Error('Request token failed to match.'));
  }

  // Destroy the cookie. 
  res.clearCookie(jscsrf.conf('cookieName'));
  
  // Continue. 
  next();
}

/**
 * GET /delete_everything
 * Route secured by jscsrf middleware.
 * @date   2017-06-30
 * @return mixed
 */
app.get('/delete_everything', validateCSRFToken, function (req, res) {

  // Try reloading the page after initial success message (=401)
  res.send('Passed!');
});

/**
 * POST /setcsrftoken
 * Ajax request route (ie: onclick, onsubmit) to set a token in a cookie.
 * Jquery example:
 *   // <a class="delete_everything" href="/delete_everything">Delete everything</a>
 *   $('.delete_everything').on('click', function(){
 *     // Post request to example route below. Note: cache=false, async=false.
 *     $.ajax({type: "POST", url: '/setcsrftoken', cache: false, async: false});
 *     // Go to /delete_everything
 *     return true;
 *   }); 
 * @date   2017-06-30
 * @return string
 */
app.post('/setcsrftoken', function (req, res) {

  // Get the current token. Possible to extend to use named tokens.
  let token = jscsrf.getToken();
  
  // See cookie-parser docs for options
  res.cookie(jscsrf.conf('cookieName'), token, {maxAge : null});
  
  // For debugging.
  res.send({'token': token});
});

app.listen(8080);

Methods:

setConfig(options)

  • options an object passed to over-write default options; expires (default: 3 seconds), alg (default: aes-256-ctr), salt

conf(option)

  • option Optional. If specified, returns the config option value. If empty, returns all config options.

getToken()

  • returns a new time sensitive token

isValidToken(token)

  • token Optional. If unspecified, will use the most recently generated token.
  • returns true/false

Notes:

This very basic method of time based, request tokenization has been used in production sites for 5+ years to prevent common annoyances like bot registrations (transparently replacing craptchas), prevent resource abuse (ie: scraping data from ajax get urls, etc.), and provide CSRF protection on links, such as user log out and deleting sensitive data via get requests.

Common CSRF mechanisms add a token to a form input which can be scraped and passed along with input, and in some cases, defeat its intended purpose. Common methods are also ill-equipped to deal with get requests (links).

License:

Unlicense

0.0.11

7 years ago

0.0.10

7 years ago

0.0.9

7 years ago

0.0.8

7 years ago

0.0.7

7 years ago

0.0.6

7 years ago

0.0.5

7 years ago

0.0.4

7 years ago

0.0.2

7 years ago

0.0.3

7 years ago

0.0.1

7 years ago