DEV Community

Cover image for Improve the Safety of Your React App
Daniel Musembi
Daniel Musembi

Posted on

Improve the Safety of Your React App

It is time to strengthen the security of your React apps.

INTRODUCTION

You should construct a safe React app to safeguard your users' information and keep your app running smoothly. As programmers, we need to implement safety checks and industry best practices to fortify our code.

This post will examine strategies and code snippets that can be implemented to increase the safety of your React application.

1.Protecting Against Unwanted Input with Validation

Cross-site scripting (XSS) and SQL injections are two forms of harmful attacks that can be avoided with proper input validation. To ensure correct input from users and clean data before processing, use libraries such as Yup or Formik.

lets see an example

import React, { useState } from "react";
import { Formik } from "formik";
import * as Yup from "yup";

const App = () => {
  const [formState, setFormState] = useState({
    username: "",
    password: "",
  });

  const validationSchema = Yup.object().shape({
    username: Yup.string().required(),
    password: Yup.string().required(),
  });

  const handleSubmit = (values) => {
    // Do something with the values here
  };

  return (
    <Formik
      initialValues={formState}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ errors, handleChange, handleBlur }) => (
        <form>
          <input
            name="username"
            value={formState.username}
            onChange={handleChange("username")}
            placeholder="Username"
          />
          {errors.username && <span>{errors.username}</span>}
          <input
            name="password"
            value={formState.password}
            onChange={handleChange("password")}
            placeholder="Password"
            type="password"
          />
          {errors.password && <span>{errors.password}</span>}
          <button type="submit">Submit</button>
        </form>
      )}
    </Formik>
  );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

This code uses the Formik library to create a form that validates user input. The validationSchema property is used to define the rules that must be met for the form to be valid. The handleChange and handleBlur functions are used to update the form state when the user changes or blurs a field. The handleSubmit function is used to handle the submission of the form.

The form's validation rules are defined with the help of the Yup library. There are predefined validation criteria available in the Yup library, and you may also construct your own.

2.Protected Conversations: Closing the Cybergates

Secure protocols, such as HTTPS, must be used when interacting with APIs or backends. Data sent over an encrypted connection cannot be intercepted or altered in transit. You should also keep private information, such as API keys and credentials, out of your React app's source code. Instead, put them in environment variables from which only authorized users can retrieve them.

// Fetching data from an API
const fetchData = async () => {
  try {
    const response = await fetch('https://api.example.com/data', {
      headers: {
        Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`,
      },
    });
    // Process the response
  } catch (error) {
    // Handle the error
  }
};
Enter fullscreen mode Exit fullscreen mode

3.Proper Authentication: Verifying User Identities

Protecting user accounts requires the deployment of strong authentication systems. For secure password hashing, rely on tried-and-true tools like Firebase Authentication, Auth0, or bcrypt. Multi-factor authentication (MFA) and session management are two methods you can use to verify a user's identity more thoroughly.

// Firebase Authentication
import { firebase } from "firebase";

const auth = firebase.auth();

const handleSubmit = (values) => {
  const { username, password } = values;

  auth.signInWithEmailAndPassword(username, password)
    .then(() => {
      // The user has been authenticated successfully
    })
    .catch((error) => {
      // There was an error authenticating the user
    });
};

// Auth0
import { Auth0Provider } from "@auth0/auth0-react";

const clientId = "YOUR_CLIENT_ID";
const domain = "YOUR_DOMAIN";

const App = () => {
  return (
    <Auth0Provider
      clientId={clientId}
      domain={domain}
    >
      <AppComponent />
    </Auth0Provider>
  );
};

// bcrypt
import bcrypt from "bcrypt";

const hashPassword = (password) => {
  return bcrypt.hash(password, 10);
};

const comparePasswords = (password, hashedPassword) => {
  return bcrypt.compare(password, hashedPassword);
};

export default App;

Enter fullscreen mode Exit fullscreen mode

4.Controlling Permissions Based on Roles

Use RBAC to limit access to features or data for certain groups of users. Assign users to specific groups (administrator, user, visitor, etc.) and set their respective privileges. The use of RBAC allows you to restrict access to critical parts of your application and prevent malicious use.

// Import the RBAC library
import { useRole } from "react-rbac";

// Define the roles and permissions
const roles = {
  administrator: {
    permissions: ["create", "update", "delete"],
  },
  user: {
    permissions: ["read"],
  },
  visitor: {
    permissions: [],
  },
};

// Use the useRole hook to get the current user's role
const currentUser = useRole();

// Use the currentUser variable to determine which features or data the user has access to
if (currentUser.role === "administrator") {
  // The user has access to all features and data
} else if (currentUser.role === "user") {
  // The user has access to read-only features and data
} else {
  // The user has no access to features or data
}

Enter fullscreen mode Exit fullscreen mode

5.Sanitizing Inputs to Prevent Cross-Site Scripting (XSS)

When user-generated content is not properly sanitized and treated as code, XSS attacks might occur. Use tools like DOMPurify or the features built into React e.g (dangerouslySetInnerHTML) to sanitize and validate user inputs, preventing the execution of malicious scripts.

// Import the DOMPurify library
import { DomPurify } from "dompurify";

// Define a function to sanitize user input
const sanitizeInput = (input) => {
  return DomPurify.sanitize(input);
};

// Use the dangerouslySetInnerHTML property to render user input after it has been sanitized
const App = () => {
  const [userInput, setUserInput] = useState("");

  // When the user changes the input value, update the state
  const handleChange = (event) => {
    setUserInput(event.target.value);
  };

  // Render the user input after it has been sanitized
  return (
    <div>
      <input
        type="text"
        placeholder="Enter some text"
        onChange={handleChange}
      />
      <div dangerouslySetInnerHTML={{ __html: sanitizeInput(userInput) }} />
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

Conclusion

There is no "option" in regards to the security of your React app. Input validation, secure communication, sufficient authentication, role-based access control, and protection against XSS attacks are all ways to build a robust application. Regularly checking and auditing your software for security flaws is essential.

Don't forget to implement proven best practices for cyber security. Let's work together to make the internet a safer place for everyone.

Good luck, and have fun with the code!

Top comments (1)

Collapse
 
delower618 profile image
DELOWER| Areon

🚀 Exciting times for developers! Areon Network invites you to participate in their groundbreaking Hackathon. Head over to hackathon.areon.network to register and compete for a share of the impressive $500k prize pool. Unleash your coding prowess! 💻💡 #DevChallenge #AreonNetwork