JavaScript Application Security: Top 10 Vulnerabilities for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JavaScript Application Security: Top 10 Vulnerabilities for Beginners



Web application security is one of the most important topics for any developer. JavaScript (especially on the server side with Node.js) often becomes a target for attackers due to its popularity. In this article, we will cover the 10 most common vulnerabilities that beginner developers face and show how to avoid them.



1. XSS (Cross-Site Scripting)

XSS is one of the most common attacks, where an attacker injects a malicious script into a web page. This happens when user data is inserted into HTML without escaping.



Dangerous code (vulnerable):

app.get('/search', (req, res) => {  const query = req.query.q;  res.send(`<h1>Search results: ${query}</h1>`);});


Safe code (protection):

const escapeHtml = require('escape-html');

app.get('/search', (req, res) => { const query = escapeHtml(req.query.q); res.send(`<h1>Search results: ${query}</h1>`);});


2. SQL Injection

If you use SQL databases (e.g., SQLite or PostgreSQL), unescaped queries can lead to data leaks.



Dangerous code:

const user = req.body.username;db.query(`SELECT * FROM users WHERE name = '${user}'`);


Safe code (use parameterized queries):

const user = req.body.username;db.query('SELECT * FROM users WHERE name = $1', [user]);


3. Insecure Deserialization

Using JSON.parse() on untrusted data can lead to "prototype pollution" attacks.



Example of vulnerability:

const data = JSON.parse(req.body.jsonData);// If data contains __proto__, it can change the Object prototype


Protection: always validate data before parsing or use libraries like fast-json-stable-stringify.



4. Lack of Input Validation

Never trust user data. Always check the type, length, and format of the data.



// Bad: accept everythingapp.post('/profile', (req, res) => {  const { name, age } = req.body;  // ...});

// Good: validateconst schema = { name: 'string', age: 'number' };if (typeof req.body.name !== 'string') throw new Error('Invalid name');


5. CSRF (Cross-Site Request Forgery)

An attack where an attacker forces a user to perform an unwanted action on a site where they are authenticated.



Protection: use CSRF tokens.

const csrf = require('csurf');app.use(csrf({ cookie: true }));

app.get('/form', (req, res) => { res.render('form', { csrfToken: req.csrfToken() });});


6. Information Leakage Through Errors

Never show detailed error messages to the user — this gives hackers information about your application's structure.



Bad:

app.use((err, req, res, next) => {  res.status(500).send(err.stack); // Leaks the call stack!});


Good:

app.use((err, req, res, next) => {  console.error(err.stack); // Log for ourselves  res.status(500).send('Internal server error');});


7. Unsafe Use of eval() and Function()

The eval() and new Function() functions execute a string as code — this is extremely dangerous if the string contains user data.



// Dangerous! Never do thisconst userInput = req.body.code;eval(userInput); // An attacker can execute any code


Alternative:

Blogs

Book Recommendations