node. JS Security Checklist

Source: Internet
Author: User

Objective

Security is always a problem that cannot be ignored. Many people admit it, but few people really take it seriously. So we've listed this list so that you can do a security check before deploying your app to a production environment for tens of thousands of users.

Most of the security items listed below are universal and apply to a Node.js wide range of languages and frameworks, in addition to the outside. However, it also contains some Node.js small tools for writing.

Configure administrative security-related HTTP headers

Here are some security-related HTTP headers that your site should set up:

    • Strict-Transport-Security: Force the use of a secure connection (HTTPS over SSL/TLS) to connect to the server.

    • X-Frame-Options: Provides protection for "click Hijacking".

    • X-XSS-Protection: Opens most modern browser-built filtering capabilities for cross-site scripting attacks (XSS).

    • X-Content-Type-Options: Prevent the browser from using MIME-sniffing to determine the type of response, instead use explicit content-type to determine.

    • Content-Security-Policy: Prevents cross-site scripting attacks and other cross-site injection attacks.

In Node.js , these can be easily set up by using the helmet module:

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

Helmetcan also be used in KOA: Koa-helmet.

Of course, in many architectures, these headers are set in the configuration of the Web server (Apache,nginx), not in the code of the application. If it is configured via Nginx, the configuration file will resemble the following example:

# nginx.confadd_header X-Frame-Options SAMEORIGIN;  add_header X-Content-Type-Options nosniff;  add_header X-XSS-Protection "1; mode=block"; add_header Content-Security-Policy "default-src ‘self‘"; 

A complete example can be referred to this nginx configuration.

If you want to quickly confirm whether your site is set up with these HTTP headers, you can check online through this website: http://cyh.herokuapp.com/cyh.

Sensitive data for clients

When deploying a front-end application, make sure that you do not expose sensitive data such as keys in your code, which can be seen by everyone.

There is no automated way to detect them today, but there are some ways to reduce the chance of accidentally exposing sensitive data to the client:

    • Using the pull request Update code

    • Set up a code review mechanism

Identity authentication for brute force protection

Brute force is a systematic enumeration of all possible outcomes and attempts to find the right answer. In the Web application, the user login is particularly suitable for it to play.

You can prevent this type of attack by limiting the user's connection frequency. In Node.js , you can use the Ratelimiter package.

var email = req.body.email;  var limit = new Limiter({ id: email, db: db });limit.get(function(err, limit) {});

Of course, you can encapsulate it as a middleware for your application to use. Expressand Koa both already have good middleware ready for you:

var ratelimit =Require' Koa-ratelimit ');var Redis =Require' Redis ');var KOA =require ( ' koa '); var app = Koa (); var emailbasedratelimit = Ratelimit ({db:redis.createClient (), Duration: 60000, Max: 10, ID:  function return Context.body.email;}); var ipbasedratelimit = Ratelimit ({db:redis.createClient (), Duration: 60000, Max: 10, ID:  function return Context.ip;}); App.post ( '/login ', Ipbasedratelimit, Emailbasedratelimit, handlelogin);    

What we do here is limit the number of times a user can try to log in for a given period of time-which reduces the risk of brute-force user passwords being hacked. The options in the example above can be changed according to your actual situation, so don't simply copy and paste them.

If you want to test the performance of your service in these scenarios, you can use Hydra.

Session Management

The importance of the safe use of cookies is self-evident. Especially for dynamic Web applications, they need to use cookies to maintain state on top of stateless protocols such as HTTP.

Cookie Marking

The following is a list of properties that each cookie can set, and what they mean:

    • Secure-This property tells the browser that a cookie is passed only when the request is transmitted over HTTPS.

    • HttpOnly-Setting this property will prohibit the javascript script from acquiring this cookie, which can be used to help prevent cross-site scripting attacks.

Cookie Domain
    • Domain-This property is used to compare the domain name of the server in the request URL. If the domain name matches successfully, or if this is its subdomain, continue checking the path properties.

    • Path-the URL path available for a cookie can also be specified in addition to the domain name. When the domain name and path match, the cookie is sent with the request.

    • Expires-this property is used to set persistent cookie, and after setting it, the cookie will not expire until the specified time arrives.

In Node.js , you can use cookies to easily create cookies. However, it is lower-level. When you create an app, you may be more likely to use some of its footprints, such as cookie-session.

var cookieSession = require(‘cookie-session‘);  var express = require(‘express‘);var app = express();app.use(cookieSession({ name: ‘session‘, keys: [ process.env.COOKIE_KEY1, process.env.COOKIE_KEY2 ]}));app.use(function (req, res, next) { var n = req.session.views || 0; req.session.views = n++; res.end(n + ‘ views‘);});app.listen(3000); 

(The above example is taken from the documentation for the Cookie-session module)

Csrf

Cross-site request forgery (CSRF) is a means of forcing users to perform an attack on a Web application that they have logged in to do something that is not what they intended to do. This attack is often used for requests that change the state of a user, usually without stealing data, because the attacker does not see the content of the response.

In Node.js , you can use the CSRF module to mitigate this attack. It's also very low-level, and you might prefer to use middleware like Csurf Express .

In the routing layer, you can have the following code:

