Chuyển tới nội dung
Home » Helmet In Node Js | Getting Started

Helmet In Node Js | Getting Started

Secure ExpressJS Application With Helmet

Conclusion

HTTP headers are something that is often ignored by developers. Most of the time, it’s because we are too preoccupied with trying to make our APIs work and behave the way we want them to.

HTTP headers are generally an afterthought. This can lead to vulnerabilities and sharing of data that can be easily used to exploit your application. It is not that hard to view HTTP headers in the browser. A user simply needs to right-click, navigate to dev tools, then over to the Network tab and check the headers on a file that was fetched from the server. This will let a malicious user see what kind of techniques they can use to exploit your APIs.

By design, HTTP headers are available for all to see. The browser uses this information to prevent certain things from happening to your site — such as cross-domain hijacking and enforcing the usage of HTTPS.

Using Helmet.js with your Express application is a quick and simple way to create a layer of security by switching from Express defaults to a more secure set of defaults. In addition to this, Helmet.js also lets you configure your HTTP headers with ease through the available modules.

Tránh các lỗ hổng đã biết khác

Dưới đây là một số gợi ý bạn nên tham khảo để tăng cường bảo mật cho website của mình (đọc full tại đây https://blog.risingstack.com/node-js-security-checklist/)

  • Triển khai

    rate-limiting

    để ngăn chặn tấn công DDOS
  • Sử dụng

    csurf middleware

    để ngăn chặn (CSRF).
  • Luôn lọc và tiền xử lý user input để ngăn chặn tấn công cross-site scripting (XSS) và command injection.
  • Sử dụng parameterized queries hoặc prepared statements để ngăn chặn SQL injection.
  • Sử dụng sqlmap để chẩn đoán trước lỗi SQL injection vulnerabilities.
  • Sử dụng nmap and sslyze để test cài đặt SSL ciphers, keys…
  • Sử dụng

    safe-regex

    để đảm bảo tất cả các

    regular expressions

    không bị ảnh hưởng bởi regular expression denial of service

Tham khảo: https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS https://blog.risingstack.com/node-js-security-checklist/ https://letsencrypt.org/isrg/ https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations https://expressjs.com/en/advanced/best-practice-security.html https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx

All rights reserved

Helmet.js is a useful Node.js module that helps you secure HTTP headers returned by your Express apps. HTTP headers are an important part of the HTTP protocol, but are generally transparent from the end-user perspective. The headers provide important metadata about the HTTP request or response so the client (browser) and server can send additional information in a transaction.

Why Secure HTTP headers?

Since users do not see HTTP headers, developers have a tendency to ignore them. However, HTTP headers can leak sensitive information about your app inadvertently, so it’s important to configure and use them in a secure way.

A popular way Express apps leak information is through the

X-Powered-By

header. This header informs the browser which server vendor and version you’re using. By default, Express exposes the

X-Powered-By

header and leaks “Express” (usually without a version number). Hackers typically cross-reference this information with a list of publicly disclosed known vulnerabilities, which makes your app a prime target for easy exploits — especially if you’re running an unpatched version of Express.

What is Helmet.js?

Fortunately, Helmet.js makes securing HTTP headers easy for Node.js developers. Helmet.js is a collection of 12 Node modules that interface with Express. Each module provides configuration options for securing different HTTP headers. Here’s a list of the Node modules that are included with Helmet.js:

HTTP Header Helmet.js Default? Related Node Module
Content-Security-Policy contentSecurityPolicy for setting Content Security Policy
Expect-CT expectCt for handling Certificate Transparency
X-DNS-Prefetch-Control dnsPrefetchControl://helmetjs.github.io/docs/dns-prefetch-control) controls browser DNS prefetching
X-Frame-Options frameguard to prevent clickjacking
X-Powered-By hidePoweredBy to remove the X-Powered-By header
Public-Key-Pins hpkp for HTTP Public Key Pinning
Strict-Transport-Security hsts for HTTP Strict Transport Security
X-Download-Options ieNoOpen sets X-Download-Options for IE8+
Cache-Control noCache to disable client-side caching
X-Content-Type-Options noSniff to keep clients from sniffing the MIME type
Referrer-Policy referrerPolicyto hide the Referer header
X-XSS-Protection xssFilter adds some small XSS protections

Sourced from: https://github.com/helmetjs/helmet

For some HTTP headers, Helmet.js automatically defaults to the “secure” option. Others, like

Content-Security-Policy

, require the developer to make an explicit configuration. This is usually because the “best practice” may break functionality or degrade user experience — so configurations must be tuned accordingly.

Helmet.js’s Github page does a great job providing an overview of each HTTP header, the attack scenario, and different Helmet.js configurations you can use. We won’t go into the specifics of each header in this post; instead, we’ll focus on three areas:

  • How to inspect your HTTP headers
  • How to install Helmet
  • An example configuration: Content-Security-Policy

Next, click on the “Network” tab and select an HTTP request made by the browser. Since I am testing on my local machine, I’ve clicked ‘localhost’.

Chances are your Express application isn’t using Helmet.js or securely configuring HTTP headers, so you may see something like this:

Secure ExpressJS Application With Helmet
Secure ExpressJS Application With Helmet

How Helmet.js works and how to use it

Helmet.js comes with a collection of Node modules that you can use to interface to Express to increase the HTTP header security. How does it work? It lets you configure the headers and prevent common vulnerabilities such as clickjacking, implementation of strict HTTP, and download options for vulnerable browsers such as IE8.

When you use Helmet.js, you can also configure Content-Security-Policy to force subsequent developers working on public-facing APIs that require HTTP to approach the code with a security-first mindset.

Here is a list of HTTP headers supported by Helmet.js and how to use them.

Content-Security-Policy

helmet.contentSecurityPolicy(options) lets you set the Content-Security-Policy which allows you to mitigate cross-site scripting attacks. If no directive is applied by the developer, the following policy is set as the default:

Here is an example of the module in use:

useDefaults applies all the defaults as stated above and overrides it with the supplied directives directly below.

But what is a Content-Security-Policy — or CSP?

A CSP lets the browser know how to process certain directions and minimize cross-site scripting vulnerabilities. When CSP isn’t set on your headers, the browser is set to accept all HTTP responses by default. This includes resources from external domains.

By default, Helmet.js doesn’t add CSP as part of its default configuration as it can block things like CDN file inclusion — which can negatively impact a user’s experience. While a blanket exclusion of external loading of scripts is not recommended, you can create a whitelist of domains that is monitored and maintained by the development team.

Expect-CT

helmet.expectCT sets the Expect-CT header. This prevents mis-issued SSL certificates. There are three parameters that you can use.

  • maxAge – determines the number of sections to expect Certificate Transparency.
  • enforce – if true, the user agent should refuse future connections that violate the Certificate Transparency policy. If not set, it defaults to false.
  • reportUri – if anything fails, it will report the failure to the URL supplied.

Here is an example of the module in use:

X-DNS-Prefetch-Control

helmet.dnsPrefetchControl lets you set the X-DNS-Prefetch-Control header in Express. This helps control DNS prefetching and improves user privacy.

Here’s how to use it:

X-Frame-Options

helmet.frameguard sets the X-Frame-Options in the header to prevent clickjacking attacks.

Here is how you can use it:

action takes either deny or sameorigin. By default, Helmet sets this to sameorigin.

X-Powered-By

helmet.hidePoweredBy removes the X-Powered-By broswer, which can give valuable information to malicious users to exploit. In Express, this information is sent to the public by default.

Here is how you can use it:

Strict-Transport-Security

helmet.hsts sets the Strict-Transport-Security header. This tells the browser to prefer HTTPS over HTTP. The maxAge parameter lets the number of seconds browsers should remember to prefer HTTPS. By default, this figure is 15552000 — or 180 days.

You can also include subdomains as well via includeSubDomains. Here is how to use it:

X-Download-Options

helmet.isNoOpen sets the X-Download-Options header. This is specific to the vulnerabilities in IE 8 and forces potentially unsafe downloads to be saved and prevents the execution of HTML in your site’s context.

Here is how to use it:

X-Content-Type-Options

helmet.noSniff sets the X-Content-Type-Options head to nosniff. This prevents MIME type sniffing.

Here is how to use it:

Referrer-Policy

helmet.referrerPolicy sets the Referrer-Policy header. This controls the information inside the Referer header.

Here is an example of how to use it:

By default, Helmet.js sets this to no-referrer.

X-XSS-Protection

helmet.xssFilter prevents cross-site scripting. While browsers come with a filter that prevents this by default, it is not evenly applied and bugginess can range depending on if the end-user is using Chrome, IE, Firefox, Safari, or something else.

Using helmet.xssFilter puts another layer of security on your API. Here is how to use it:

Sử dụng Helmet

Helmet là một package được viêt để giúp bạn bảo vệ ứng dụng của mình khỏi những lỗ hổng đã biết bằng cách thiết lập các Http headers một cách phù hợp Thực tế thì Helmet chỉ là một tập hợp các Middleware nhỏ làm nhiệm vụ thiết lập các Http headers liên quan đến bảo mật, cụ thể như sau:

  • csp Thiết lập header

    Content-Security-Policy

    giúp ngăn chặn tấn công cross-site scripting và các tấn công cross-site injections khác.
  • hidePoweredBy Xóa header

    X-Powered-By header

    khỏi response, giúp dấu đi thông tin mã nguồn bạn sử dụng.
  • hpkp Thêm header

    Public Key Pinning

    giúp bản vệ ứng dụng khỏi tấn công

    man-in-the-middle

    với chứng chỉ giả mạo.
  • hsts Cài đặt header

    Strict-Transport-Security

    giúp thực thi kết nối bảo mật (HTTP over SSL/TLS) đến server.
  • ieNoOpen set header

    X-Download-Options

    cho IE8+.
  • noCache set header

    Cache-Control



    Pragma

    để tắt client-side caching.
  • noSniff set header

    X-Content-Type-Options

    giúp ngăn chặn trình duyệt khỏi MIME-sniffing.
  • frameguard set header

    X-Frame-Options

    để bảo vệ ứng dụng khỏi

    clickjacking

    .
  • xssFilter set header

    X-XSS-Protection

    giúp kích hoạt bộ lọc

    Cross-site scripting (XSS)

    .

Cài đặt và sử dụng Helmet


npm install --save helmet


var helmet = require('helmet') app.use(helmet())

Nếu bạn không muốn sử dụng Helmet thì tốt nhất vẫn nên tắt header

X-Powered-By

. Hacker có thể sử dụng header này để xác định ứng dụng của bạn sử dụng Express.js


app.disable('x-powered-by')

Lưu ý rằng tắt header


x-powered-by

không đảm bảo chắc chắn được hacker không thể xác định app của bạn viết trên Express.js, tuy nhiên nó là cách khá đơn giản và cũng có hiệu quả rất tốt

Set Header Using Helmet NPM Package | How To Header In Nodejs API Using Helmet | API Development
Set Header Using Helmet NPM Package | How To Header In Nodejs API Using Helmet | API Development

Reference


Content-Security-Policy

Default:


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

The

Content-Security-Policy

header mitigates a large number of attacks, such as cross-site scripting. See MDN’s introductory article on Content Security Policy.

This header is powerful but likely requires some configuration.

To configure this header, pass an object with a nested

directives

object. Each key is a directive name in camel case (such as

defaultSrc

) or kebab case (such as

default-src

). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.


// 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-e33...'" (or similar) app.use((req, res, next) => { res.locals.cspNonce = crypto.randomBytes(32).toString("hex"); next(); }); app.use( helmet({ contentSecurityPolicy: { directives: { scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`], }, }, }) );

These directives are merged into a default policy, which you can disable by setting

useDefaults

to

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: [], }, }, }) );

