In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "how to improve the security of Node.js applications". In daily operation, I believe many people have doubts about how to improve the security of Node.js applications. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "how to improve the security of Node.js applications". Next, please follow the editor to study!
1. Data validation-never trust your users
You have to validate data from user input or other systems. Otherwise, this will pose a threat to the current system and lead to unimaginable security vulnerabilities. Now, let's learn how to validate incoming data in Node.js. You can use a module called validator to perform data validation. For example:
Const validator = require ('validator'); validator.isEmail (' foo@bar.com'); / / = > true validator.isEmail ('bar.com'); / / = > false
In addition, you can also use the joi module to validate data and models, such as:
Const joi = require ('joi'); try {const schema = joi.object (). Keys ({name: joi.string (). Min (3) .max (45). Required (), email: joi.string (). Email (). Required (), password: joi.string (). Min (6) .max (20). Required ()}) Const dataToValidate = {name: "Shahid", email: "abc.com", password: "123456",} const result = schema.validate (dataToValidate); if (result.error) {throw result.error.details [0] .message;}} catch (e) {console.log (e);}
2. SQL injection attack
SQL injection allows malicious users to tamper with SQL statements by passing illegal parameters. Here is an example, suppose you write a SQL like this:
UPDATE users SET first_name= "'+ req.body.first_name +'" WHERE id=1332
Under normal circumstances, you want this query to look like this:
UPDATE users SET first_name = "John" WHERE id = 1332
But now, if someone passes the value of first_name as follows:
John ", last_name=" Wick ";
At this point, your SQL statement will look like this:
UPDATE users SET first_name= "John", last_name= "Wick";-- "WHERE id=1001
You will see that the WHERE condition has been commented out, and this update will change the first_name of all users in the entire table to John and last_name to Wick. Now, you're in trouble!
How to avoid SQL injection
The most effective way to avoid SQL injection attacks is to filter the input data. You can validate each input data one by one, or you can validate it by parameter binding. The most commonly used method for developers is parameter binding because it is efficient and secure.
If you are using some of the more popular ORM frameworks, such as sequelize, hibernate, etc., then this data validation and SQL injection protection mechanism is already provided in the framework.
If you prefer to rely on database modules, such as mysql for Node, then you can use the filtering methods provided by the database. The following code is an example of using mysql for Node:
Var mysql = require ('mysql'); var connection = mysql.createConnection ({host:' localhost', user: 'me', password:' secret', database: 'my_db'}); connection.connect (); connection.query (' UPDATE users SET? =? WHERE? =?', ['first_name',req.body.first_name,' id',1001], function (err, result) {/ /...})
?? Is replaced by the field name,? Is replaced by the field value, which ensures the security of the input value.
You can also use stored procedures to improve security, but developers tend to avoid using stored procedures because of the lack of maintainability.
At the same time, you should also perform server-side data validation. However, I do not recommend that you validate each field manually. You can use modules such as joi to solve this problem.
Type conversion
JavaScript is a dynamically typed language, that is, values can be of any type. You can use type conversion to verify the type of data, which ensures that only data of a specified type can enter the database. For example, the user ID can only be a numeric type, see the following code:
Var mysql = require ('mysql'); var connection = mysql.createConnection ({host:' localhost', user: 'me', password:' secret', database: 'my_db'}); connection.connect (); connection.query (' UPDATE users SET? =? WHERE? =?', ['first_name',req.body.first_name,' id',Number (req.body.ID)], function (err, result) {/ /...})
Have you noticed the change? Here we use the Number (req.body.ID) method to ensure that the user ID must be numeric.
3. Application authentication and authorization
Sensitive data, such as passwords, should be stored in the system in a secure manner so that malicious users do not abuse sensitive information. In this section, we will learn how to store and manage common passwords, and almost every application has a different way of storing passwords in its system.
Password hash
A hash is a function that generates a fixed-size string of input values. The output value of the hash function cannot be decrypted, so it can be said to be "one-way". Therefore, for data such as passwords, the values stored in the database must be hashes, not plaintext.
You may wonder, since hashing is an irreversible form of encryption, how does an attacker gain password access?
As I mentioned above, hash encryption uses an input string and generates a fixed-length output value. As a result, attackers take the opposite approach by generating a hash from the regular password list and then comparing the hash with the hash in the system to find the password. This kind of attack is called Lookup Tables.
This is why, as a system architect, you will never allow simple universal passwords to be used in your system. To avoid attacks, you can also use something called "salt", which we call the "Hashgar salt method". Append salt to the password hash, making the input value unique. Salt values must be random and unpredictable. We recommend that you use the hash algorithm BCrypt, in Node.js, you can use the bcyrpt node module to perform hashing.
Please refer to the code in the following example:
Const bcrypt = require ('bcrypt'); const saltRounds = 10; const password = "Some-Password@2020"; bcrypt.hash (password, saltRounds, (err, passwordHash) = > {/ / we will just print it to the console for now / / you should store it somewhere and never logs or print it console.log ("Hashed Password:", passwordHash);})
The SaltRounds function is the cost of the hash function. The higher the cost, the more secure the generated hash password. You should determine the salt value according to the computing power of the server. After the hash value of the password is generated, the password entered by the user will be compared with the hash value stored in the database. The reference code is as follows:
Const bcrypt = require ('bcrypt'); const incomingPassword = "Some-Password@2020"; const existingHash = "some-hash-previously-generated" bcrypt.compare (incomingPassword, existingHash, (err, res) = > {if (res & & res = true) {return console.log ("Valid Password");} / / invalid password handling here else {console.log ("Invalid Password") })
Password storage
Whether you use a database or a file to store passwords, you cannot use plaintext storage. As we learned in the previous section, you can hash the password and store it in the database. I recommend using the varchar data type for password fields, or you can choose fields of unlimited length. If you are using bcrypt, you can use the varchar (60) field type because bcrypt generates a hash of a fixed length of 60 characters.
Authentication and authorization
A system with appropriate role permissions will prevent some malicious users from doing some ultra vires in the system. In order to implement the correct authorization process, assign the appropriate roles and permissions to each user so that they can perform certain tasks within the scope of their permissions. In Node.js, you can use the famous ACL module to develop access control lists according to the authorization in the system.
Const ACL = require ('acl2'); const acl = new ACL (new ACL.memoryBackend ()); / / guest is allowed to view blogs acl.allow (' guest', 'blogs',' view') / / check if the permission is granted acl.isAllowed ('joed',' blogs', 'view', (err, res) = > {if (res) {console.log ("User joed is allowed to view blogs");}})
Check the acl2 documentation for more information and sample code.
4. Protection against violent attacks
Hackers often use software to repeatedly use different passwords to try to gain system permissions until they find a valid password, which is called a brute force attack. A simple and effective way to avoid this attack is to "ask him to wait a minute", that is, when someone tries to log in to the system and try to enter an invalid password more than three times, ask them to wait about 60 seconds before trying again. In this way, attackers will greatly increase the cost of time and will make it impossible for them to crack passwords.
Another way to prevent this attack is to shield IP from invalid login requests. The system allows 3 incorrect login attempts per IP within 24 hours. If someone tries to crack it by force, their IP will be blocked for 24 hours. Many companies have used this method to prevent violent attacks. If you use the Express framework, there is a middleware module that enables rate limiting in incoming requests. It is called express = brute.
Here is an example.
Install dependencies
Npm install express-brute-save
Enable it in the route
Const ExpressBrute = require ('express-brute'); const store = new ExpressBrute.MemoryStore (); / / stores state locally, don't use this in production const bruteforce = new ExpressBrute (store); app.post (' / auth', bruteforce.prevent, / / error 429 if we hit this route too often function (req, res, next) {res.send ('success');}); / /.
5. HTTPS secure transmission
Now that it's 2021, you should also use HTTPS to send data to the network. HTTPS is an extension of the HTTP protocol with secure communication support. Using HTTPS, you can ensure that the data sent by users on the Internet is encrypted and secure.
I'm not going to elaborate on how the HTTPS protocol works here, we'll just discuss how to use it. Here I highly recommend using LetsEncrypt to generate security certificates for all your domain names.
You can use LetsEncrypt on Apache and Nginx-based Web servers. I strongly recommend that you use the HTTPS protocol at the reverse proxy or gateway layer because they have a lot of onerous computing operations.
6. Session hijacking protection
Session is the most important part of any dynamic Web application, and a secure session is really necessary for users and systems. Sessions are implemented using Cookie, so they must be secured to prevent session hijacking. The following is a list of properties that can be set for each cookie and what they mean:
Secure-this property tells the browser to send the cookie only when the request is sent through HTTPS.
HttpOnly-this attribute is used to prevent cross-site scripting attacks because it does not allow access to cookie through JavaScript.
Domain-this attribute is used to compare with the server domain name that requested URL, and if the domain name matches, or its subdomain, then the path attribute is checked.
Path-in addition to domian, you can also specify a valid URL path for cookie. If the domain and path match, you can send the cookie in the request.
Expires-the cookie,cookie that this property uses to set persistence expires only when the set date is exceeded.
In the Express framework, you can use the express-session npm module to manage sessions.
Const express = require ('express'); const session = require (' express-session'); const app = express (); app.use ({secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: {secure: true, path:' /'}}))
7. Cross-site request forgery attack (CSRF) protection
Cross-site request forgery attacks take advantage of trusted users in the system to perform harmful and malicious operations on Web applications. In Node.js, we can use the csurf module to mitigate CSRF attacks. The module needs to initialize express-session or cookie-parser first. You can take a look at the following sample code:
Const express = require ('express'); const cookieParser = require (' cookie-parser'); const csrf = require ('csurf'); const bodyParser = require (' body-parser'); / / setup route middlewares const csrfProtection = csrf ({cookie: true}); const parseForm = bodyParser.urlencoded ({extended: false}); / / create express app const app = express (); / / we need this because "cookie" is 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');}); app.listen (3000)
On the web page, you need to create a hidden input field and save the CSRF token in that input field, for example:
Favorite color: Submit
If you are using an AJAX request, the CSRF token can be passed through the request header (header).
Var token = document.querySelector ('meta [name = "csrf-token"]'). GetAttribute ('content'); headers: {' CSRF-Token': token}
8. Denial of service
A denial of service or DOS attack can allow an attacker to destroy the system and force the system to shut down or prevent users from accessing the service. Attackers usually send a large amount of traffic and requests to the system, thus increasing the server CPU and memory load, causing the system to crash. To mitigate DOS attacks in Node.js applications, the first step is to identify such events, and I strongly recommend integrating these two modules into the system.
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Account lockout-after n failed attempts, lock the account or IP address for a period of time (e.g. 24 hours?)
Rate limiting-restricts users to request the system only n times in a specific period of time, for example, a single user can only request 3 times per minute.
Regular expression denial of service (ReDOS) attack is a kind of DOS attack. The attacker takes advantage of the design defects or computational complexity of regular expressions in the system to consume a large amount of system resources of the server, resulting in service interruption or suspension of the server.
We can use some tools to check for risky regular expressions to avoid the use of these regular expressions. For example, this tool:
Https://github.com/davisjam/vuln-regex-detector
9. Dependency verification
We all use a large number of dependencies in our projects. We also need to check and verify these dependencies to ensure the security of the entire project. NPM already has such an audit function to find vulnerabilities in the project. Simply run the following command from the source code directory:
Npm audit
To fix the vulnerability, you can run this command:
Npm audit fix
You can also dry run to check for fixes before applying them to the project.
Npm audit fix-dry-run-json
10. HTTP security header information
HTTP provides some security header information to prevent common attacks. If you are using the Express framework, you can use the helmet module, which enables all security headers in 1 line of code.
Npm install helmet-save
Here's a look at how to use:
Const express = require ("express"); const helmet = require ("helmet"); const app = express (); app.use (helmet ()); / /.
This enables the following HTTP headers:
Strict-Transport-Security
X-frame-Options
X-XSS-Protection
X-Content-Type-Protection
Content-Security-Policy
Cache-Control
Expect-CT
Disable X-Powered-By
These HTTP headers can prevent a variety of attacks from malicious users, such as click hijacking, cross-site scripting attacks and so on.
At this point, the study on "how to improve the security of Node.js applications" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.