Application SecurityTech

Secure Coding practices for JavaScript

JavaScript is one of the most used programming languages for the development of web applications, becoming increasingly common in mobile applications. According to Stack Overflow, nearly 70% of developers use JavaScript. In this article, we explore some of the secure coding practices for JavaScript, highlighting the role of developers as protagonists in preventing vulnerabilities and potential threats to their software.

You can also listen to this article:

Its popularity makes Javascript one of the prime targets for cyber criminals. The organization Secure Coding shows that JavaScript ranks fourth in the list of the most vulnerable programming languages, behind only Java, PHP and C.

It is essential that devs who use this language in their daily development are proactive in adopting security and protection measures for the application code.

Summary of how JavaScript works

JavaScript is a memory management language. That is, when creating functions, variables, strings, the engine allocates a certain amount of memory and frees it when it is no longer needed. JavaScript does this process automatically for you!

Thus, when the reservation is released (Release), the memory can be used for other purposes. For this purpose, there is a garbage collector that in the background reclaims the allocated memory. So this garbage collector removes some objects when they become inaccessible.

This memory lifecycle in JavaScript prevents you from encountering the classic buffer overflow problems like in C and C++ languages. However, there are many ways that code written in this language can be vulnerable to very common attacks like SQL Injection and Cross-Site Scripting.

Prevent Cross-Site Scripting (XSS) Attacks

Cross-site scripting (XSS) occurs when an attacker injects malicious code into the client side of a web application, usually in the form of a browser script. The flaws allow the browser to accept this untrusted data without properly validating it, making it possible for the attacker to be able to access any cookies, session tokens or other sensitive information held by the browser and used with that website.

To avoid this type of threat, we recommend the following practices:

Always validate and clear user input.

This ensures that it contains only acceptable characters that cannot be used to initiate XSS-type attacks.

Use securemethods like innerText instead of innerHTML

To manipulate the Document Object Model (DOM), use secure methods like innerText instead of innerHTML, avoiding DOM-based XSS. InnerHTML is usually used for inserting tags, texts and images in a web page, creating a security risk, for this reason, innerHTML is not used for insertion of plain text.

Understanding in practice through the following example, creating a property:

Example using innerHTML:

Result using innerHTML:

Example using innerText:

The result using innerText:

In short, innerText retrieves and sets the tag content as plain text, while innerHTML retrieves and sets the content in HTML format.

Utilize frameworks and functions that help prevent XSS attacks

Node.Js, a packaged compilation of Google’s V8 JavaScript engine, has the encodeURI and encodeURIComponent global functions that can help you with this. Also, it is important to consider using packages like XSS-Filters.

It is secure to apply these filters like this:

document.write(“<a href=” + xssFilters.uriInUnQuotedAttr(url) + “>” + xssFilters.uriInHTMLData(url) + “</a>”);

XSS filters are primarily designed based on the HTML 5 specification. The principle is to escape specific characters for each non-programmable output context.

On the server side (Node.js), install xss-filters npm and include it as a dependency for your project:

npm install xss-filters –save

In the XSS-Filters repository there are more advanced tutorials, as well as explaining how to install it on the client side (browser).

Prevent SQL Injection attacks

A SQL Injection attack consists of “injecting” an SQL query through customer input data into the application. A successful exploit allows the attacker to read sensitive data from the database as well as modify it.

In the case of Javascript, SQL databases are vulnerable to this type of attack if the query parameters are easily exploited by executing arbitrary statements.

To avoid this type of threat, we recommend the following practices:

Validate user input appropriately

Let’s see this example of the use of the Express.Js framework (or just Express), one of the most used together with Node.Js, in the presentation of a vulnerability for this type of attack:

In this case, the application gets user IDs from this URL and retrieves the corresponding email address by querying the database, as there are two holes in this code snippet:

The first one is that the database query was built using string concatenation.

The second issue is where user input is concatenated to the query instead of being treated as untrusted data.

An attacker could create a query string ID parameter so that he can access all tables in the application’s database. By entering, for example, these string parameters:

Resulting in the following query:

A successful query will provide the attacker with a list of all tables in the database. Therefore, to mitigate SQL Injection, developers need to always perform proper input validation, because if the validation check fails, the SQL query will not be executed.

Use parameterized queries or prepared statements instead of concatenations

In this case, parameterized queries serve to abstract the SQL syntax from the input parameters. The example in Node.Js below shows the code for an authorization, where the username and password will come out of the HTTP request. The sqlQuery contains a query that was created to authenticate the input credentials. The SQL query is executed on line 7 as you can see:

 Link for GitHub.

The problem in this code is the SQL query and the lack of sanitization of username and password entries. In this case, a prepared statement or parameterized query should be used instead of concatenation. A prepared statement serves to abstract SQL syntax from any input parameters.

Example using prepared statement:

 Link for GitHub.

To understand more about prepared statements in JavaScript, check out this document.

Be critical of third-party components

Applications of this language are highly dependent on third-party libraries. And these components may also contain vulnerabilities or content with dubious intent, affecting the security of your application.

Always inspect third-party libraries for vulnerabilities:

Add integrity code to your application

Working on the front-end, it is likely that you have used <scripts> tags to import third-party libraries. But what if the resource has been tampered with? This is something that can happen when you render external resources to your web application, causing your application to lose security.

To deal with this situation, you can add an integrity code, known as Subresource Integrity (SRI) for browsers to verify that the resources, such as Content Delivery Network (CDNs) that they seek, are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

It is worth remembering that, before evaluating if it has been tampered with, b.

Update NPM package versions

If you see a symbol like ^or ~ in any version of the NPM package, it means that there is an automatic version for minor and patch versions.

Enabling the update of these packages will help reduce security risks.

Use some package manager

Tracking all the packages you are using in your web application can help you keep third-party vulnerabilities at bay.

You can accomplish this through a package manager such as npm, Yarn, or pnpm. In addition to managing, they also provide tools to audit your packages and help you find common JavaScript security issues.

The importance Secure Coding training for developers

There are many other common JavaScript security issues that can increase the risk to your application. In addition, new vulnerabilities are always emerging and, therefore, developers need to be up to date and aware of these secure coding techniques.

When we look at a designed development process, we identify that the first step is training and capacity building in this type of skill.

It is clear that this type of activity is essential to the Secure Development process. With the People & Culture – the Education module of the Conviso Platform, it is possible to perform technical exercises in secure coding in JavaScript and many other languages.

Through People & Culture, you can solve real-world security challenges and still receive scores to track your progress.

Nova call to action

Related posts
Application Security

Finding classes for exploiting Unsafe Reflection / Unchecked Class Instantiation vulnerabilities in Java with Joern

During a pentest engagement we found a Java application vulnerable to unsafe reflection [1]. This…
Read more
Application Security

Mitigating Vulnerabilities: Elevating Security Proficiency in Software Development

In the ever-evolving digital landscape, the significance of software security cannot be overstated.
Read more
Application Security

The Importance of Supply Chain to Application Security

When we think about software development, we usually think about complex technical concepts…
Read more

Deixe um comentário