You can get the default directives object with

helmet.contentSecurityPolicy.getDefaultDirectives()

. Here is the default policy (whitespace added for readability):


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

The

default-src

directive can be explicitly disabled by setting its value to

helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc

, but this is not recommended.

You can set the

Content-Security-Policy-Report-Only

instead.


// Sets the Content-Security-Policy-Report-Only header app.use( helmet({ contentSecurityPolicy: { directives: { /* ... */ }, reportOnly: true, }, }) );

Helmet performs very little validation on your CSP. You should rely on CSP checkers like CSP Evaluator instead.

To disable the

Content-Security-Policy

header:


app.use( helmet({ contentSecurityPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.contentSecurityPolicy())

.


Cross-Origin-Embedder-Policy

This header is not set by default.

The

Cross-Origin-Embedder-Policy

header helps control what resources can be loaded cross-origin. See MDN’s article on this header for more.


// 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" } }));

You can use this as standalone middleware with

app.use(helmet.crossOriginEmbedderPolicy())

.


Cross-Origin-Opener-Policy

Default:


Cross-Origin-Opener-Policy: same-origin

The

Cross-Origin-Opener-Policy

header helps process-isolate your page. For more, see 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" }, }) );

To disable the

Cross-Origin-Opener-Policy

header:


app.use( helmet({ crossOriginOpenerPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.crossOriginOpenerPolicy())

.


Cross-Origin-Resource-Policy

Default:


Cross-Origin-Resource-Policy: same-origin

The

Cross-Origin-Resource-Policy

header blocks others from loading your resources cross-origin in some cases. For more, see “Consider deploying Cross-Origin Resource Policy and 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" } }));

To disable the

Cross-Origin-Resource-Policy

header:


app.use( helmet({ crossOriginResourcePolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.crossOriginResourcePolicy())

.


Origin-Agent-Cluster

Default:


Origin-Agent-Cluster: ?1

The

Origin-Agent-Cluster

header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about it in the spec.

This header takes no options and is set by default.


// Sets "Origin-Agent-Cluster: ?1" app.use(helmet());

To disable the

Origin-Agent-Cluster

header:


app.use( helmet({ originAgentCluster: false, }) );

You can use this as standalone middleware with

app.use(helmet.originAgentCluster())

.


Referrer-Policy

Default:


Referrer-Policy: no-referrer

The

Referrer-Policy

header which controls what information is set in the

Referer

request header. See “Referer header: privacy and security concerns” and the header’s documentation on MDN for more.


// Sets "Referrer-Policy: no-referrer" app.use(helmet());


policy

is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when setting a fallback policy. It defaults to

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"], }, }) );

To disable the

Referrer-Policy

header:


app.use( helmet({ referrerPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.referrerPolicy())

.


Strict-Transport-Security

Default:


Strict-Transport-Security: max-age=15552000; includeSubDomains

The

Strict-Transport-Security

header tells browsers to prefer HTTPS instead of insecure HTTP. See the documentation on MDN for more.


// Sets "Strict-Transport-Security: max-age=15552000; includeSubDomains" app.use(helmet());


maxAge

is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to

15552000

, which is 180 days.


includeSubDomains

is a boolean which dictates whether to include the

includeSubDomains

directive, which makes this policy extend to subdomains. It defaults to

true

.


preload

is a boolean. If true, it adds the

preload

directive, expressing intent to add your HSTS policy to browsers. See the “Preloading Strict Transport Security” section on MDN for more. It defaults to

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, }, }) );

To disable the

Strict-Transport-Security

header:


app.use( helmet({ strictTransportSecurity: false, }) );

You can use this as standalone middleware with

app.use(helmet.strictTransportSecurity())

.


X-Content-Type-Options

Default:


X-Content-Type-Options: nosniff

The

X-Content-Type-Options

mitigates MIME type sniffing which can cause security issues. See documentation for this header on MDN for more.

This header takes no options and is set by default.


// Sets "X-Content-Type-Options: nosniff" app.use(helmet());

To disable the

X-Content-Type-Options

header:


app.use( helmet({ xContentTypeOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xContentTypeOptions())

.


X-DNS-Prefetch-Control

Default:


X-DNS-Prefetch-Control: off

The

X-DNS-Prefetch-Control

header helps control DNS prefetching, which can improve user privacy at the expense of performance. See documentation on MDN for more.


// Sets "X-DNS-Prefetch-Control: off" app.use(helmet());


allow

is a boolean dictating whether to enable DNS prefetching. It defaults to

false

.

Examples:


// Sets "X-DNS-Prefetch-Control: off" app.use( helmet({ xDnsPrefetchControl: { allow: false }, }) ); // Sets "X-DNS-Prefetch-Control: on" app.use( helmet({ xDnsPrefetchControl: { allow: true }, }) );

To disable the

X-DNS-Prefetch-Control

header and use the browser’s default value:


app.use( helmet({ xDnsPrefetchControl: false, }) );

You can use this as standalone middleware with

app.use(helmet.xDnsPrefetchControl())

.


X-Download-Options

Default:


X-Download-Options: noopen

The

X-Download-Options

header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site’s context. For more, see this old post on MSDN.

This header takes no options and is set by default.


// Sets "X-Download-Options: noopen" app.use(helmet());

To disable the

X-Download-Options

header:


app.use( helmet({ xDownloadOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xDownloadOptions())

.


X-Frame-Options

Default:


X-Frame-Options: SAMEORIGIN

The legacy

X-Frame-Options

header to help you mitigate clickjacking attacks. This header is superseded by the

frame-ancestors

Content Security Policy directive but is still useful on old browsers or if no CSP is used. For more, see the documentation on MDN.


// Sets "X-Frame-Options: SAMEORIGIN" app.use(helmet());


action

is a string that specifies which directive to use—either

DENY

or

SAMEORIGIN

. (A legacy directive,

ALLOW-FROM

, is not supported by Helmet. Read more here.) It defaults to

SAMEORIGIN

.

Examples:


// Sets "X-Frame-Options: DENY" app.use( helmet({ xFrameOptions: { action: "deny" }, }) ); // Sets "X-Frame-Options: SAMEORIGIN" app.use( helmet({ xFrameOptions: { action: "sameorigin" }, }) );

To disable the

X-Frame-Options

header:


app.use( helmet({ xFrameOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xFrameOptions())

.


X-Permitted-Cross-Domain-Policies

Default:


X-Permitted-Cross-Domain-Policies: none

The

X-Permitted-Cross-Domain-Policies

header tells some clients (mostly Adobe products) your domain’s policy for loading cross-domain content. See the description on OWASP for more.


// Sets "X-Permitted-Cross-Domain-Policies: none" app.use(helmet());


permittedPolicies

is a string that must be

"none"

,

"master-only"

,

"by-content-type"

, or

"all"

. It defaults to

"none"

.

Examples:


// 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", }, }) );

To disable the

X-Permitted-Cross-Domain-Policies

header:


app.use( helmet({ xPermittedCrossDomainPolicies: false, }) );

You can use this as standalone middleware with

app.use(helmet.xPermittedCrossDomainPolicies())

.


X-Powered-By

Default: the

X-Powered-By

header, if present, is removed.

Helmet removes the

X-Powered-By

header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (see this discussion) and is mostly removed to save bandwidth, but may thwart simplistic attackers.

Note: Express has a built-in way to disable the

X-Powered-By

header, which you may wish to use instead.

The removal of this header takes no options. The header is removed by default.

To disable this behavior:


// 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, }) );

You can use this as standalone middleware with

app.use(helmet.xPoweredBy())

.


X-XSS-Protection

Default:


X-XSS-Protection: 0

Helmet disables browsers’ buggy cross-site scripting filter by setting the legacy

X-XSS-Protection

header to . See discussion about disabling the header here and documentation on MDN.

This header takes no options and is set by default.

To disable the

X-XSS-Protection

header:


// This is not recommended. app.use( helmet({ xXssProtection: false, }) );

You can use this as standalone middleware with

app.use(helmet.xXssProtection())

.

Node.js Securing Apps with Helmet.js

Helmet.js

is a Node.js module that helps in securing HTTP headers. It is implemented in express applications. Therefore, we can say that helmet.js helps in securing express applications. It sets up various HTTP headers to prevent attacks like Cross-Site-Scripting(XSS), clickjacking, etc.

Why security of HTTP headers are important:

Sometimes developers ignore the HTTP headers. Since HTTP headers can leak sensitive information about the application, therefore, it is important to use the headers in a secure way.

Node-Modules included in Helmet.js are:

Helmet.js comes with more built-in modules for increasing the security of the Express application.

  • Content-Security-Policy: It sets up the Security Policy.
  • Expect-CT: It is used for handling Certificate Transparency.
  • X-DNS-Prefetch-Control: It is used for controlling the fetching of browser DNS.
  • X-Frame-Options: It is used to prevent ClickJacking.
  • X-Powered-By: It is used to remove X-Powered-By header. X-Powered-By header leaks the version of the server and its vendor.
  • Public-Key-Pins: It is used for HTTP public key pinning.
  • Strict-Transport-Security: It is used for HTTP Strict Transport policy.
  • X-Download-Options: It restricts to various Download-Options.
  • Cache control: It is used for disabling Client-Side caching.
  • X-Content-Type-Options: It is used to prevent the Sniffing attack.
  • Referrer-Policy: It is used to hide the referrer header.
  • X-XSS-Protection: It is used to add protection to XSS attacks.

How to inspect HTTP Header:

For inspecting the header, first right-click on a page that you want to inspect. Now, click on

inspect element

. After that open the

Network

tab. The network tab will look like this:

It will be empty at first. In the network tab, all the HTTP requests made by the browser will be shown up.

Pre-requisites:

  1. An IDE of your choice.
  2. Node.js installed in your system.
  3. Knowledge of Node.js and express applications.

Setting up a basic express application:

  1. First initialize the application with package.json file. Write the following command:

    npm init

  2. Install express module by using the following command:

    npm install express –save

    Shown below is our package.json file:

    {
    “name”: “HelmetJs”,
    “version”: “1.0.0”,
    “description”: “”,
    “main”: “index.js”,
    “scripts”: {
    “test”: “echo \”Error: no test specified\” && exit 1″
    },
    “author”: “Pranjal Srivastava”,
    “license”: “ISC”,
    “dependencies”: {
    “express”: “^4.17.1”,
    }
    }

  3. Create a file in which we will write our javascript code. For example, app.js. You can name your file whatever you want. Now, write the following code for setting up the server:


    const express = require(


    'express'


    );


    const app = express();


    app.get(


    '/'


    , (req, res) => {


    res.send(


    "This is the Demo page for"


    " setting up express server !"


    });


    app.listen(3000, (err) => {


    if


    (err) { console.log(err); }


    else


    { console.log(


    'Server started "


    });

  4. Run app.js file with the following command:

    node app.js

    The output of above command is shown below:

    Server started at http://localhost:3000

  5. Open the browser and go to http://localhost:3000. Again open the Network tab and there you will see the list of requests made by the browser. Select the localhost requests and you will see the list of response headers like this:

    HTTP/1.1 304 Not Modified
    X-Powered-By: Express
    ETag: W/”35-QqeUaYjSJ35gtyT3DcgtpQlitTU”
    Date: Thu, 04 Jun 2020 15:55:00 GMT
    Connection: keep-alive

Setting up and implementing Helmet.js in an express application:

  1. For installing the helmet.js module, write the following command:

    npm install helmet –save

  2. In app.js file, write the following code to make use of helmet module:


    const express = require(


    'express'


    );


    const helmet = require(


    'helmet'


    );


    const app = express();


    app.use(helmet());


    app.get(


    '/'


    , (req, res) => {


    res.send(


    "This is the Demo page for"


    " setting up express server !"


    });


    app.listen(3000, (err) => {


    if


    (err) { console.log(err); }


    else


    { console.log(


    'Server started "


    });

  3. Start the server with the following command:

    node app.js

  4. Open the Network tab by clicking on Inspect Element. Click on localhost and you will notice an additional set of headers in response. The headers are as follows:

    HTTP/1.1 304 Not Modified
    X-DNS-Prefetch-Control: off
    X-Frame-Options: SAMEORIGIN
    Strict-Transport-Security: max-age=15552000; includeSubDomains
    X-Download-Options: noopen
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    ETag: W/”35-QqeUaYjSJ35gtyT3DcgtpQlitTU”
    Date: Thu, 04 Jun 2020 16:11:37 GMT
    Connection: keep-alive

    Here, the new set of headers are applied by our helmet.js module. These headers are added for an additional level of security.

Conclusion: Helmet.js

module is very useful for NodeJs developers as it adds security to the express applications. In this tutorial, we learned about helmet.js and seen its implementation in a basic express application.

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!

Looking for a place to share your ideas, learn, and connect? Our Community portal is just the spot! Come join us and see what all the buzz is about!

Last Updated :
08 Oct, 2021

Like Article

Save Article

Share your thoughts in the comments

Please Login to comment…

Express.js Best Security Paractices

Bài đăng này đã không được cập nhật trong 6 năm

Express.js là một trong những framework phổ biến nhất trong làng dev Node.js, nó là một framework đơn giản nhưng đủ mạnh để giúp chúng ta tiếp cận cũng như phát triển website dựa trên framwork này. Cũng giống như với các framework khác, với Express.js chúng ta cũng có khá nhiều điểm cần lưu ý để đảm bảo ứng dụng của mình hoạt động linh hoạt và an toàn trên môi trường production. Thuật ngữ “production” được dùng để chỉ định giai đoạn trong vòng đời phát triển phần mềm mà khi đó ứng dụng hoặc api đã được public đến người dùng cuối hoặc khách hàng. Ngược lại, giao đoan “development” là giai đoạn khi mà chúng ta vẫn còn đang tiếp tục công việc coding hoặc testing. Hai môi trường Production và Development thường có những cài đặt, cấu hình khác nhau nhằm phục vụ cho việc debug, testing khi development và đảm bảo performance, security khi lên production; trong đó thì có rất nhiều thứ hợp lý và hữu ích khi development nhưng lại hoàn toàn không nên hoặc bị cấm khi lên production (như là logging, debugging…) Dưới đây là một số lưu ý khi triển khai production cho một ứng dụng Express.js

Get started

Here’s a sample Express app that uses 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);

You can also

require("helmet")

if you prefer.

By default, Helmet sets the following headers:


  • Content-Security-Policy

    : A powerful allow-list of what can happen on your page which mitigates many attacks

  • Cross-Origin-Opener-Policy

    : Helps process-isolate your page

  • Cross-Origin-Resource-Policy

    : Blocks others from loading your resources cross-origin

  • Origin-Agent-Cluster

    : Changes process isolation to be origin-based

  • Referrer-Policy

    : Controls the

    Referer

    header

  • Strict-Transport-Security

    : Tells browsers to prefer HTTPS

  • X-Content-Type-Options

    : Avoids MIME sniffing

  • X-DNS-Prefetch-Control

    : Controls DNS prefetching

  • X-Download-Options

    : Forces downloads to be saved (Internet Explorer only)

  • X-Frame-Options

    : Legacy header that mitigates clickjacking attacks

  • X-Permitted-Cross-Domain-Policies

    : Controls cross-domain behavior for Adobe products, like Acrobat

  • X-Powered-By

    : Info about the web server. Removed because it could be used in simple attacks

  • X-XSS-Protection

    : Legacy header that tries to mitigate XSS attacks, but makes things worse, so Helmet disables it

Each header can be configured. For example, here’s how you configure the

Content-Security-Policy

header:

// This sets custom options for the // Content-Security-Policy header. app.use( helmet({ contentSecurityPolicy: { directives: { “script-src”: [“‘self'”, “example.com”], }, }, }), );

Headers can also be disabled. For example, here’s how you disable the

Content-Security-Policy

and

X-Download-Options

headers:

// This disables the Content-Security-Policy // and X-Download-Options headers. app.use( helmet({ contentSecurityPolicy: false, xDownloadOptions: false, }), );

Helmet NodeJS | Middleware NodeJS
Helmet NodeJS | Middleware NodeJS

I am the author here. Thanks! I am glad you found the article useful and comprehensive.

Express.js is the most popular web framework for developing web applications in Node.js. It comes with several features to make API development faster and easier.

However, Express falls short when it comes to security, not ensuring an adequate level of protection from common vulnerabilities. Fortunately, it can be easily extended thanks to middleware, a set of functions executed during the processing of HTTP requests.

Helmet.js is middleware-based technology that improves security by safeguarding HTTP headers returned by a Node.js app. Here, you will learn what Helmet is, why you need it, and how to integrate it into Node.js to secure HTTP headers in an Express.js application. We will cover:

Let’s dig into Helmet in Node.js!

Helmet.js is an open source JavaScript library that helps you secure your Node.js application by setting several HTTP headers. It acts as a middleware for Express and similar technologies, automatically adding or removing HTTP headers to comply with web security standards.

Although not a silver bullet, Helmet makes it harder for attackers to exploit known vulnerabilities. It helps to protect Node.js Express apps from common security threats such as Cross-Site Scripting (XSS) and click-jacking attacks.

Helmet is particularly useful because Express applications do not come with security HTTP headers out of the box. This explains why the

helmet

npm package has more than 2,000,000 weekly downloads, while its GitHub repo boasts over 9.4k stars!

Let’s now dig deeper into why adopting Helmet in Node.js is so important.

Without Helmet, default headers returned by Express expose sensitive information and make your Node.js app vulnerable to malicious actors. In contrast, using Helmet in Node.js protects your application from XSS attacks, Content Security Policy vulnerabilities, and other security issues.

Let’s explore this question further through an example. You are going to set up a Node.js Express app and see what level of security its default HTTP headers offer.

First, make sure you have Node.js and npm installed on your machine. If you aren’t set up yet, start by downloading Node.js and following the installation wizard to set it up.

Now, let’s set up an Express project. Run the command below to create the

express-demo

project folder:

mkdir express-demo

Then, enter the

express-demo

folder in your terminal by running the following:

cd express-demo

Launch the following command to initialize a default npm project:

npm init -y

The

npm init

command will configure a blank npm project for you. Note that the

-y

flag will automatically answer “yes” to all questions that npm would otherwise ask you during the process.

You need to add Express to your project’s dependencies. Install the Express module with the below:

npm install express

Then, create an

index.js

file in the

express-demo

folder and initialize it with these lines:

// index.js const express = require(“express”) // creating an Express instance const app = express() const PORT = process.env.PORT || 3000 // initializing a basic API that // returns the “Hello, World!” message app.get(“/”, (req, res) => { res.json(“Hello, World!”) }) // running the server app.listen(PORT, () => { console.log(`Starting Express server on http://localhost:${PORT}`) })

This is nothing more than a basic Express server setup with a single endpoint.

Start the server with this command:

node index.js

The Express server should now be running at

http://localhost:3000

. Launch the command below in your terminal to test the endpoint:

curl http://localhost:3000/

This should print the following output:

“Hello, World!”

Et voilà! You now have a working Express app!

Let’s now use the demo application we just created to verify the default behavior of Express when it comes to security HTTP headers.

Repeat the

curl

command above with the

--include

flag to get also the HTTP response headers:

curl http://localhost:3000/ –include

If you do not have cURL installed on your computer, use an HTTP client such as Postman or Insomnia to inspect the HTTP headers of the response.

In the response header section, you should be seeing the following:

X-Powered-By: Express Content-Type: application/json; charset=utf-8 Content-Length: 15 ETag: W/”f-pob1Yw/KBE+3vrbZz9GAyq5P2gE” Date: Fri, 20 Jan 2023 16:29:40 GMT Connection: keep-alive Keep-Alive: timeout=5

Note the

X-Powered-By

header. As with all headers that begin with

X-

, it is a non-standard header. Specifically, backend technologies generally use

X-Powered-By

to indicate the name and version number of the framework or library used by the server to generate the HTTP response.

As recommended by OWASP, a nonprofit foundation that works to improve web security,

X-Powered-By

should be omitted. This is because you should never give attackers details about your tech stack. Otherwise, they could use that info to exploit known vulnerabilities in that framework or library.

Now, let’s check what the Security Headers online project has to say about the security level of your Express app.

Since Security Headers only allows you to test public addresses, you need to make your local Express server publicly available. You can either deploy your Express app to a server or take advantage of ngrok, which allows you to expose a local web server to the Internet.

Download ngrok, extract it, and open the folder in the terminal. Then, launch the following command to host your local server with ngrok:

ngrok http 3000

You should get a similar result to the below:

The “Forwarding” field contains the URL to publicly access your local server. Since the endpoint to test is , copy the URL, add a trailing character, and paste it in the Security Headers input as shown below:

Click the “Scan” button, and you should get the following result:

As you can see here, the Security Headers project gives the demo app a worrying “F” grade. The reason is that the API response developed with Express without Helmet is missing all the most relevant HTTP security headers.

This is also why the official Express “Production Best Practices: Security” page mentions adopting Helmet as a best practice for production applications. Let’s now learn how to integrate Helmet in Node.js!

Let’s expand the Express demo project implemented earlier to secure it with Helmet. As you are about to learn, this only takes a couple of lines of code.

First, you need to add Helmet.js to your project’s dependencies. Install the

helmet

npm package with the following command:

npm i helmet

Your

package.json

file will now contain

helmet

in the

dependencies

fields.

Integrating Helmet into your Node.js Express app is simple. In case of problems, follow the official guide.

In your

index.js

file, import

helmet

with the following command:

const helmet = require(“helmet”)

Now, register

helmet

in your Express application with the below:

app.use(helmet())

Remember that

helmet()

is nothing more than an Express middleware. Specifically, the top-level

helmet()

function is a wrapper of 15 sub-middlewares. So, by registering

helmet()

, you are adding 15 Express middlewares to your apps.

Note that each middleware takes care of setting one HTTP security header.

Your

index.js

file will now look as follows:

// index.js const express = require(“express”) const helmet = require(“helmet”) const PORT = process.env.PORT || 3000 const app = express() // enabling the Helmet middleware app.use(helmet()) // initializing a basic API that // returns the “Hello, World!” message app.get(“/”, (req, res) => { res.json(“Hello, World!”) }) // running the server app.listen(PORT, () => { console.log(`Starting Express server on http://localhost:${PORT}`) })

That’s it! Adding Helmet to your Node.js app only involve two lines of code!

Let’s repeat the security test performed earlier. Stop your Node.js local server and relaunch it with this command:

node index.js

Repeat the

curl

command or use an HTTP client to see the HTTP headers of the new response:

curl http://localhost:3000/ –include

The response HTTP header section will now include the following:

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 Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin Cross-Origin-Resource-Policy: same-origin X-DNS-Prefetch-Control: off X-Frame-Options: SAMEORIGIN Strict-Transport-Security: max-age=15552000; includeSubDomains X-Download-Options: noopen X-Content-Type-Options: nosniff Origin-Agent-Cluster: ?1 X-Permitted-Cross-Domain-Policies: none Referrer-Policy: no-referrer X-XSS-Protection: 0 Content-Type: application/json; charset=utf-8 Content-Length: 15 ETag: W/”f-pob1Yw/KBE+3vrbZz9GAyq5P2gE” Date: Fri, 20 Jan 2023 18:15:32 GMT Connection: keep-alive Keep-Alive: timeout=5

As you can see, there are many new HTTP headers in the response. Also,

X-Powered-By

was removed.

If you shut down ngrok, run it again with the following:

ngrok http 3000

Otherwise, visit the Security Headers website right away. Just like before, copy the URL provided by ngrok and click “Scan.” This time, the outcome will be different:

Note that the API response now involves all the major HTTP Security headers, except for

Permissions-Policy

. This allowed the Express app to go from an “F” grade to an “A” grade. What a huge change with just two lines of code!

Also, as mentioned on GitHub by one of the lead developers of Helmet.js, Helmet does not automatically support

Permissions-Policy

only because the header specification is still in a draft state. So, this may change soon.

As you just learned, Helmet sets a lot of headers by default. Since security policies change over time, it is critical to always keep

helmet

up-to-date. This way, the security headers introduced by Helmet will always comply with security standards.

All of those headers have an impact on the security of your application, but some are more relevant than others. Let’s now focus on the most important security headers to understand why they are useful, how Helmet treats them by default, and how you can configure them with Helmet.


Content-Security-Policyheader

Content Security Policy, also known as CSP, is a security measure that helps you mitigate several attacks, such as cross-site scripting (XSS) and data injection attacks.

Specifically, CSP allows you to specify what sources of content a web page is allowed to load and execute. For example, you can use CSP to block a web page from loading images and iframes from other websites.

You can configure CSP through the

Content-Security-Policy

HTTP header. By default, Helmet gives the

Content-Security-Policy

header the following value:

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

With this policy, your web pages cannot load remote fonts or styles. This is because

font-src

and

style-src

are set to

self

, respectively. The CSP policy defined by Helmet by default is very restrictive, but you can change it with

contentSecurityPolicy()

as follows:

// overriding “font-src” and “style-src” while // maintaining the other default values helmet.contentSecurityPolicy({ useDefaults: true, directives: { “font-src”: [“‘self'”, “external-website.com”], // allowing styles from any website “style-src”: null, }, })


useDefaults

applies the default values. Then, the following directives override the defaults. Set

useDefaults

to

false

to define a CSP policy from scratch.


Referrer-Policyheader

The

Referrer-Policy

HTTP header defines what data should be sent as referrer information in the

Referer

header. By default,

Referer

generally contains the current URL from which an HTTP request is performed.

For example, if you click on a link to a third-party website,

Referer

will contain the address of the current web page. As a result, the third-party website could use the header to track you or understand what you were visiting.

If the current address contains private user information, the third-party site will be able to steal it from the

Referer

header. Because of this, even though this header is typically used for caching or analytics, it opens up some privacy concerns because it can leak sensitive information.

Helmet sets it to

no-referrer

by default. This means that the

Referer

header will always be empty. So, requests performed by web pages served by your Node.js app will not include any referrer information.

If you want to change this restrictive policy, you can do it with

refererPolicy

as below:

// setting “Referrer-Policy” to “no-referrer” app.use( helmet.referrerPolicy({ policy: “no-referrer”, }) )


Strict-Transport-Securityheader

The

Strict-Transport-Security

HTTP header, also known as HSTS, specifies that a site or resource should only be accessed via HTTPS. In detail, the

maxAge

parameter defines the number of seconds browsers should remember to prefer HTTPS over HTTP.

By default, Helmet sets the

Strict-Transport-Security

header as follows:

max-age=15552000; includeSubDomains

Note that

15552000

seconds corresponds to 180 days, as well as that

includeSubDomains

extends the HSTS policy to all the site’s subdomains.

You can configure the

Strict-Transport-Security

header with the

hsts

Helmet function as follows:

app.use( helmet.hsts({ // 60 days maxAge: 86400, // removing the “includeSubDomains” option includeSubDomains: false, }) )


X-Content-Type-Optionsheader

The

X-Content-Type-Options

HTTP header defines that the MIME types used in the

Content-Type

header must be followed. This mitigates MIME type sniffing, which can lead to XSS attacks and cause other vulnerabilities.

For example, attackers could hide HTML code in a

.png

file. The browser might perform MIME type sniffing to determine the content type of the resource.

Since the file contains HTML code, the browser will determine that it is an HTML file rather than a JPG image. Thus, the browser will execute the attacker’s code accordingly when rendering the page.

By default, Helmet sets

X-Content-Type-Options

to

nosniff

. This disables and prevents MIME type sniffing.

Note that the

noSniff()

Helmet function contained in

helmet()

does not accept parameters. If you want to disable this behavior and go against recommended security policies, you can prevent Helmet from importing

nosniff()

with the following:

app.use( // not loading the noSniff() middleware helmet({ noSniff: false, }) )


X-Frame-Optionsheader

The

X-Frame-Options

HTTP response header specifies whether or not a browser should be allowed to render a page in the , , and HTML elements.

By preventing the content of your site from being embedded in other sites, you can avoid click-jacking attacks. A click-jacking attack involves tricking users into clicking on something different from what they perceive or expect.

By default, Helmet sets

X-Frame-Options

to

SAMEORIGIN

. This allows a web page to be embedded in a frame on pages with the same origin as the page itself. You can set this header in Helmet with

frameguard()

as follows:

// setting “X-Frame-Options” to “DENY” app.use( helmet.frameguard({ action: “deny”, }) );

If you want to omit the

X-Frame-Options

header entirely, you can disable the

frameguard()

middleware with the following:

app.use( // not including the frameguard() middleware helmet({ frameguard: false, }) )

Note that this is not recommended for security reasons.

In this article, you learned what Helmet.js is and why it plays such an important role when it comes to securing a Node.js app.

As you saw here, APIs developed in Express do not involve security HTTP headers. So, default Express apps come with some security concerns.

With Helmet, you can add a security layer to Node.js with just a single line of code, safeguarding your application from the most common attacks and vulnerabilities.

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.

By building these four simple projects, you’ll learn how CSS variables can help you write reusable, elegant code and streamline the way you build websites.

In this article, we’ll learn what a component library is and how to build our component library with React and TypeScript.

Chakra UI has emerged as a highly relevant design library. Let’s discuss what makes Chakra UI a great choice for modern applications.

Brant Snow is the Vice President of Technology at Extensiv, an omnichannel software solutions provider for warehouse, inventory, and order […]

I am the author here. Thanks! I am glad you found the article useful and comprehensive.

Really helpfull

Yet another great LogRocket article! The articles alone is why I would consider using LogRocket for the project I’m currently working on.

I’ll be in touch soon.

I’m using Helmet and CORS packages to my node.js application. But I don’t know what’s the difference of both packages and the performance impact to the application. Also, by using these packages, will it secure the my node.js application or adds security to the client?

2 Answers

Helmet is a nodejs package that helps protect your server from some well-known web vulnerabilities by setting HTTP response headers appropriately, it comes with a collection of several middleware functions that set security headers that are returned from your express application.
The top-level

helmet

function is a wrapper around 15 smaller middlewares.

Some security attacks help secure your express server from common attacks such as clickjacking, and cross-site scripting attacks, it also helps enforce secure HTTPS connections to your server, download options for vulnerable browsers, and a host of other vulnerabilities. As you see it’s an important package to have in your express app, it’s actually listed among packages to use under production’s best practices from the official express website.

Cors on the other hand is a node.js package that provides your express app with middlewares to enable Cross-origin resource sharing (CORS) which is a mechanism that allows resources on your express app from being shared with external domains, its important in making cross-domain requests possible in case it’s needed.
A typical use case is developing a full-stack application where the static content like the HTML pages are not located within the domain of your express app, like in the case of local development where an angular or react app running on

localhost:4200

needs to access your express app resource served from

localhost:3000

, without CORS enabled this request will not be possible.

The Cors package equally exposes a reach interface to restrict access of resources to whitelisted domains, below is an example from the node.js CORS package


var express = require('express') var cors = require('cors') var app = express() var whitelist = ['http://example1.com', 'http://example2.com'] var corsOptions = { origin: function (origin, callback) { if (whitelist.indexOf(origin) !== -1) { callback(null, true) } else { callback(new Error('Not allowed by CORS')) } } } app.get('/products/:id', cors(corsOptions), function (req, res, next) { res.json({msg: 'This is CORS-enabled for a whitelisted domain.'}) })

Notice the whitelisted domains

http://example1.com

and

http://example2.com

allowed to access the

/products/:id

route of the express server.

Summary

Helmet and Cors are 2 important node.js packages with different purposes. Helmet secures your express app by setting response HTTP headers appropriately, while Cors enables your express application access control to allow restricted resources from being accessed from external domains.

Performance-wise, both helmet and cors bring basic middleware functions with little or no performance effect, setting a couple of important HTTP headers will not negatively impact your server, I don’t think so. and as a matter of fact now you know the importance of using this packages in your express app and what it brings.

  • 6I maintain Helmet and I upvoted this answer. Jul 9, 2022 at 17:23
  • If we use proxy server like nginx, will it still protect the node.js app? @EvanHahn Jul 10, 2022 at 4:48
  • 1Yes, as long as nginx doesn’t disable the headers. Jul 11, 2022 at 14:13

In my opinion CORS is the best, you can easily eliminate the worst error which is “breaking cors law”, and also adding some security to your node.js application, by stricting it to accept connections from origins you want to. So, yes, it will secure your node.js app if you know how to set it right

  • Hi thanks for the quick answer. But my concern is Helmet given as the best solution in the express official website expressjs.com/en/advanced/… Also I need to know about the differences between them. Jul 9, 2022 at 15:26
  • Furthermore, if we use proxy server like nginx, will it still protect the node.js app? Jul 9, 2022 at 15:27
  • You could try using Helmet alongside with cors. Helmet provides security for your app for clickjacking, enforces HTTPS connection to server, and prevents cross-site scripting attacks injecting scripts into your app to gain connection. And yes, if you use proxy server nothing will change, proxy server only makes the server more available from other sources like other links etc.– SkayuJul 9, 2022 at 15:31
  • If we use both Helmet and Cors, it will impact to the performance of my application as too many headers were applied. And for the second question, if we use a proxy server, it will not get the Helmet protection as it not served the HTTP content Jul 9, 2022 at 15:36

Helmet helps secure Express apps by setting HTTP response headers.

Reference


Content-Security-Policy

Default:


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

The

Content-Security-Policy

header mitigates a large number of attacks, such as cross-site scripting. See MDN’s introductory article on Content Security Policy.

This header is powerful but likely requires some configuration.

To configure this header, pass an object with a nested

directives

object. Each key is a directive name in camel case (such as

defaultSrc

) or kebab case (such as

default-src

). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.


// 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-e33...'" (or similar) app.use((req, res, next) => { res.locals.cspNonce = crypto.randomBytes(32).toString("hex"); next(); }); app.use( helmet({ contentSecurityPolicy: { directives: { scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`], }, }, }) );

These directives are merged into a default policy, which you can disable by setting

useDefaults

to

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: [], }, }, }) );

You can get the default directives object with

helmet.contentSecurityPolicy.getDefaultDirectives()

. Here is the default policy (whitespace added for readability):


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

The

default-src

directive can be explicitly disabled by setting its value to

helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc

, but this is not recommended.

You can set the

Content-Security-Policy-Report-Only

instead.


// Sets the Content-Security-Policy-Report-Only header app.use( helmet({ contentSecurityPolicy: { directives: { /* ... */ }, reportOnly: true, }, }) );

Helmet performs very little validation on your CSP. You should rely on CSP checkers like CSP Evaluator instead.

To disable the

Content-Security-Policy

header:


app.use( helmet({ contentSecurityPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.contentSecurityPolicy())

.


Cross-Origin-Embedder-Policy

This header is not set by default.

The

Cross-Origin-Embedder-Policy

header helps control what resources can be loaded cross-origin. See MDN’s article on this header for more.


// 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" } }));

You can use this as standalone middleware with

app.use(helmet.crossOriginEmbedderPolicy())

.


Cross-Origin-Opener-Policy

Default:


Cross-Origin-Opener-Policy: same-origin

The

Cross-Origin-Opener-Policy

header helps process-isolate your page. For more, see 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" }, }) );

To disable the

Cross-Origin-Opener-Policy

header:


app.use( helmet({ crossOriginOpenerPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.crossOriginOpenerPolicy())

.


Cross-Origin-Resource-Policy

Default:


Cross-Origin-Resource-Policy: same-origin

The

Cross-Origin-Resource-Policy

header blocks others from loading your resources cross-origin in some cases. For more, see “Consider deploying Cross-Origin Resource Policy and 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" } }));

To disable the

Cross-Origin-Resource-Policy

header:


app.use( helmet({ crossOriginResourcePolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.crossOriginResourcePolicy())

.


Origin-Agent-Cluster

Default:


Origin-Agent-Cluster: ?1

The

Origin-Agent-Cluster

header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about it in the spec.

This header takes no options and is set by default.


// Sets "Origin-Agent-Cluster: ?1" app.use(helmet());

To disable the

Origin-Agent-Cluster

header:


app.use( helmet({ originAgentCluster: false, }) );

You can use this as standalone middleware with

app.use(helmet.originAgentCluster())

.


Referrer-Policy

Default:


Referrer-Policy: no-referrer

The

Referrer-Policy

header which controls what information is set in the

Referer

request header. See “Referer header: privacy and security concerns” and the header’s documentation on MDN for more.


// Sets "Referrer-Policy: no-referrer" app.use(helmet());


policy

is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when setting a fallback policy. It defaults to

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"], }, }) );

To disable the

Referrer-Policy

header:


app.use( helmet({ referrerPolicy: false, }) );

You can use this as standalone middleware with

app.use(helmet.referrerPolicy())

.


Strict-Transport-Security

Default:


Strict-Transport-Security: max-age=15552000; includeSubDomains

The

Strict-Transport-Security

header tells browsers to prefer HTTPS instead of insecure HTTP. See the documentation on MDN for more.


// Sets "Strict-Transport-Security: max-age=15552000; includeSubDomains" app.use(helmet());


maxAge

is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to

15552000

, which is 180 days.


includeSubDomains

is a boolean which dictates whether to include the

includeSubDomains

directive, which makes this policy extend to subdomains. It defaults to

true

.


preload

is a boolean. If true, it adds the

preload

directive, expressing intent to add your HSTS policy to browsers. See the “Preloading Strict Transport Security” section on MDN for more. It defaults to

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, }, }) );

To disable the

Strict-Transport-Security

header:


app.use( helmet({ strictTransportSecurity: false, }) );

You can use this as standalone middleware with

app.use(helmet.strictTransportSecurity())

.


X-Content-Type-Options

Default:


X-Content-Type-Options: nosniff

The

X-Content-Type-Options

mitigates MIME type sniffing which can cause security issues. See documentation for this header on MDN for more.

This header takes no options and is set by default.


// Sets "X-Content-Type-Options: nosniff" app.use(helmet());

To disable the

X-Content-Type-Options

header:


app.use( helmet({ xContentTypeOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xContentTypeOptions())

.


X-DNS-Prefetch-Control

Default:


X-DNS-Prefetch-Control: off

The

X-DNS-Prefetch-Control

header helps control DNS prefetching, which can improve user privacy at the expense of performance. See documentation on MDN for more.


// Sets "X-DNS-Prefetch-Control: off" app.use(helmet());


allow

is a boolean dictating whether to enable DNS prefetching. It defaults to

false

.

Examples:


// Sets "X-DNS-Prefetch-Control: off" app.use( helmet({ xDnsPrefetchControl: { allow: false }, }) ); // Sets "X-DNS-Prefetch-Control: on" app.use( helmet({ xDnsPrefetchControl: { allow: true }, }) );

To disable the

X-DNS-Prefetch-Control

header and use the browser’s default value:


app.use( helmet({ xDnsPrefetchControl: false, }) );

You can use this as standalone middleware with

app.use(helmet.xDnsPrefetchControl())

.


X-Download-Options

Default:


X-Download-Options: noopen

The

X-Download-Options

header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site’s context. For more, see this old post on MSDN.

This header takes no options and is set by default.


// Sets "X-Download-Options: noopen" app.use(helmet());

To disable the

X-Download-Options

header:


app.use( helmet({ xDownloadOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xDownloadOptions())

.


X-Frame-Options

Default:


X-Frame-Options: SAMEORIGIN

The legacy

X-Frame-Options

header to help you mitigate clickjacking attacks. This header is superseded by the

frame-ancestors

Content Security Policy directive but is still useful on old browsers or if no CSP is used. For more, see the documentation on MDN.


// Sets "X-Frame-Options: SAMEORIGIN" app.use(helmet());


action

is a string that specifies which directive to use—either

DENY

or

SAMEORIGIN

. (A legacy directive,

ALLOW-FROM

, is not supported by Helmet. Read more here.) It defaults to

SAMEORIGIN

.

Examples:


// Sets "X-Frame-Options: DENY" app.use( helmet({ xFrameOptions: { action: "deny" }, }) ); // Sets "X-Frame-Options: SAMEORIGIN" app.use( helmet({ xFrameOptions: { action: "sameorigin" }, }) );

To disable the

X-Frame-Options

header:


app.use( helmet({ xFrameOptions: false, }) );

You can use this as standalone middleware with

app.use(helmet.xFrameOptions())

.


X-Permitted-Cross-Domain-Policies

Default:


X-Permitted-Cross-Domain-Policies: none

The

X-Permitted-Cross-Domain-Policies

header tells some clients (mostly Adobe products) your domain’s policy for loading cross-domain content. See the description on OWASP for more.


// Sets "X-Permitted-Cross-Domain-Policies: none" app.use(helmet());


permittedPolicies

is a string that must be

"none"

,

"master-only"

,

"by-content-type"

, or

"all"

. It defaults to

"none"

.

Examples:


// 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", }, }) );

To disable the

X-Permitted-Cross-Domain-Policies

header:


app.use( helmet({ xPermittedCrossDomainPolicies: false, }) );

You can use this as standalone middleware with

app.use(helmet.xPermittedCrossDomainPolicies())

.


X-Powered-By

Default: the

X-Powered-By

header, if present, is removed.

Helmet removes the

X-Powered-By

header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (see this discussion) and is mostly removed to save bandwidth, but may thwart simplistic attackers.

Note: Express has a built-in way to disable the

X-Powered-By

header, which you may wish to use instead.

The removal of this header takes no options. The header is removed by default.

To disable this behavior:


// 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, }) );

You can use this as standalone middleware with

app.use(helmet.xPoweredBy())

.


X-XSS-Protection

Default:


X-XSS-Protection: 0

Helmet disables browsers’ buggy cross-site scripting filter by setting the legacy

X-XSS-Protection

header to . See discussion about disabling the header here and documentation on MDN.

This header takes no options and is set by default.

To disable the

X-XSS-Protection

header:


// This is not recommended. app.use( helmet({ xXssProtection: false, }) );

You can use this as standalone middleware with

app.use(helmet.xXssProtection())

.

Helmet

Helmet helps secure Express apps by setting HTTP response headers.

Express JS | Using The Helmet Middleware
Express JS | Using The Helmet Middleware

Bảo mật với cookie

Để đảm bảo rẳng cookies không khiến ứng dụng của bạn bị hack, tuyệt đối không sử dụng cookie name mặc định cũng như cần phải thiết lập đúng cách các options với cookie Đối với việc bảo mật cookies, chúng ta có thể sử dụng 2 packages sau:

  • express-session thay thế middleware mặc định

    express.session

    lên phiên bản Express 3.x.
  • cookie-session thay thế middleware mặc định

    express.cookieSession

    lên phiên bản Express 3.x. Điểm khác biệt chính giữa hai packages này nằm ở cách chúng lưu trữ dữ liệu cookie session.

    express-session

    lưu trữ dữ liệu session tại server, nó chỉ sử dụng cookie để lữu trữ Session ID. Mặc định nó sẽ sử dụng bộ lưu trữ in-memory và cách lưu trữ này không được thiết kế để chạy với môi trường production. Với môi trường Production, bạn sẽ cần phải cài đặt một bộ lưu trữ session có tính linh hoạt cao và có khả năng mở rộng, xem danh sách được hỗ trợ: https://github.com/expressjs/session#compatible-session-stores

    cookie-session

    thì ngược lại, nó triển khai một bộ lưu trữ

    cookie-backed

    :

    cookie-session

    sẽ serializes toàn bộ dữ liệu session thành cookie. Chỉ sử dụng cách này khi dữ liệu session nhỏ và có thể dễ dàng để mã hóa. Mặc dù browser có thể hỗ trợ tối thiểu 4096 bytes cho mỗi cookie nhưng để đảm bảo bạn không bị quá giới hạn này thì tốt nhất không để cho size vượt quá 4093 bytes với mỗi cookie domain. Bạn cũng nên lưu ý rằng dữ liệu cookie là mở và có thể can thiệp bởi client, do đó trong trường hợp dữ liệu cookie là quan trọng thì tốt hơn nên sử dụng

    express-session

    .

Không sử dụng cookie name mặc định

Cũng giống như với việc dấu đi header

X-Powered-By

, chúng ta cũng nên thay đổi tên mặc định của cookie, điều này sẽ giúp ẩn dấu thông tin framework ta sử dụng


var session = require('express-session') app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 's3Cur3', name: 'sessionId' }))

Thiết lập các options nâng cao bảo mật

Cài đặt các options sau đây để giúp tăng cường bảo mật cho cookie:

  • secure – Đảm bảo rằng browser sẽ chỉ gửi cookie qua HTTPS.
  • httpOnly – Đảm bảo rằng cookie chỉ được gửi qua HTTP(S), không phải thông qua client JavaScript, giúp ngăn chặn tấn công cross-site scripting.
  • domain – Chỉ định domain của cookie; Cookie chỉ hợp lệ đối với domain phát sinh request.
  • path – Chỉ định path của cookie.
  • expires – Thiết lập thời gian hết hạn cho cookie. Ví dụ về thiết lập bảo mật cho cookie


var session = require('cookie-session') var express = require('express') var app = express() var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], cookie: { secure: true, httpOnly: true, domain: 'example.com', path: 'foo/bar', expires: expiryDate } }))

Cập nhật tất cả các packages hiện tại

NPM là một công cụ rất mạnh mẽ hỗ trợ quản lý các dependencies của ứng dụng, tuy nhiên các packages có thể tồn tại các lỗ hổng bảo mật có thể ảnh hưởng đến ứng dụng của bạn. Ứng dụng của bạn không thể đảm bảo được bảo mật nếu một trong các packages có lỗ hổng. Sử dụng các packages sau để kiểm tra bảo mật các packages bạn sử dụng:

Use either or both of the following two tools to help ensure the security of third-party packages that you use: nsp and Snyk.

nsp là một công cụ command-line giúp kiểm tra bảo mật dựa trên db các lỗ hổng đã biết.


$ npm i nsp -g


nsp check

Snyk cung cấp cả cli và Github integration để có thể check lỗ hổng nhanh và toàn diện hơn


$ npm install -g snyk $ cd your-app


snyk test


snyk wizard

helmet.js | Secure Node.js and Express.js APP/API
helmet.js | Secure Node.js and Express.js APP/API

Get started

Here’s a sample Express app that uses 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);

You can also

require("helmet")

if you prefer.

By default, Helmet sets the following headers:


  • Content-Security-Policy

    : A powerful allow-list of what can happen on your page which mitigates many attacks

  • Cross-Origin-Opener-Policy

    : Helps process-isolate your page

  • Cross-Origin-Resource-Policy

    : Blocks others from loading your resources cross-origin

  • Origin-Agent-Cluster

    : Changes process isolation to be origin-based

  • Referrer-Policy

    : Controls the

    Referer

    header

  • Strict-Transport-Security

    : Tells browsers to prefer HTTPS

  • X-Content-Type-Options

    : Avoids MIME sniffing

  • X-DNS-Prefetch-Control

    : Controls DNS prefetching

  • X-Download-Options

    : Forces downloads to be saved (Internet Explorer only)

  • X-Frame-Options

    : Legacy header that mitigates clickjacking attacks

  • X-Permitted-Cross-Domain-Policies

    : Controls cross-domain behavior for Adobe products, like Acrobat

  • X-Powered-By

    : Info about the web server. Removed because it could be used in simple attacks

  • X-XSS-Protection

    : Legacy header that tries to mitigate XSS attacks, but makes things worse, so Helmet disables it

Each header can be configured. For example, here’s how you configure the

Content-Security-Policy

header:


// This sets custom options for the // Content-Security-Policy header. app.use( helmet({ contentSecurityPolicy: { directives: { "script-src": ["'self'", "example.com"], }, }, }) );

Headers can also be disabled. For example, here’s how you disable the

Content-Security-Policy

and

X-Download-Options

headers:


// This disables the Content-Security-Policy // and X-Download-Options headers. app.use( helmet({ contentSecurityPolicy: false, xDownloadOptions: false, }) );

Get started

Here’s a sample Express app that uses 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);

You can also

require("helmet")

if you prefer.

By default, Helmet sets the following headers:


  • Content-Security-Policy

    : A powerful allow-list of what can happen on your page which mitigates many attacks

  • Cross-Origin-Opener-Policy

    : Helps process-isolate your page

  • Cross-Origin-Resource-Policy

    : Blocks others from loading your resources cross-origin

  • Origin-Agent-Cluster

    : Changes process isolation to be origin-based

  • Referrer-Policy

    : Controls the

    Referer

    header

  • Strict-Transport-Security

    : Tells browsers to prefer HTTPS

  • X-Content-Type-Options

    : Avoids MIME sniffing

  • X-DNS-Prefetch-Control

    : Controls DNS prefetching

  • X-Download-Options

    : Forces downloads to be saved (Internet Explorer only)

  • X-Frame-Options

    : Legacy header that mitigates clickjacking attacks

  • X-Permitted-Cross-Domain-Policies

    : Controls cross-domain behavior for Adobe products, like Acrobat

  • X-Powered-By

    : Info about the web server. Removed because it could be used in simple attacks

  • X-XSS-Protection

    : Legacy header that tries to mitigate XSS attacks, but makes things worse, so Helmet disables it

Each header can be configured. For example, here’s how you configure the

Content-Security-Policy

header:


// This sets custom options for the // Content-Security-Policy header. app.use( helmet({ contentSecurityPolicy: { directives: { "script-src": ["'self'", "example.com"], }, }, }) );

Headers can also be disabled. For example, here’s how you disable the

Content-Security-Policy

and

X-Download-Options

headers:


// This disables the Content-Security-Policy // and X-Download-Options headers. app.use( helmet({ contentSecurityPolicy: false, xDownloadOptions: false, }) );

Helmet - Express.js Security with HTTP Headers
Helmet – Express.js Security with HTTP Headers

Không sử dụng những phiên bản có lỗi hoặc không được khuyến khích (deprecated)

Phiên bản mới nhất (hiện tại) của Express.js là 4.16.1, với rất nhiều tính năng cải tiến về tốc độ cũng như bảo mật; các phiên bản tiền nhiệm như Express 2.x hoặc Express 3.x cũng rất mạnh mẽ và được đánh giá cao, tuy nhiên các phiên bản cũ này đã không còn được hỗ trợ nữa. Điều đó có nghĩa là tất cả những vấn đề về hiệu năng hay bảo mật của Express 2.x và Express 3.x sẽ không còn được khắc phục nữa. Vậy nên nếu bạn đang làm một ứng dụng mới sử dụng Express.js thì hãy nên sử dụng phiên bản mới nhất; nếu bạn vẫn đang sử dụng Express.js cũ cho các ứng dụng của mình thì nên xem xét cập nhật lên Express 4 nếu có thể. Ngoài ra thì để đảm bảo phiên bản mình sử dụng không phải là phiên bản lỗi thì bạn cũng có thể kiểm tra danh sách các phiên bản có lỗi tại đây

Sử dụng Transport Layer Security (TLS)

Nếu ứng dụng của bạn có làm việc với những dữ liệu quan trọng, hãy sử dụng Transport Layer Security (TLS) để bảo mật các kết nối và dữ liệu của mình. Công nghệ này sẽ mã hóa dữ liệu trước khi nó được gửi đi từ client lên server, điều này sẽ giúp ngăn chặn một số kỹ thuật hacking phổ biến. Mặc dù với Ajax và Post requets thì có vẻ như dữ liệu truyền đi đã bị che dấu (chúng ta không nhìn thấy nó như với GET request), tuy nhiên thì trong thực tế chúng vẫn có thể bị tấn công bởi các công cụ hỗ trợ packet sniffing hoặc tấn công man-in-the-middle Mã hóa Secure Socket Layer (SSL) được sử dụng rất phổ biến và chắc hẳn bạn đã gặp nó rất nhiều rồi. TLS đơn giản chỉ là quá trình tiền theo của SSL. Nói theo một cách khác thì nếu bạn đã sử dụng SSL trước đó thì hãy nên xem xét để nâng cấp lên TLS, TLS có thể được cài đặt rất dễ dàng thông qua Nginx. Bạn có thể tìm hiểu về cấu hình TLS với Nginx tại đây Ngoài ra thì bạn nên thử Let’s Encrypt, đó là một công cụ miễn phí, tự động hoàn toàn với chứng chỉ xác thực được cung cấp bởi Internet Security Research Group (ISRG)

Node Express Tutorial 24 - Using third party middleware: morgan, helmet, & cors
Node Express Tutorial 24 – Using third party middleware: morgan, helmet, & cors

Getting Started

How to Inspect Your HTTP Headers

First, you should become comfortable inspecting HTTP traffic generated by your app. All modern browsers have a “Developer Tool” feature that lets you inspect network traffic requested by the browser. In this example, we’ll use Chrome. You can find Developer Tools from the Chrome menu:

Next, click on the “Network” tab and select an HTTP request made by the browser. Since I am testing on my local machine, I’ve clicked ‘localhost’.

Chances are your Express application isn’t using Helmet.js or securely configuring HTTP headers, so you may see something like this:

You’ll notice that none of the security headers listed in the table above appear in the image. In fact, we are leaking our use of Express! Fortunately, this is a quick fix with Helmet.js.

How to Install Helmet.js

First, use npm to download Helmet.js (we’re assuming you already have Express installed):


npm install helmet --save

Then, include it in your app:


var express = require('express'); var app = express(); var helmet = require('helmet'); app.use(helmet());

Helmet will now implement it’s default HTTP header configurations when you start your Express app! You should see the HTTP response headers look something like this:

Notice how Helmet.js disables the

X-Powered-By

header? Pretty cool 🙂

Want a demo of Veracode Interactive Analysis?

Veracode Interactive Analysis (IAST) helps teams instantly discover vulnerabilities in their applications at runtime by embedding security into their development processes and integrating directly into their CI/CD pipelines. Get a demo.

If you’ve ever delved into Node.js, then there’s a high chance that you’ll also encounter Express.js — a minimalist web framework built to create Node.js web applications. It comes with HTTP utilities for rapidly developing APIs and provides the foundations of other major and popular Node.js frameworks such as Feathers, LoopBack, Blueprint, and Nest.js.

While Express is generally robust for assisting your full stack application builds and prototypes, it is not perfect when it comes to security. The reason for this is because Express is designed for creating web applications — not securing your Node.js server from vulnerabilities. The defaults leave the HTTP headers mostly open, in part, to assist with the rapid application development. This is where Helmet.js steps in.

Helmet.js fills in the gap between Node.js and Express.js by securing HTTP headers that are returned by your Express apps. HTTP, by design, is open in nature and highly insecure. It can leak sensitive information about your app and leave your data open to anyone with some tech skills to see.

In short, using the preset default HTTP headers is a sure way to quickly get your app and running, but at the potential cost of anyone having access to it in a malicious way. What makes it worse is that because end users tend to be uneducated over the importance of HTTPS over HTTP, developers tend to ignore it unless otherwise forced to use HTTPS by their security policies.

In this article, we will go over how to install Helmet.js, what the different headers are, and how to use them in Helmet.js.

Reference


Content-Security-Policy

Default:

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

The

Content-Security-Policy

header mitigates a large number of attacks, such as cross-site scripting. See MDN’s introductory article on Content Security Policy.

This header is powerful but likely requires some configuration.

To configure this header, pass an object with a nested

directives

object. Each key is a directive name in camel case (such as

defaultSrc

) or kebab case (such as

default-src

). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.

// 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}’`], }, }, }), );

These directives are merged into a default policy, which you can disable by setting

useDefaults

to

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: [], }, }, }), );

You can get the default directives object with

helmet.contentSecurityPolicy.getDefaultDirectives()

. Here is the default policy (whitespace added for readability):


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

The

default-src

directive can be explicitly disabled by setting its value to

helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc

, but this is not recommended.

You can set the

Content-Security-Policy-Report-Only

instead.

// Sets the Content-Security-Policy-Report-Only header app.use( helmet({ contentSecurityPolicy: { directives: { /* … */ }, reportOnly: true, }, }), );

Helmet performs very little validation on your CSP. You should rely on CSP checkers like CSP Evaluator instead.

To disable the

Content-Security-Policy

header:

app.use( helmet({ contentSecurityPolicy: false, }), );

You can use this as standalone middleware with

app.use(helmet.contentSecurityPolicy())

.


Cross-Origin-Embedder-Policy

This header is not set by default.

The

Cross-Origin-Embedder-Policy

header helps control what resources can be loaded cross-origin. See MDN’s article on this header for more.

// 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” } }));

You can use this as standalone middleware with

app.use(helmet.crossOriginEmbedderPolicy())

.


Cross-Origin-Opener-Policy

Default:

Cross-Origin-Opener-Policy: same-origin

The

Cross-Origin-Opener-Policy

header helps process-isolate your page. For more, see 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” }, }), );

To disable the

Cross-Origin-Opener-Policy

header:

app.use( helmet({ crossOriginOpenerPolicy: false, }), );

You can use this as standalone middleware with

app.use(helmet.crossOriginOpenerPolicy())

.


Cross-Origin-Resource-Policy

Default:

Cross-Origin-Resource-Policy: same-origin

The

Cross-Origin-Resource-Policy

header blocks others from loading your resources cross-origin in some cases. For more, see “Consider deploying Cross-Origin Resource Policy and 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” } }));

