2017-06-13 34 views
1

我正在创建示例Express应用程序来演示Content-Security-Policy(CSP)头并试图使用helmet-csp在单个路径上实现头盔csp

所有头盔-CSP的文档显示它通过app.use(csp({ ... }))作为标准的第三方中间件 - 这增加了CSP标头在我的应用程序的每个路线,但我想自定义个别路线。

示例应用程序

var express = require('express'); 
var http = require('http'); 
var csp = require('helmet-csp'); 
var app = express(); 

app.use(csp({ 
    directives: { 
     frameSrc: ["'none'"] 
    } 
})); 

app.get('/', (request, response) => { 
    response.send('hi, :wave: =]'); 
}); 

app.get('/frameable', (request, response) => { 
    response.send('you can frame me!'); 
}); 

http.createServer(app).listen(80, (err) => { 
    if (err) { 
     return console.log('error', err); 
    } 
}); 

利用上述,路线接收CSP头:

内容安全-政策:帧-src的 '无'

/frameable路线,我想覆盖此CSP标题是:

内容安全-政策:帧的src“自我”

每当我需要/想自定义页眉通过头盔-CSP在每个路由设置,我是否需要手动覆盖它们各自app.get内用线,如:

response.setHeader('Content-Security-Policy', "frame-src 'self'"); 

还是有办法通过头盔-CSP本身做到这一点?

回答

2

定制中间件是能够改变标题,只是use(csp)

app.use(function (req, res, next) { 
    if (req.url == '/frameable') { 
     res.set('Content-Security-Policy', 'frame-src \'self\''); 
    } 
    next(); 
}); 

后添加它你也可以链中间件,因为它是一个返回函数的函数:

app.use(function (req, res, next) { 
    var middleware; 

    if (req.url == '/frameable') { 
     middleware = csp({ 
      directives: { 
       frameSrc: ["'self'"] 
      } 
     }); 
    } else { 
     middleware = csp({ 
      directives: { 
       frameSrc: ["'none'"] 
      } 
     }); 
    } 

    middleware(req, res, next); 
}); 
+0

这是直接修改头 - 这很容易做(见我的问题的结束);我很好奇,如果有可能通过中间件本身在每个路由的基础上做到这一点。在案例中,手动设置一个小型CSP头并不是世界末日,但是当多个头有多个选项并且它们是在多个路径上自定义时 - 使用helmet-csp会更友好'而不是每次手动定义它们。 – newfurniturey

+0

链接中间件允许一些重用 – jasonpenny

+0

哦,这太好了 - 谢谢!知道这是一个中间件类型的东西(而不是绑定到库),这真是太棒了,它将在未来帮助很多。谢谢(^_^) – newfurniturey

2

这行为被内置到Express中。

Express可让您为每个路由指定多个请求处理程序。由于csp回复路由处理,你可以前加入您的路由处理:

app.get('/frameable', csp({ 
    directives: { 
     frameSrc: ["'self'"] 
    } 
}), (request, response) => { 
    response.send('you can frame me!'); 
}); 

如果你喜欢的东西拆了一点,你可以做这样的事情:

var normalCspHandler = csp({ 
    directives: { 
     frameSrc: ["'none'"] 
    } 
}); 

var frameSelfCspHandler = csp({ 
    directives: { 
     frameSrc: ["'self'"] 
    } 
}); 

app.use(normalCspHandler); 

app.get('/frameable', frameSelfCspHandler, (request, response) => { 
    response.send('you can frame me!'); 
}); 

(顺便说一句,我保持头盔,所以让我知道,如果你有任何反馈!)

+0

啊,这真的很好知道 - 非常感谢你的答案=] – newfurniturey