0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kintoneのいいね表示を題材にHTMLエスケープを確認する|ユーザー名を安全に表示するJavaScript

0
Posted at

kintacoです。自社のいいね!ボタンでは、反応したユーザーの表示名をHTMLへ差し込む前にエスケープしています。この記事では実コードのescapeHtmlをそのまま取り出し、文字列とHTMLの違いを確認します。

いいねの保存処理や、kintone REST APIは含みません。APIから取得した値だから、そのままHTMLとして扱ってよいわけではない、という点に絞った解説です。

textContentで表示できるなら、まず文字列として扱う

名前を表示するだけなら、DOM要素のtextContentへ設定すると、タグを文字として扱えます。HTMLテンプレートへ差し込む構成を使う場合は、差し込む文脈に合わせた処理が必要です。

以下はHTMLのテキスト部分向けのエスケープです。スクリプト、CSS、URL、イベント属性に使う汎用的な無害化関数ではありません。

function escapeHtml(str) {
  return String(str)
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

&を先に置き換える

最初に&を置き換え、そのあと<・>・ダブルクオート・シングルクオートを置き換えます。あとから生成した<などの&まで再度変換しないための順番です。

console.log(escapeHtml('<管理者 & 担当者>'));
// &lt;管理者 &amp; 担当者&gt;

同じ文字列へ二度適用すると、エンティティ中の&も変換されます。加工済みかどうか曖昧な値を何度も通すのではなく、元データを保持し、表示する直前に一度だけ変換します。

ユーザー名の表示と、ユーザーの識別を分ける

いいね済みかを判断する場合には、表示名ではなくユーザーコードを比較します。同じ表示名が複数存在したり、名前が変更されたりするからです。表示用テキストのエスケープだけで、ユーザーの一意性や編集権限が保証されるわけではありません。

保存の競合も別の問題

画面へ安全に文字を表示できても、複数人が同時にいいねを保存したときの競合は解決しません。レコード更新を実装する場合には、権限、取得と更新の間の変更、リビジョン指定、失敗後の表示を別に設計します。このサンプルに保存処理はありません。

確認したことと未確認のこと

特殊文字、複数の文字が混ざる場合、日本語、二重適用をNode.jsで確認しました。実ブラウザーでの攻撃コード実行テストや、kintoneでのいいね保存テストは含みません。テンプレートへ組み込む場合は、その出力箇所が本当にHTMLテキストの文脈かも確認してください。

ボタンと保存先を設定して使いたい場合

自社のいいね!ボタンプラグインの仕様・設定画面に、設定から利用する方法もまとめています。サンプルと製品版の対応範囲は異なります。

無料利用では、非契約ドメインのPC・モバイル一覧画面に有償プランの案内バナーが30%の確率で表示されます。契約済みドメインでは表示されません。一度閉じると、同じブラウザー・同じkintoneドメインでは、全Kintacoプラグイン共通で24時間非表示になります。

参考資料

製品仕様と実コードの確認元:LikeButton/src/js/desktop.js(1.0.6)。

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?