To disable the

Cross-Origin-Resource-Policy

header:

app.use( helmet({ crossOriginResourcePolicy: false, }), );

You can use this as standalone middleware with

app.use(helmet.crossOriginResourcePolicy())

.


Origin-Agent-Cluster

Default:

Origin-Agent-Cluster: ?1

The

Origin-Agent-Cluster

header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about it in the spec.

This header takes no options and is set by default.

// Sets “Origin-Agent-Cluster: ?1” app.use(helmet());

To disable the

Origin-Agent-Cluster

header:

app.use( helmet({ originAgentCluster: false, }), );

You can use this as standalone middleware with

app.use(helmet.originAgentCluster())

.


Referrer-Policy

Default:

Referrer-Policy: no-referrer

The

Referrer-Policy

header which controls what information is set in the

Referer

request header. See “Referer header: privacy and security concerns” and the header’s documentation on MDN for more.

// Sets “Referrer-Policy: no-referrer” app.use(helmet());


policy

is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when setting a fallback policy. It defaults to

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”], }, }), );

To disable the

Referrer-Policy

header:

app.use( helmet({ referrerPolicy: false, }), );

You can use this as standalone middleware with

app.use(helmet.referrerPolicy())

.


Strict-Transport-Security

Default:

Strict-Transport-Security: max-age=15552000; includeSubDomains

