signed-token-csrf
v2.1.1
Published
CSRF connect middleware using signed tokens
Readme
signed-token-csrf
CSRF connect middlewares using signed tokens
API
new Csrf(secret, [opts])
Parameters
| parameter | type | description |
| ---------------------- | ------------------- | ---------------------------------------------------------------------------------------------------- |
| secret | string | a server side secret |
| [opts] | Object | optional: options |
| [opts.name=csrf] | string | optional: header & cookie name of token |
| [opts.cookie] | Object | optional: cookie options - defaults to {path: '/', httpOnly: true, secure: true, sameSite: true} |
| [opts.token] | Object | optional: signedToken options - defaults to {digest: 'sha256', commonlen: 24, tokenlen: 48} |
| [opts.ignoreMethods] | Array<string> | optional: ignore methods ['HEAD', 'OPTIONS'] |
| [opts.host] | string | optional: hostname of service to check against |
create
Connect middleware (req, res, next) => {}
Creates method req.csrfToken() to get CSRF token as well as the secret for
signing in req.session.csrf if available or sets a csrf cookie.
Name of session key and cookie name can be changed via opts.name.
Default name is csrf.
NOTE: If used together with verifyXhr() only set CSRF Cookie on successful login!
verify
Connect middleware (req, res, next) => {}
Obtains a token from a request using either req.body.csrf, req.query.csrf or req.headers['x-csrf-token'] and verifies it with the secret from req.session.csrf if available or from the csrf cookie.
body-parser is required to obtain the token from the request body.
Name of session key and cookie name can be changed via opts.name
verifyXhr
Connect middleware (req, res, next) => {}
Verifies the cookie only; For token based xhr requests. See Your API-Centric Web App Is Probably Not Safe Against XSS and CSRF.
NOTE: Only set CSRF Cookie with create() on successful login!
csrf
Connect middleware (req, res, next) => {} which chains create and verify.
Example
Forms
See ./example/app.js. Run with node exampe/app.js and open http://localhost:3000 in browser.
const Csrf = require('signed-token-csrf')
const bodyParser = require('body-parser')
const session = require('express-session')
const app = require('express')()
const csrf = new Csrf('csrfSecret', { cookie: { secure: false } })
// works with or without a session
app.use(
session({ secret: 'sessionSecret', resave: false, saveUninitialized: true })
)
app.use(csrf.checkOrigin)
app.get(
'/form',
csrf.create, // adds CSRF protection
(req, res) => {
// render a form
res.end(`
<form action="/form" method="POST">
<input type="hidden" name="csrf" value="${req.csrfToken()}" >
<input type="text" name="text" value="some text"><br>
<button>Submit</button>
</form>
`)
}
)
app.post(
'/form', // render the submitted values or throw
bodyParser.urlencoded({ extended: false }),
csrf.verify,
(req, res) => {
res.end(`
<h2>Parameters</h2>
<pre>
text: ${req.body.text}
csrf: ${req.body.csrf}
</pre>
`)
}
)
app.use('/', (req, res) => {
res.redirect('/form')
})
app.listen(3000)XHR
Run example and browse to http://localhost:3000/xhr
app.use(csrf.checkOrigin)
app.get(
'/api/login',
(req, res, next) => {
// prevent creating a new csrf cookie if authenticated
const err =
req.headers.authorization && httpError(403, 'already authenticated')
next(err)
},
csrf.create,
(req, res) => res.json({ token: 'your-auth-token' })
)
app.use('/api', csrf.verifyXhr, (req, res) => res.json({}))Installation
Requires nodejs.
$ npm install signed-token-csrfTests
$ npm testLicense
Unlicense https://unlicense.org
