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プラグインで秘匿情報を隠す〜隠蔽方法編〜 ^

*2

GaroonプロキシAPIを利用すると、認証/認可情報の公開範囲を管理者以上の権限をもつユーザーに限定できます。
詳細はGaroonヘルプのプロキシAPIの設定を参照してください。

^

*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