The

Strict-Transport-Security

header tells browsers to prefer HTTPS instead of insecure HTTP. See the documentation on MDN for more.

// Sets “Strict-Transport-Security: max-age=15552000; includeSubDomains” app.use(helmet());


maxAge

is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to

15552000

, which is 180 days.


includeSubDomains

is a boolean which dictates whether to include the

includeSubDomains

directive, which makes this policy extend to subdomains. It defaults to

true

.


preload

is a boolean. If true, it adds the

preload

directive, expressing intent to add your HSTS policy to browsers. See the “Preloading Strict Transport Security” section on MDN for more. It defaults to

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, }, }), );

To disable the

Strict-Transport-Security

header:

app.use( helmet({ strictTransportSecurity: false, }), );

You can use this as standalone middleware with

app.use(helmet.strictTransportSecurity())

.


X-Content-Type-Options

Default:

X-Content-Type-Options: nosniff

The

X-Content-Type-Options

mitigates MIME type sniffing which can cause security issues. See documentation for this header on MDN for more.

This header takes no options and is set by default.

// Sets “X-Content-Type-Options: nosniff” app.use(helmet());

To disable the

X-Content-Type-Options

header:

app.use( helmet({ xContentTypeOptions: false, }), );

You can use this as standalone middleware with

app.use(helmet.xContentTypeOptions())

