Question:
Is it risky to set innerHTML for a div?

Problem:

I want to show status text depending on the response received on the Axios post. My code is as below.


import React from 'react';

import axios from 'axios';


const handleSubmit = (email, pass) => {


    const data = {

        'user': email.value,

        'password': pass.value,

    };


    const headers = {

        "Content-Type": "application/json",

    }


    axios.post('/auth', data, {

        headers: headers

    })

    .then( function (res) {

        //do auth success stuff

    })

    .catch(function (error) {

        //auth failed, show status to user

        var err = document.getElementById("error");

        err.innerHTML = "Authentication failed";

        err.hidden = false;

    });

}


const Login = () => {

    return(

        <form

            onSubmit={(event) => {

                event.preventDefault()

                const [email, password] = event.target.elements;

                handleSubmit(email, password);

            }}>       

        

            <div className="medium-text">

                <div className="center">

                    <input type="text" id="email" name="email" placeholder="Email" />

                    <input type="password" id="password" name="password" placeholder="Password"/>

                    <div className="">

                        <button type="submit">Submit</button><br/><br/>

                    </div>

                    <div id="error" hidden>

                    </div>

                </div>

            </div>

        </form>

    );

};


export default Login;


Now as you can see when authentication fails, I have below code.

    //auth failed, show status to user

    var err = document.getElementById("error");

    err.innerHTML = "Authentication failed";

    err.hidden = false;


So my question is, is it safe to write code this way, as I read somewhere in react we have something like dangerouslySetInnerHTML and there is a chance somebody may hack if we use innerHtml directly, how is that possible.



Solution:

Yes it's potentially a vector for cross-site scripting. Also, it's simply not the React way.


Instead, store the error in state and render it if required. There's no need to use DOM methods at all


const authenticate = async (user, password) => {

  try {

    // Axios defaults to sending JSON

    const res = await axios.post("/auth", { user, password });


    // do auth success stuff...

  } catch (error) {

    // you want to know why things failed, right?

    console.error(

      "/auth request failed",

      error.response?.data,

      error.toJSON?.() ?? error,

    );

    throw new Error("Authentication failed");

  }

};


Here I'm using state to hold not only any error but also the input values. This method is referred to as >controlled components.



import { useState } from "react";


const Login = () => {

  // state for controlled inputs

  const [user, setUser] = useState("");

  const [password, setPassword] = useState("");


  // state for auth errors

  const [error, setError] = useState(null);


  const handleSubmit = async (e) => {

    e.preventDefault();

    try {

      await authenticate(user, password);

    } catch (err) {

      setError(err.message);

    }

  };


  return (

    <form onSubmit={handleSubmit}>

      <div className="medium-text">

        <div className="center">

          <input

            type="text"

            id="email"

            name="email"

            placeholder="Email"

            value={user}

            onChange={(e) => setUser(e.target.value)}

          />

          <input

            type="password"

            id="password"

            name="password"

            placeholder="Password"

            value={password}

            onChange={(e) => setPassword(e.target.value)}

          />

          <div className="">

            <button type="submit">Submit</button>

          </div>


          {/* conditionally render any error */}

          {error && <div id="error">{error}</div>}

        </div>

      </div>

    </form>

  );

};


Suggested blogs:

>What makes index.html have such kind of name in Django?

>Fix Module Not Found during deployment- Django

>Creating a Django with existing directories, files etc.?

>Fix Module Not Found Error in Django

>How to create a to-do list for users, with only incomplete tasks in Django?

>How to populate Django Quill Field from ORM

>How to test the post-Django function?

>How to filter events by month in Django?

>Implement nested serializers in the Django rest framework


Ritu Singh

Ritu Singh

Submit
0 Answers