How JSX prevents injection attacks

How Can Injection Attacks Be Prevented in JSX?

In this article, we’ll learn how to defend React applications from injection attacks by blocking injection attacks within JSX code. We’ll look at essential ways for strengthening your code against potential weaknesses.

Security is still a top priority in the fast-paced world of online development. Injection attacks offer a substantial threat to React apps, which could compromise the integrity and user experience of your online project.

Table of Content

  • How JSX prevents injection attacks
  • Preventing Attacks Using DOMPurify
  • Preventing Attacks Using Declarative programming

Let’s take an Example

Because of insufficient input validation, this online calculator is vulnerable to injection attacks. Users can take advantage of this flaw by inserting malicious code, such as JavaScript, into the input boxes. Because the calculator fails to sanitize and validate user input, attackers can execute arbitrary code, posing possible security issues such as Cross-Site Scripting (XSS) attacks.

Calculator.js Code example

Javascript




import React, { useState, useEffect } from "react";
import "./calc.css";
 
const Calculator = () => {
    const [expression, setExpression] = useState("");
 
    useEffect(() => {
        const handleKeyDown = (event) => {
            const { key } = event;
            event.preventDefault();
            handleKeyPress(key);
        };
 
        window.addEventListener("keydown", handleKeyDown);
 
        return () => {
            window.removeEventListener("keydown", handleKeyDown);
        };
    }, [expression]);
 
    const handleKeyPress = (key) => {
        if (key.length === 1) {
            handleAppend(key);
        } else {
            switch (key) {
                case "Enter":
                case "=":
                    handleEvaluate();
                    break;
                case "Backspace":
                case "Delete":
                    handleBackspace();
                    break;
                default:
                    break;
            }
        }
    };
 
    const handleAppend = (value) => {
        setExpression((prevExpression) => prevExpression + value);
    };
 
    const handleEvaluate = () => {
        try {
            const result = eval("(" + expression + ")");
            setExpression(result.toString());
        } catch (error) {
            console.error(error);
            setExpression("Error");
        }
    };
 
    const handleClear = () => {
        setExpression("");
    };
 
    const handleBackspace = () => {
        setExpression(expression.slice(0, -1));
    };
 
    return (
        <div className="calculator">
            <h2>Online Calculator</h2>
            <div
                className="display"
                tabIndex="0"
                onKeyDown={(e) => e.preventDefault()}
            >
                {expression}
            </div>
            <div className="buttons">
                <button className="operator" onClick={() => handleAppend("+")}>
                    +
                </button>
                <button className="operator" onClick={() => handleAppend("-")}>
                    -
                </button>
                <button className="operator" onClick={() => handleAppend("*")}>
                    *
                </button>
                <button className="operator" onClick={() => handleAppend("/")}>
                    /
                </button>
                <button className="operator" onClick={handleClear}>
                    C
                </button>
                <button className="equal" onClick={handleEvaluate}>
                    =
                </button>
 
                <button className="number" onClick={() => handleAppend("7")}>
                    7
                </button>
                <button className="number" onClick={() => handleAppend("8")}>
                    8
                </button>
                <button className="number" onClick={() => handleAppend("9")}>
                    9
                </button>
                <button className="operator" onClick={() => handleAppend(".")}>
                    .
                </button>
 
                <button className="number" onClick={() => handleAppend("4")}>
                    4
                </button>
                <button className="number" onClick={() => handleAppend("5")}>
                    5
                </button>
                <button className="number" onClick={() => handleAppend("6")}>
                    6
                </button>
                <button className="del" onClick={handleBackspace}>
                    DEL
                </button>
 
                <button className="number" onClick={() => handleAppend("1")}>
                    1
                </button>
                <button className="number" onClick={() => handleAppend("2")}>
                    2
                </button>
                <button className="number" onClick={() => handleAppend("3")}>
                    3
                </button>
                <button className="equal" onClick={handleEvaluate}>
                    =
                </button>
            </div>
        </div>
    );
};
 
export default Calculator;


Output:

Online vulnerable calculator

The provided Calculator.js code is vulnerable to cross-site scripting (XSS) attacks due to the direct evaluation of user input in the `handleEvaluate` function. This vulnerability allows a malicious user to inject arbitrary JavaScript code into the application, which can then be executed when the user clicks the “=” button.

The `eval()` method can run arbitrary code, which can lead to security vulnerabilities if user input is not properly sanitized or checked.

Because of insufficient input validation, this online calculator is vulnerable to injection attacks. Users can take advantage of this flaw by inserting malicious code, such as JavaScript, into the input boxes.

To maintain web application security, such direct assessment of user input must be avoided, and safer solutions for processing and parsing user-generated material must be used.

Similar Reads

How JSX prevents injection attacks

...

Approach 1: Using DOMPurify

Approach 1: Using DOMPurify...

Approach 2: Declarative programming

DOMPurify is a quick and tolerant DOM-only XSS (cross-site scripting) sanitizer for HTML, MathML, and SVG. It is written in JavaScript and is compatible with all modern browsers. DOMPurify sanitizes HTML and prevents XSS attacks by removing any harmful HTML, hence preventing XSS attacks and other security issues.Install the library using npm...