.


X-DNS-Prefetch-Control

Default:

X-DNS-Prefetch-Control: off

The

X-DNS-Prefetch-Control

header helps control DNS prefetching, which can improve user privacy at the expense of performance. See documentation on MDN for more.

// Sets “X-DNS-Prefetch-Control: off” app.use(helmet());


allow

is a boolean dictating whether to enable DNS prefetching. It defaults to

false

.

Examples:

// Sets “X-DNS-Prefetch-Control: off” app.use( helmet({ xDnsPrefetchControl: { allow: false }, }), ); // Sets “X-DNS-Prefetch-Control: on” app.use( helmet({ xDnsPrefetchControl: { allow: true }, }), );

To disable the

X-DNS-Prefetch-Control

header and use the browser’s default value:

app.use( helmet({ xDnsPrefetchControl: false, }), );

You can use this as standalone middleware with

app.use(helmet.xDnsPrefetchControl())

.


X-Download-Options

Default:

X-Download-Options: noopen

The

X-Download-Options

header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site’s context. For more, see this old post on MSDN.

This header takes no options and is set by default.

// Sets “X-Download-Options: noopen” app.use(helmet());

To disable the

X-Download-Options

header:

app.use( helmet({ xDownloadOptions: false, }), );

You can use this as standalone middleware with

