LoginSignup
1
0

More than 1 year has passed since last update.

React 画面から入力できるHTMLタグに制限をかける

Posted at

画面上のテキストエリアにユーザーがHTML文字列を入力する仕様だが
scriptタグなどはXSSリスクがあるので入力できないようにする方法を書きます

実装方法

ポイントは入力されたHTML文字列をstringのままチェックするのではなく、
HTMLElementとしてチェックするところです
そのためテキストエリアの下に入力した文字列をHTMLとして描画し、その要素を取得してタグのチェックを行います

文字列のHTML描画はnpm install interweave でhtmlを安全に描画できるライブラリをインストールします

import { Interweave } from "interweave";
import React, { useState } from "react";

// 入力可能なhtmlタグ
const allowedTags = ["p", "span", "div"];

const HtmlInput = () => {
    /** 入力内容 */
    const [text, setText] = useState("");
    /** チェック結果メッセージ */
    const [checkResult, setCheckResult] = useState("");
    /**
     * htmlタグチェック
     */
    const checkTags = () => {
        // interweaveでhtml描画している箇所のhtmlElementを取得する
        // children[0]にはinterweaveにより追加されたspanが入ってくるので、更にその子要素が入力内容のhtmlとなる
        const elements = document.getElementById("checkArea")?.children[0].children;
        for (let i=0; i < elements!.length; i++){
            // tagNameで取得したタグ名は大文字なので小文字化する
            if (!allowedTags.includes(elements?.item(i)?.tagName!.toLowerCase()!)){
                setCheckResult("チェックNG");
                return false;
            }
        }
        setCheckResult("チェックOK");
    }


    return (
        <div>
            <textarea value={text} 
            onChange={event => setText(event.target.value)}
            onBlur={checkTags}>
            </textarea>
            <div id="checkArea" className="hidden">
                <Interweave content={text}/>
            </div>
            <div>
            {checkResult}
            </div>
        </div>
    )
}
export default HtmlInput;

入力を許可しているpタグを入力後、フォーカスアウトするとチェックOKと表示されます
スクリーンショット 2022-12-04 2.12.26.png

今度はpタグの下に許可されていないh1タグを追加するとチェックNGと表示されます
スクリーンショット 2022-12-04 2.13.37.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0