@ basinative/ 中间软件
带有 CORS 、 速率限制、 CSRF 和框架适配器的服务器不可知中件管道
部分 基础 生态系统——一个基于信号的网络运行时间超过本土的HTML.
安装
npm install @basenative/middleware
快速启动
import { createPipeline, cors, rateLimit, csrf, logger } from '@basenative/middleware';
import { toExpressMiddleware } from '@basenative/middleware';
const pipeline = createPipeline()
.use(cors({ origins: ['https://example.com'] }))
.use(rateLimit({ max: 100, windowMs: 60_000 }))
.use(csrf())
.use(logger());
// Use with Express
const app = express();
app.use(toExpressMiddleware(pipeline));
API 密码
管道
createPipeline()——创建中件管. 以 :.use(middleware)- 添加中间软件函数(ctx, next) => Promise<void>。 。 。 ..run(ctx)——用上下文对象执行管道..toHandler()——以单一处理器功能返回管道..stack——只读数组已注册中件.
compose(...middlewares)——将多件中件功能组合为一.
背景形状
每个中间件都收到上下文对象:
{ request: { method, url, headers, body }, response: { status, headers, body }, state: {} }
内置中件
cors(options?)设置 CORS 信头 。 选项 :origins, (中文(简体) ),methods, (中文(简体) ),headers, (中文(简体) ),credentials, (中文(简体) ),maxAge。 。 。 .rateLimit(options?)——流程中速率限制器. 选项 :max, (中文(简体) ),windowMs, (中文(简体) ),keyFn, (中文(简体) ),message。 。 。 .csrf(options?)——双投饼干CSRF保护. 选项 :cookieName, (中文(简体) ),headerName。 。 。 .logger(options?)- 请求/答复记录中间软件。 选项 :format, (中文(简体) ),skip。 。 。 .securityHeaders(options?)为工人式操作人员设置的响应加固头(CSP、HSTS、许可政策、COOP/COEP/CORP、缓存姿态)。 见下文.
安全信头
import { securityHeaders } from '@basenative/middleware/security-headers';
一个硬化的基线,共享。 产品供应他们真正的产品——什么
他们谈话的宿主,他们是否想要被索引, 答复可能要多久
缓存 —— 软件包提供其他一切, 所以添加一个 CDN 到 script-src
永远不能无声地下降 frame-ancestors 'none'。 。 。 .
采用新产品
import { securityHeaders } from '@basenative/middleware/security-headers';
// Configure once, at module scope. Options are validated eagerly: a bad
// directive throws at boot, not on the first request that needs it.
const harden = securityHeaders({
csp: {
// Merged INTO the baseline. 'self' stays; this adds to it.
'script-src': ['https://cdn.example.com'],
'connect-src': ['https://api.example.com'],
},
hsts: { preload: true },
cache: ({ contentType }) =>
contentType.startsWith('application/json') ? 'private, no-store' : null,
});
export default {
async fetch(request, env, ctx) {
const response = await handle(request, env, ctx);
return harden(response, { request });
},
};
这就是整个收养过程. harden 接受任意 Response - 包括
不可改变的一 env.ASSETS.fetch() 返回,并用
状态、状态文本、身体和每个不相关的标题都完好无损.
你得到什么而不问
| 页眉 | 默认 | 为什么这个值 |
|---|---|---|
Content-Security-Policy | default-src 'self', (中文(简体) ), script-src 'self', (中文(简体) ), style-src 'self', (中文(简体) ), style-src-attr 'none', (中文(简体) ), img-src 'self' data:, (中文(简体) ), font-src 'self', (中文(简体) ), connect-src 'self', (中文(简体) ), object-src 'none', (中文(简体) ), frame-ancestors 'none', (中文(简体) ), base-uri 'self', (中文(简体) ), form-action 'self', (中文(简体) ), upgrade-insecure-requests | 默认拒绝; 每种津贴都是名下要求的产品 |
Strict-Transport-Security | max-age=31536000; includeSubDomains | 一岁. preload 实值 选入 ——这是向浏览器复仇者列表的呈文,它缓慢而痛苦地离开 |
X-Frame-Options | DENY | 重复使用 frame-ancestors仍然通过扫描仪进行分级,并被更老的引擎所尊崇 |
X-Content-Type-Options | nosniff | 不相可观. 没有反应,这是错的 |
Referrer-Policy | strict-origin-when-cross-origin | |
Permissions-Policy | camera=(), microphone=(), geolocation=(), payment=(), usb=() | 拒绝高风险特性; 选择返回每个特性 |
Cross-Origin-Opener-Policy | same-origin | |
Cross-Origin-Resource-Policy | 删除 | same-origin 打破任何为兄弟子域提供资产的产品。 故意设定( S)corp: 'same-site'而不是在断电中发现它 |
Cross-Origin-Embedder-Policy | 删除 | 要求每个跨源子资源选择使用;在您审计后启用 |
X-Robots-Tag | 删除 | noindex: true 在一个内部工具上; 在营销网站上错了, 所以从不默认 |
合并语义——值得读出两次的部分
CSP指令合并. 呼叫源列表与基线的,
被破损,基线第一. csp: { 'connect-src': ['https://api.example.com'] }
产量 connect-src 'self' https://api.example.com基准的指令
未按给定添加.
权限政策特性替换 . 以许可联合否定是
毫无意义,所以 permissions: { camera: ['self'] } 选择返回到
并留下其他的默认否认.
null 移除. 在任何地图上, null 放下那个入口 这是唯一的办法
失去基线保护,必须写明:
securityHeaders({
csp: { 'upgrade-insecure-requests': null }, // local dev over plain http
permissions: { usb: null }, // do not send the feature at all
});
csp: false 完全没有CSP,所以一个从未有过的产品可以被收养
今天给其他七个信头的软件包 稍后再写它的政策 同样的
hsts: false, (中文(简体) ), coop: false, (中文(简体) ), frameOptions: false。 。 。 .
无
nonce: true 生成一个新碱基64,每个响应一次,并附加到
script-src (可以通过 nonceDirectives) (中文(简体) ). 注射时使用
返回后的标记中的脚本—— Cloudflare Web 分析信标, a
Bot Fight Mode 片段——所以这些标签运行时没有 'unsafe-inline'。 。 。 .
当身体本身携带非ce时,首先生成并接回:
import { securityHeaders, createNonce } from '@basenative/middleware/security-headers';
const harden = securityHeaders({ nonce: true });
const nonce = createNonce();
const html = renderPage({ nonce }); // <script nonce="...">
return harden(new Response(html, { headers }), { nonce });
不通过非曲直 nonce: true 掷出静静地放下它会挡住
在本地没有失败的情况下, 内置的脚本 .
按要求执行的政策
当政策因要求而异时——每租户相机允许列表,a 只预览的 CORP —— 构建记录而不是装饰一个响应 :
import { buildSecurityHeaders } from '@basenative/middleware/security-headers';
const headers = buildSecurityHeaders({
permissions: { camera: tenant.allowsScanner ? ['self'] : [] },
corp: env.ENVIRONMENT === 'production' ? 'same-site' : 'cross-origin',
});
return new Response(html, { headers: { ...headers, 'Content-Type': 'text/html' } });
buildSecurityHeaders 从不包含 Cache-Control; 来源于
响应,因此 securityHeaders() 应用它.
缓存姿态
cache 调用 { contentType, status, request, response }返回 a
Cache-Control 要设置的值,或 null编号 :undefined 离开任何
处理器已选择 :
cache: ({ contentType, status }) => {
if (status !== 200) return null;
if (contentType.startsWith('text/html')) return 'public, max-age=300';
return null;
},
管道内
securityHeadersMiddleware(options) 与 a 相同的标题 createPipeline()
阶段。 它首先运行在下游的中间器皿 cache 查看内容类型
处理器选择,然后在 ctx.state.cspNonce。 。 。 .
它会向你扔出错误
每一个都是一种失败 它实际上已经运送到某个地方, 现在抓住 建筑业:
hsts: { preload: true, includeSubDomains: false }——预装入列表拒绝 因此,该指令声称它不具备资格.permissions: { bluetooth: [] }——没有注册特征. 浏览器忽略它 并在每个响应上记录一个控制台警告.- 一个未知的选项密钥——一个打字会默地掉出一个头,所以被拒绝.
- a CSP来源,含有:
;它将注入第二个指令. - a 不含CSP,或针对被删除的指令.
API 密码
securityHeaders(options?)→(response, context?) => ResponsebuildSecurityHeaders(options?, context?)→Record<string, string>securityHeadersMiddleware(options?)* 管道MiddlewareFncreateNonce(byteLength = 16)— 基数64字符串DEFAULT_CSP, (中文(简体) ),DEFAULT_PERMISSIONS- 被冻结,供检查
context 实值 { request?, nonce? }。 。 。 . request 传递到 cache 已经
从来没有检查过头部建筑.
框架适应器
toExpressMiddleware(pipeline)——包接管道,用作快递中件.toHonoMiddleware(pipeline)包装一条管道,用作Hono中件.toFastifyPlugin(pipeline)——将管道包成快件插件.toCloudflareHandler(pipeline)将管道围成云浮工人fetch处理者.
许可证
阿帕奇 - 2.0