app.use(helmet.xDownloadOptions())

.


X-Frame-Options

Default:

X-Frame-Options: SAMEORIGIN

The legacy

X-Frame-Options

header to help you mitigate clickjacking attacks. This header is superseded by the

frame-ancestors

Content Security Policy directive but is still useful on old browsers or if no CSP is used. For more, see the documentation on MDN.

// Sets “X-Frame-Options: SAMEORIGIN” app.use(helmet());


action

is a string that specifies which directive to use—either

DENY

or

SAMEORIGIN

. (A legacy directive,

ALLOW-FROM

, is not supported by Helmet. Read more here.) It defaults to

SAMEORIGIN

.

Examples:

// Sets “X-Frame-Options: DENY” app.use( helmet({ xFrameOptions: { action: “deny” }, }), ); // Sets “X-Frame-Options: SAMEORIGIN” app.use( helmet({ xFrameOptions: { action: “sameorigin” }, }), );

To disable the

X-Frame-Options

header:

app.use( helmet({ xFrameOptions: false, }), );

You can use this as standalone middleware with

app.use(helmet.xFrameOptions())

.


X-Permitted-Cross-Domain-Policies

Default:

X-Permitted-Cross-Domain-Policies: none

The

X-Permitted-Cross-Domain-Policies

header tells some clients (mostly Adobe products) your domain’s policy for loading cross-domain content. See the description on OWASP for more.