var cookieparser =Require' Cookie-parser ');var csrf =Require' Csurf ');var bodyparser =Require' Body-parser ');var Express =Require' Express ');Setup Route Middlewaresvar csrfprotection = csrf ({cookie:true});var parseform = bodyparser.urlencoded ({extended: false}); Span class= "Hljs-comment" >//create Express app var app = Express (); //We need this because" cookies "are true in Csrfprotection App.use (Cookieparser ()); App.get (/form ', csrfprotection, function (req, res) {//pass the Csrftoken to the View Res.render ( ' send ', {CsrfToken:req.csrfToken ()});}); App.post ( '/process ', Parseform, csrfprotection, function (req, res) {res.send ( ' data is being Processed ');                

In the presentation layer, you need to use CSRF token :

<form action="/process" method= "POST" > < Input type= "hidden" name=< Span class= "Hljs-value" > "_csrf" value= "{{Csrftoken}}" > Favorite Color: <input type= "text" name= "FavoriteColor" > <button type=  "submit" >submit</button>< Span class= "Hljs-tag" ></form>         

(The above example is taken from the documentation for the Csurf module)

Data legality XSS

Here are two similar, but slightly different ways of attacking, one about cross-site scripting and the other on storage.

    • A non-persisted XSS attack occurs when an attacker injects executable code into the response HTML of a specified URL JavaScript .

    • Persistent XSS attacks occur when an application stores unfiltered user input. The code entered by the user will be executed in your application environment.

To defend against such attacks, make sure that you always check and filter the user's input.

SQL injection

SQL injection is likely to occur when a user's input contains partial or complete SQL query statements. It may read sensitive data, or delete data directly.

For example:

select title, author from books where id=$id  

In this example, it $id comes from the user input. User input 2 or 1=1 is also possible. This query may become:

select title, author from books where id=2 or 1=1 

The simplest way to prevent this is to use a parameterized query (parameterized queries) or a preprocessing statement (prepared statements).

If you are Node.js using PostgreSQL . Then you can use the Node-postgres module to create a parameterized query:

var q = ‘SELECT name FROM books WHERE id = $1‘;  client.query(q, [‘3‘], function(err, result) {}); 
Command injection

An attacker uses command injection to run system commands on a remote Web server. With command injection, an attacker could even get the system's password.

In practice, if you have a URL:

https://example.com/downloads?file=user1.txt  

It can become:

https://example.com/downloads?file=%3Bcat%20/etc/passwd  

In this case, it %3B becomes a semicolon. Therefore, multiple system commands will be run.

To prevent such attacks, make sure that the user's input is always checked for filtering.

We can also take Node.js the point of view:

child_process.exec(‘ls‘, function (err, data) {      console.log(data);});

At child_process.exec the bottom, it is called /bin/sh , so it is an bash interpreter, and not just a user program can be executed.

When the user's input is an anti-quote or, it is $() dangerous to pass them on to this method.

Can be used child_process.execFile to solve the above problem.

Secure transfer of SSL version, algorithm, key length

Because HTTP is transmitted in plaintext, we need to encrypt it through a SSL/TLS channel, which is HTTPS. Today's high-level encryption is generally used, but if the server lacks configuration, it can also result in low-level encryption or non-encryption on the server.

You need to test:

    • passwords, keys, and renegotiation (renegotiation) are all legally and properly configured.

    • The legality of the certificate.

Using tools like this nmap sslyze can make the job very simple.

Check certificate information
nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995 www.example.com

Use sslyze to check SSL/TSL:

--regular example.com:443
HSTS

In the Configuration Management section above we have already contacted them-the Strict-Transport-Security header enforces the use of HTTPS to connect to the server. Here is an example of Twitter:

strict-transport-security:max-age=631138519  

This defines the number of seconds that the max-age browser needs to automatically convert all HTTP requests to HTTPS.

The test for it is very simple:

curl -s -D- https://twitter.com/ | grep -i Strict  
Denial of service Account lockout

Account lockout is used to mitigate the denial of service impact caused by brute force. In practice, it means that when a user attempts a few landings and fails, he or she will be barred from logging in for a later period.

You can use the previous mentioned rate-limiter to block this type of attack.

Regular expressions

This type of attack is mainly due to some regular expressions that, in extreme cases, can become performance and bad. These are called Demonic Evil regexes:

    • To group repeating text

    • Duplicate content within a repeating group

      ([a-zA-Z]+)*, (a+)+ or (a|a?)+ in the aaaaaaaaaaaaaaaaaaaaaaaa! face of such input, are fragile. This can cause a lot of computation. For more details, refer to Redos.

You can use the Node.js tool Safe-regex this to detect your regular:

‘(beep|boop)*‘true  $ node safe.js ‘(a+){10}‘false  
Error handling error code, stack information

Some error scenarios can lead to application disclosure of underlying application schema information, such as: like: X-Powered-By:Express .

Stack information may not be useful in itself, but it often leaks information that is of great interest to attackers. It is a very bad practice to return stack information. You need to record them in the log instead of showing them to the user.

Npm

Stronger capacity means greater responsibility-NPM has many packages that can be used out of the box, but at the cost: you need to check if there are security issues with the packages themselves.

Fortunately Node Security project (NSP) is a great tool to check if the module you are using is susceptible to attack by some known means.

npm i nsp -g  # either audit the shrinkwrapnsp audit-shrinkwrap  # or the package.jsonnsp audit-package  
At last

This checklist is primarily based on the OWASP maintenance of Web application Security testing Cheat sheet.

node. JS Security Checklist

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.