kintone セキュアコーディングガイドライン

目次

概要

API の使用は利便性を高める反面、次のリスクを伴います。

  • セキュリティ上の問題が発生する。
  • cybozu.com のサービスが正常に動作しなくなる。

このページでは、kintone API を使用したプログラムを作成する上で注意すべき点を説明します。

クロスサイトスクリプティングや CSS インジェクションを防ぐ

「クロスサイトスクリプティング」(以下、XSS)とは、攻撃者が Web サイトに悪意のあるスクリプトのコードを挿入することで、閲覧者の Web ブラウザーがそのスクリプトを実行してしまう脆弱性のことです。
XSS と同様に、CSS でも悪意のある CSS コードを Web ページに挿入して実行できてしまうことがあります。
このような攻撃が可能になる脆弱性のことを「CSS インジェクション」と呼びます。

発生しうる脅威

XSS や CSS インジェクションのあるコードを読み込むことで、次のようなことが起こり得ます。

  • kintone のデータが盗み出される。
  • 偽の画面が表示される。
  • 悪意ある Cookie が Web ブラウザーに保存される。

脆弱性のあるコードの例

1
2
3
const text1 = document.getElementById('text1');
const div1 = document.getElementById('div1');
div1.innerHTML = '<input type="text" value="' + text1.value + '" />';

このコードは、text1 の値からテキストボックスを生成するコードです。
text1 のテキストボックスに次の内容を入力すると、コード実装者の意図しないコードが実行されます。

1
"onclick="alert(1)

対策

出力するすべての要素に対して、エスケープ処理をする

外部からプログラムに渡される文字列においては、特殊な意味をもつ文字(< > " など)をエスケープしてください。

HTML の要素を適切にエスケープするには、さまざまな知識を要します。
できる限り document.writeinnerHTML を使用した HTML の動的な生成を避けてください。
なお innerHTML の代わりに innerText を使用することでも、一般的な XSS は防げます。

出力する URL は「http://」または 「https://」で始まる URL だけにする

外部からの入力を元に a タグの href 属性や img タグの src 属性などの URL を動的に生成すると、javascript: などから始まる文字列を入力され、スクリプトを埋め込まれる場合があります。
これを防ぐには「http://」または「https://」で始まる URL のみを出力するようにします。

外部からの入力値を使用した要素の生成を避ける

untrusted には外部からの入力値が設定されているとします。

1
2
3
4
5
6
7
const tag = document.createElement('script');

// innerHTML を使った実装は避ける
tag.innerHTML = untrusted;

// innerText を使う
tag.innerText = untrusted;
信頼できない外部サイトに置かれた JavaScript や CSS を読み込まない

取り込み先のスクリプトが変わり、ある日突然データを盗み出すためのプログラムが作動するかもしれません。
外部のスクリプトを取り込む場合は、そのサイトが信頼できるかを十分に確かめてください。

通信に HTTPS を使用する

cybozu.com では、HTTPS によりお客様の Web ブラウザーとの通信を暗号化しています。
外部のシステムと連携する場合でも HTTPS に対応した API を利用してください。

認証情報や認可情報を適切に取り扱う

外部サービスと連携する場合は、外部サービスの認証や認可に関する情報をどこかに保存する必要があります。
これらの情報が漏洩した場合の影響を考慮して、認証/認可情報の保存場所を慎重に検討したり、認証情報の公開範囲を限定したりするなどの対処を実施してください。
特に JavaScript カスタマイズでは、一般利用者が閲覧できる場所に、認証/認可情報が保存されやすい傾向にあります。

認証/認可情報の一例

  • パスワード
  • API キー
  • OAuth クライアントシークレットやアクセストークン

認証/認可情報の保存先

ここでは、次に分類して紹介します。

  • 管理者(特定の権限を保持する人)しか閲覧できない保存先を推奨する。
  • 一般ユーザーでも閲覧できる保存先を推奨しない。

これらはあくまで参考情報です。
繰り返しになりますが、漏洩した場合の影響を考慮して、適切な保存先を慎重に検討してください。

推奨する保存先

*1 kintone カスタマイズをプラグイン化しプロキシ機能を利用すると、認証/認可情報の公開範囲をアプリ管理者以上の権限をもつユーザーに限定できます。
詳細は kintoneプラグイン開発入門 【Part2: 情報の隠匿方法編】 を参照してください。 ^

*2 Garoon プロキシ API を利用すると、認証/認可情報の公開範囲を管理者以上の権限をもつユーザーに限定できます。
詳細は「プロキシ API の設定( クラウド版 (External link) オンプレ版 (External link) )」を参照してください。 ^

*3 HttpOnly の Cookie は、JavaScript からのアクセスを防ぎます。 ^

推奨しない保存先
  • フロントエンドのプログラム(例:kintone JavaScript カスタマイズ、Garoon JavaScript カスタマイズ)
  • Web Storage(localStorage 、sessionStorage)
  • HttpOnly ではない Cookie
  • kintone プラグインの設定
    kintone.plugin.app.setConfig()
  • Garoon プラグインの設定
    garoon.plugin.setConfig()

情報の保存先として利用されることが多い Web Storage は、任意の JavaScript からアクセスできます。
同様に kintone プラグインの設定や HttpOnly ではない Cookie も、JavaScript からアクセスできます。

そのため、悪意のあるサイトにアクセスしてしまった場合などに、認証/認可情報が悪用される可能性があります。

参考記事

外部からセキュアに kintone のデータを操作する

取得したデータを適切に保管する

cybozu.com から取得したデータには個人情報や機密情報が含まれます。
これらの情報を外部アプリケーションで保存する場合は、データの流出や損失が発生しないよう、慎重にシステムを設計し、運用してください。

ユーザーを識別する際はユーザー ID を使用する

ユーザーを一意に特定したい場合、システムが内部的に発行したユーザー ID を使用することを推奨します。
ログイン名は cybozu.com 共通管理者が変更できる項目です。
後からユーザーのログイン名を別のユーザーのログイン名として付け替えた場合、ログイン名で識別すると意図しないユーザーを参照する可能性があります。

ユーザー ID は、次の API で取得できます。

JavaScript カスタマイズ利用時のその他の注意点

クロスドメイン制約

クロスドメイン制約のため、XHR(XMLHttpRequest)を使用した cybozu.com と外部サイトとの通信はできません。「Access-Control-Allow-Origin」ヘッダーは付与できません。

cybozu.com の Cookie には HttpOnly 属性が付いているため、JavaScript で cybozu.com の Cookie は取得できません。

外部サイトへのリダイレクト

次のようなオブジェクトに渡す URL を、外部からの入力値を元に動的に生成する場合は、想定した URL が生成されていることを確認するように実装してください。

  • location.href
  • document.location
  • window.open

strict モードの使用

JavaScript の strict モードを使うと、コーディングのミスを防ぎコードをよりセキュアなものにできます。
strict モードの詳細は MDN のドキュメント (External link) を参照してください。

strict モードの主な特徴
  • 宣言した変数だけに値を代入できる。
  • eval 関数内で定義された変数のスコープが、その関数の中だけに限定される。
  • arguments.callee がサポートされない。
1
2
'use strict';
mistypedVaraible = 17; // throws a ReferenceError