signed-token-csrf v2.0.0
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