// Sets “X-Permitted-Cross-Domain-Policies: none” app.use(helmet());


permittedPolicies

is a string that must be

"none"

,

"master-only"

,

"by-content-type"

, or

"all"

. It defaults to

"none"

.

Examples:

// 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”, }, }), );

To disable the

X-Permitted-Cross-Domain-Policies

header:

app.use( helmet({ xPermittedCrossDomainPolicies: false, }), );

You can use this as standalone middleware with

app.use(helmet.xPermittedCrossDomainPolicies())

.


X-Powered-By

Default: the

X-Powered-By

header, if present, is removed.

Helmet removes the

X-Powered-By

header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (see this discussion) and is mostly removed to save bandwidth, but may thwart simplistic attackers.

Note: Express has a built-in way to disable the

X-Powered-By

header, which you may wish to use instead.

The removal of this header takes no options. The header is removed by default.

To disable this behavior:

// 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, }), );

You can use this as standalone middleware with

app.use(helmet.xPoweredBy())

.


X-XSS-Protection

Default:

X-XSS-Protection: 0

Helmet disables browsers’ buggy cross-site scripting filter by setting the legacy

X-XSS-Protection

header to . See discussion about disabling the header here and documentation on MDN.

This header takes no options and is set by default.

To disable the

X-XSS-Protection

