Helmet giúp bảo mật các ứng dụng Express bằng cách đặt các tiêu đề phản hồi HTTP.
Helmet.js là một thư viện JavaScript mã nguồn mở giúp bạn bảo mật ứng dụng Node.js của mình bằng cách thiết lập một số tiêu đề HTTP. Nó hoạt động như một middleware cho Express và các công nghệ tương tự, tự động thêm hoặc loại bỏ các tiêu đề HTTP để tuân theo các tiêu chuẩn bảo mật web.
Bắt đầu
Dưới đây là một ứng dụng Express mẫu sử dụng Helmet:
import express from "express";
import helmet from "helmet";
const app = express();
// Use Helmet!
app.use(helmet());
app.get("/", (req, res) => {
res.send("Hello world!");
});
app.listen(8000);
Bạn cũng có thể require("helmet")
nếu bạn muốn.
Theo mặc định, Helmet thiết lập các tiêu đề sau:
Content-Security-Policy
: Một danh sách cho phép mạnh mẽ về những gì có thể xảy ra trên trang của bạn, giảm thiểu nhiều cuộc tấn côngCross-Origin-Opener-Policy
: Giúp cách ly quy trình của trang bạnCross-Origin-Resource-Policy
: Chặn người khác tải tài nguyên của bạn từ nguồn gốc khácOrigin-Agent-Cluster
: Thay đổi cách cách ly quy trình để dựa trên nguồn gốcReferrer-Policy
: Kiểm soát tiêu đề RefererStrict-Transport-Security
: Báo cho trình duyệt ưu tiên HTTPSX-Content-Type-Options
: Tránh MIME sniffingX-DNS-Prefetch-Control
: Kiểm soát tiền kích hoạt DNSX-Download-Options
: Bắt tải xuống được lưu (Chỉ dành cho Internet Explorer)X-Frame-Options
: Tiêu đề kế thừa giảm thiểu các cuộc tấn công clickjackingX-Permitted-Cross-Domain-Policies
: Kiểm soát hành vi xuyên qua miền cho các sản phẩm Adobe, chẳng hạn như AcrobatX-Powered-By
: Thông tin về máy chủ web. Được gỡ bỏ vì có thể được sử dụng trong các cuộc tấn công đơn giảnX-XSS-Protection
: Tiêu đề kế thừa giảm thiểu XSS attacks, nhưng làm tình hình xấu đi, vì vậy Helmet tắt nó
Mỗi tiêu đề có thể được cấu hình. Ví dụ, dưới đây là cách bạn cấu hình tiêu đề Content-Security-Policy
:
// This sets custom options for the
// Content-Security-Policy header.
app.use(
helmet({
contentSecurityPolicy: {
directives: {
"script-src": ["'self'", "example.com"],
},
},
})
);
Các tiêu đề cũng có thể bị vô hiệu hóa. Ví dụ, dưới đây là cách bạn vô hiệu hóa các tiêu đề Content-Security-Policy
và X-Download-Options
:
// This disables the Content-Security-Policy
// and X-Download-Options headers.
app.use(
helmet({
contentSecurityPolicy: false,
xDownloadOptions: false,
})
);
Tham Khảo
Content-Security-Policy
Mặc định:
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Tiêu đề Content-Security-Policy
giảm thiểu nhiều cuộc tấn công, như cross-site scripting. Xem MDN’s introductory article on Content Security Policy.
Tiêu đề này mạnh mẽ nhưng có thể cần một số cấu hình.
Để cấu hình tiêu đề này, truyền một đối tượng với một đối tượng directives
lồng nhau. Mỗi khóa là tên chỉ thị bằng chữ thường gạch dưới (như defaultSrc
) hoặc gạch ngang (như default-src
). Mỗi giá trị là một mảng (hoặc tập hợp khác) các chuỗi hoặc hàm cho chỉ thị đó. Nếu một hàm xuất hiện trong mảng, nó sẽ được gọi với các đối tượng yêu cầu và phản hồi.
// Sets all of the defaults, but overrides `script-src`
// and disables the default `style-src`.
app.use(
helmet({
contentSecurityPolicy: {
directives: {
"script-src": ["'self'", "example.com"],
"style-src": null,
},
},
})
);
// Sets the `script-src` directive to
// "'self' 'nonce-e33ccde670f149c1789b1e1e113b0916'"
// (or similar)
app.use((req, res, next) => {
res.locals.cspNonce = crypto.randomBytes(16).toString("hex");
next();
});
app.use(
helmet({
contentSecurityPolicy: {
directives: {
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
},
},
})
);
Những chỉ thị này được kết hợp thành một chính sách mặc định, bạn có thể vô hiệu hóa bằng cách đặt useDefaults
thành false
.
// Sets "Content-Security-Policy: default-src 'self';
// script-src 'self' example.com;object-src 'none';
// upgrade-insecure-requests"
app.use(
helmet({
contentSecurityPolicy: {
useDefaults: false,
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "example.com"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
},
})
);
Bạn có thể lấy đối tượng chỉ thị mặc định với helmet.contentSecurityPolicy.getDefaultDirectives()
. Đây là chính sách mặc định (khoảng trắng được thêm vào để dễ đọc):
default-src 'self';
base-uri 'self';
font-src 'self' https: data:;
form-action 'self';
frame-ancestors 'self';
img-src 'self' data:;
object-src 'none';
script-src 'self';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline';
upgrade-insecure-requests
Chỉ thị default-src
có thể bị vô hiệu hóa một cách rõ ràng bằng cách đặt giá trị của nó thành helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc
, nhưng điều này không được khuyến khích.
Bạn có thể đặt Content-Security-Policy-Report-Only thay thế.
// Sets the Content-Security-Policy-Report-Only header
app.use(
helmet({
contentSecurityPolicy: {
directives: {
/* ... */
},
reportOnly: true,
},
})
);
Helmet thực hiện rất ít kiểm tra hợp lệ trên CSP của bạn. Bạn nên dựa vào các công cụ kiểm tra CSP như CSP Evaluator thay vào đó.
Để vô hiệu hóa tiêu đề Content-Security-Policy
:
app.use(
helmet({
contentSecurityPolicy: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.contentSecurityPolicy())
.
Cross-Origin-Embedder-Policy
Tiêu đề này không được thiết lập mặc định.
Tiêu đề Cross-Origin-Embedder-Policy
giúp kiểm soát các tài nguyên có thể được tải qua nguồn gốc khác. Xem MDN’s article on this header để biết thêm chi tiết.
// Helmet does not set Cross-Origin-Embedder-Policy
// by default.
app.use(helmet());
// Sets "Cross-Origin-Embedder-Policy: require-corp"
app.use(helmet({ crossOriginEmbedderPolicy: true }));
// Sets "Cross-Origin-Embedder-Policy: credentialless"
app.use(helmet({ crossOriginEmbedderPolicy: { policy: "credentialless" } }));
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.crossOriginEmbedderPolicy())
.
Cross-Origin-Opener-Policy
Mặc định:
Cross-Origin-Opener-Policy: same-origin
Tiêu đề Cross-Origin-Opener-Policy
giúp cách ly quy trình của trang. Để biết thêm chi tiết, xem MDN’s article on this header.
// Sets "Cross-Origin-Opener-Policy: same-origin"
app.use(helmet());
// Sets "Cross-Origin-Opener-Policy: same-origin-allow-popups"
app.use(
helmet({
crossOriginOpenerPolicy: { policy: "same-origin-allow-popups" },
})
);
Để vô hiệu hóa tiêu đề Cross-Origin-Opener-Policy
:
app.use(
helmet({
crossOriginOpenerPolicy: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.crossOriginOpenerPolicy())
.
Cross-Origin-Resource-Policy
Mặc định:
Cross-Origin-Resource-Policy: same-origin
Tiêu đề Cross-Origin-Resource-Policy
chặn người khác khỏi việc tải tài nguyên của bạn từ nguồn gốc khác trong một số trường hợp. Để biết thêm chi tiết, xem “Consider deploying Cross-Origin Resource Policy và MDN’s article on this header.
// Sets "Cross-Origin-Resource-Policy: same-origin"
app.use(helmet());
// Sets "Cross-Origin-Resource-Policy: same-site"
app.use(helmet({ crossOriginResourcePolicy: { policy: "same-site" } }));
Để vô hiệu hóa tiêu đề Cross-Origin-Resource-Policy
:
app.use(
helmet({
crossOriginResourcePolicy: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.crossOriginResourcePolicy())
.
Origin-Agent-Cluster
Mặc định:
Origin-Agent-Cluster: ?1
Tiêu đề Origin-Agent-Cluster
cung cấp cơ chế cho phép các ứng dụng web cách ly nguồn gốc của họ khỏi các quy trình khác. Đọc thêm về nó tại in the spec.
Tiêu đề này không có tùy chọn và được thiết lập theo mặc định.
// Sets "Origin-Agent-Cluster: ?1"
app.use(helmet());
Để vô hiệu hóa tiêu đề Origin-Agent-Cluster
:
app.use(
helmet({
originAgentCluster: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.originAgentCluster())
.
Referrer-Policy
Mặc định:
Referrer-Policy: no-referrer
Tiêu đề Referrer-Policy
kiểm soát thông tin được đặt trong the Referer request header. Xem “Referer header: privacy and security concerns” và the header’s documentation trên MDN để biết thêm chi tiết.
// Sets "Referrer-Policy: no-referrer"
app.use(helmet());
policy
là một chuỗi hoặc mảng chuỗi đại diện cho chính sách. Nếu được truyền dưới dạng mảng, nó sẽ được nối với dấu phẩy, điều này hữu ích khi thiết lập a fallback policy. Mặc định là no-referrer
.
// Sets "Referrer-Policy: no-referrer"
app.use(
helmet({
referrerPolicy: {
policy: "no-referrer",
},
})
);
// Sets "Referrer-Policy: origin,unsafe-url"
app.use(
helmet({
referrerPolicy: {
policy: ["origin", "unsafe-url"],
},
})
);
Để vô hiệu hóa tiêu đề Referrer-Policy
:
app.use(
helmet({
referrerPolicy: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.referrerPolicy())
.
Strict-Transport-Security
Mặc định:
Strict-Transport-Security: max-age=15552000; includeSubDomains
Tiêu đề Strict-Transport-Security
thông báo cho trình duyệt ưu tiên HTTPS thay vì HTTP không an toàn. Để biết thêm chi tiết, xem the documentation on MDN.
// Sets "Strict-Transport-Security: max-age=15552000; includeSubDomains"
app.use(helmet());
maxAge
là số giây mà trình duyệt nên nhớ để ưu tiên HTTPS. Nếu truyền một số không nguyên, giá trị sẽ được làm tròn xuống. Mặc định là 15552000
, tương đương 180 ngày.
includeSubDomains
là một boolean quyết định liệu có bao gồm chỉ thị includeSubDomains
, làm cho chính sách này mở rộng đến các tên miền con. Mặc định là true
.
preload
là một boolean. Nếu đúng, nó thêm chỉ thị preload
, biểu thị ý định thêm chính sách HSTS của bạn vào trình duyệt. Xem the “Preloading Strict Transport Security” section on MDN để biết thêm chi tiết. Mặc định là false
.
// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains"
app.use(
helmet({
strictTransportSecurity: {
maxAge: 123456,
},
})
);
// Sets "Strict-Transport-Security: max-age=123456"
app.use(
helmet({
strictTransportSecurity: {
maxAge: 123456,
includeSubDomains: false,
},
})
);
// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains; preload"
app.use(
helmet({
strictTransportSecurity: {
maxAge: 63072000,
preload: true,
},
})
);
Để vô hiệu hóa tiêu đề Strict-Transport-Security
:
app.use(
helmet({
strictTransportSecurity: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.strictTransportSecurity())
.
X-Content-Type-Options
Mặc định:
X-Content-Type-Options: nosniff
Tiêu đề X-Content-Type-Options
giảm thiểu MIME type sniffing có thể gây ra vấn đề bảo mật. Xem documentation for this header on MDN để biết thêm chi tiết.
Tiêu đề này không có tùy chọn và được thiết lập theo mặc định.
// Sets "X-Content-Type-Options: nosniff"
app.use(helmet());
Để vô hiệu hóa tiêu đề X-Content-Type-Options
:
app.use(
helmet({
xContentTypeOptions: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xContentTypeOptions())
.
X-DNS-Prefetch-Control
Mặc định:
X-DNS-Prefetch-Control: off
Tiêu đề X-DNS-Prefetch-Control
giúp kiểm soát việc tiền định danh DNS, có thể cải thiện quyền riêng tư của người dùng nhưng đổi lại là hiệu suất. Xem documentation on MDN để biết thêm chi tiết.
// Sets "X-DNS-Prefetch-Control: off"
app.use(helmet());
allow
là một boolean quyết định liệu có bật tiền định danh DNS. Mặc định là false
.
Ví dụ:
// Sets "X-DNS-Prefetch-Control: off"
app.use(
helmet({
xDnsPrefetchControl: { allow: false },
})
);
// Sets "X-DNS-Prefetch-Control: on"
app.use(
helmet({
xDnsPrefetchControl: { allow: true },
})
);
Để vô hiệu hóa tiêu đề X-DNS-Prefetch-Control
và sử dụng giá trị mặc định của trình duyệt:
app.use(
helmet({
xDnsPrefetchControl: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xDnsPrefetchControl())
.
X-Download-Options
Mặc định:
X-Download-Options: noopen
Tiêu đề X-Download-Options
đặc biệt cho Internet Explorer 8. Nó buộc việc tải xuống có nguy cơ an toàn để được lưu lại, giảm thiểu việc thực hiện mã HTML trong ngữ cảnh trang web của bạn. Xem this old post on MSDN để biết thêm chi tiết.
Tiêu đề này không có tùy chọn và được thiết lập theo mặc định.
// Sets "X-Download-Options: noopen"
app.use(helmet());
Để vô hiệu hóa tiêu đề X-Download-Options
:
app.use(
helmet({
xDownloadOptions: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xDownloadOptions())
.
X-Frame-Options
Mặc định:
X-Frame-Options: SAMEORIGIN
Tiêu đề X-Frame-Options
phiên bản cũ để giúp bạn giảm thiểu clickjacking attacks. Tiêu đề này đã được thay thế bằng the frame-ancestors Content Security Policy directive nhưng vẫn hữu ích trên các trình duyệt cũ hoặc nếu không sử dụng CSP. Xem the documentation on MDN để biết thêm chi tiết.
// Sets "X-Frame-Options: SAMEORIGIN"
app.use(helmet());
action
là một chuỗi xác định chỉ thị nào sẽ được sử dụng – có thể là DENY
hoặc SAMEORIGIN
. (Một chỉ thị cũ, ALLOW-FROM
, không được hỗ trợ bởi Helmet. Read more here.) Mặc định là SAMEORIGIN
.
Ví dụ:
// Sets "X-Frame-Options: DENY"
app.use(
helmet({
xFrameOptions: { action: "deny" },
})
);
// Sets "X-Frame-Options: SAMEORIGIN"
app.use(
helmet({
xFrameOptions: { action: "sameorigin" },
})
);
Để vô hiệu hóa tiêu đề X-Frame-Options
:
app.use(
helmet({
xFrameOptions: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xFrameOptions())
.
X-Permitted-Cross-Domain-Policies
Mặc định:
X-Permitted-Cross-Domain-Policies: none
Tiêu đề X-Permitted-Cross-Domain-Policies
thông báo cho một số khách hàng (chủ yếu là sản phẩm Adobe) về chính sách của tên miền của bạn để tải nội dung chéo tên miền. Xem the description on OWASP để biết thêm chi tiết.
// Sets "X-Permitted-Cross-Domain-Policies: none"
app.use(helmet());
permittedPolicies
là một chuỗi phải là "none"
, "master-only"
, "by-content-type"
hoặc "all"
. Mặc định là "none"
.
Ví dụ:
// Sets "X-Permitted-Cross-Domain-Policies: none"
app.use(
helmet({
xPermittedCrossDomainPolicies: {
permittedPolicies: "none",
},
})
);
// Sets "X-Permitted-Cross-Domain-Policies: by-content-type"
app.use(
helmet({
xPermittedCrossDomainPolicies: {
permittedPolicies: "by-content-type",
},
})
);
Để vô hiệu hóa tiêu đề X-Permitted-Cross-Domain-Policies
:
app.use(
helmet({
xPermittedCrossDomainPolicies: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xPermittedCrossDomainPolicies())
.
X-Powered-By
Mặc định: tiêu đề X-Powered-By
, nếu có, sẽ bị xóa.
Helmet loại bỏ tiêu đề X-Powered-By
, mặc định được đặt trong Express và một số khung công việc khác. Việc loại bỏ tiêu đề mang lại ích lợi bảo mật hạn chế (xem this discussion) và chủ yếu bị xóa để tiết kiệm băng thông, nhưng có thể ngăn cản các kẻ tấn công đơn giản.
Lưu ý: Express has a built-in way to disable the X-Powered-By header, bạn có thể muốn sử dụng thay vào đó.
Việc loại bỏ tiêu đề này không có tùy chọn. Tiêu đề bị loại bỏ theo mặc định.
Để vô hiệu hóa hành vi này:
// Not required, but recommended for Express users:
app.disable("x-powered-by");
// Ask Helmet to ignore the X-Powered-By header.
app.use(
helmet({
xPoweredBy: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xPoweredBy())
.
X-XSS-Protection
Mặc định:
X-XSS-Protection: 0
Helmet vô hiệu hóa bộ lọc lỗi chéo trang web lỗi của trình duyệt bằng cách đặt tiêu đề cũ X-XSS-Protection
thành 0
. Xem discussion about disabling the header here và documentation on MDN.
Tiêu đề này không có tùy chọn và được đặt mặc định.
Để vô hiệu hóa tiêu đề X-XSS-Protection
:
// This is not recommended.
app.use(
helmet({
xXssProtection: false,
})
);
Bạn có thể sử dụng nó như một middleware độc lập với app.use(helmet.xXssProtection())
.
Nguồn: https://github.com