You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.7 KiB

  1. /*!
  2. * Connect - csrf
  3. * Copyright(c) 2011 Sencha Inc.
  4. * MIT Licensed
  5. */
  6. /**
  7. * Module dependencies.
  8. */
  9. var utils = require('../utils');
  10. /**
  11. * Anti CSRF:
  12. *
  13. * CRSF protection middleware.
  14. *
  15. * By default this middleware generates a token named "_csrf"
  16. * which should be added to requests which mutate
  17. * state, within a hidden form field, query-string etc. This
  18. * token is validated against the visitor's `req.session._csrf`
  19. * property.
  20. *
  21. * The default `value` function checks `req.body` generated
  22. * by the `bodyParser()` middleware, `req.query` generated
  23. * by `query()`, and the "X-CSRF-Token" header field.
  24. *
  25. * This middleware requires session support, thus should be added
  26. * somewhere _below_ `session()` and `cookieParser()`.
  27. *
  28. * Options:
  29. *
  30. * - `value` a function accepting the request, returning the token
  31. *
  32. * @param {Object} options
  33. * @api public
  34. */
  35. module.exports = function csrf(options) {
  36. options = options || {};
  37. var value = options.value || defaultValue;
  38. return function(req, res, next){
  39. // generate CSRF token
  40. var token = req.session._csrf || (req.session._csrf = utils.uid(24));
  41. // ignore these methods
  42. if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
  43. // determine value
  44. var val = value(req);
  45. // check
  46. if (val != token) return next(utils.error(403));
  47. next();
  48. }
  49. };
  50. /**
  51. * Default value function, checking the `req.body`
  52. * and `req.query` for the CSRF token.
  53. *
  54. * @param {IncomingMessage} req
  55. * @return {String}
  56. * @api private
  57. */
  58. function defaultValue(req) {
  59. return (req.body && req.body._csrf)
  60. || (req.query && req.query._csrf)
  61. || (req.headers['x-csrf-token']);
  62. }