header:

// This is not recommended. app.use( helmet({ xXssProtection: false, }), );

You can use this as standalone middleware with

app.use(helmet.xXssProtection())

.

Helmet helps secure Express apps by setting HTTP response headers.

Content-Security-Policy in NodeJS/Express
Content-Security-Policy in NodeJS/Express

Keywords searched by users: helmet in node js

Express Helmet Js: The Must-Have Seatbelt For A Secure Node.Js Application
Express Helmet Js: The Must-Have Seatbelt For A Secure Node.Js Application
23 Node Js Developer | Helmet & Morgan - Youtube
23 Node Js Developer | Helmet & Morgan – Youtube
Helmet.Js | Secure Node.Js And Express.Js App/Api - Youtube
Helmet.Js | Secure Node.Js And Express.Js App/Api – Youtube
Các Cách Bảo Mật Ứng Dụng Node.Js - Quantrimang.Com
Các Cách Bảo Mật Ứng Dụng Node.Js – Quantrimang.Com
How To Configure Meta Tags In React Apps Dynamically With A Nodejs Server -  Dillion'S Blog
How To Configure Meta Tags In React Apps Dynamically With A Nodejs Server – Dillion’S Blog
Express Helmet Js: The Must-Have Seatbelt For A Secure Node.Js Application
Express Helmet Js: The Must-Have Seatbelt For A Secure Node.Js Application
Helmet - Node.Js & Mongodb Tips 04 - Youtube
Helmet – Node.Js & Mongodb Tips 04 – Youtube
Các Cách Bảo Mật Ứng Dụng Node.Js - Quantrimang.Com
Các Cách Bảo Mật Ứng Dụng Node.Js – Quantrimang.Com
Một Số Lưu Ý Cho Ứng Dụng Node.Js An Toàn Hơn - Tma Tech Group
Một Số Lưu Ý Cho Ứng Dụng Node.Js An Toàn Hơn – Tma Tech Group
Một Số Lưu Ý Cho Ứng Dụng Node.Js An Toàn Hơn
Một Số Lưu Ý Cho Ứng Dụng Node.Js An Toàn Hơn
React Helmet: When To Use And When To Avoid Using It For Your Website
React Helmet: When To Use And When To Avoid Using It For Your Website

See more here: kientrucannam.vn

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *