Plikli が行っているセキュリティ対策
このページには、Plikli に実装されている対策だけを、何をしているかがわかる形で書いています。
サイトとデータの分離
データベースの行レベルセキュリティ
サイトのデータを持つテーブルには PostgreSQL の行レベルセキュリティ(FORCE RLS)をかけ、別のサイトの行を読み書きできないようにしています。
API でも確認
API は、ログイン中のユーザーが権限を持たないサイトへの要求を受け付けません。
ログインとアカウント
パスワードの保存
パスワードは scrypt とランダムなソルトでハッシュ化して保存します。10 文字以上が必要です。
2 段階認証
認証アプリ(TOTP)に対応。使い切りのバックアップコードを 10 個発行し、ハッシュ化して保存します。各ユーザーが設定できます。
セッション
リクエストのたびにサーバー側でセッションを確認します。ログアウトするとすぐに無効になり、有効期限は 7 日。パスワードを再設定すると、すべての端末でログアウトします。権限もリクエストごとに読み直します。
試行回数の制限
ログイン、2 段階認証、新規登録、パスワード再設定は、同じ IP アドレスから 15 分に 10 回まで。API、コメント、お問い合わせフォームにも上限があります。
登録の有無を明かさない
パスワード再設定の画面は、そのメールアドレスが登録されているかどうかを表示しません。
権限と記録
6 つの役割
オーナー、管理者、編集者、投稿者(自分の記事のみ)、寄稿者(下書きのみ)、閲覧者。役割はサイトごとに設定します。
操作ログ
記事、画像、設定、ユーザーと役割、ドメイン、キー、書き出しの操作を記録します。
秘密情報の扱い
暗号化して保存
Google と Shopify の接続トークン、2 段階認証の秘密鍵、WordPress 取り込み用の認証情報は AES-256-GCM で暗号化して保存します。取り込み用の認証情報は、取り込みが終わると削除します。
API キーはハッシュで保存
API キーとアプリケーションパスワードは SHA-256 のハッシュだけを保存し、発行時に一度だけ表示します。いつでも無効にできます。パスワード再設定などの使い捨てトークンもハッシュ化し、有効期限をつけています。
初期値の鍵では動かない
本番環境では、初期値の秘密鍵のままではアプリが起動しません。
記事とファイル
本文の HTML を許可リストで整える
保存時と表示時の両方で、本文の HTML を許可リストで整えます。スクリプト、本文中の iframe、イベント属性は取り除き、リンクは http・https・mailto・tel だけを残します。
画像の検査
画像の種類は拡張子ではなくファイルの中身から判定し、SVG は受け付けません。配信時には nosniff とサンドボックスの CSP をつけます。
プラグインのコードを実行しない
アップロードされた WordPress のプラグイン zip は、先頭の情報だけを読み取ります(10 MB まで)。コードは実行も保存もしません。
通信と外部への接続
管理画面の CSP と HSTS
管理画面には厳しい Content-Security-Policy(自サイトのスクリプトのみ、他サイトへの埋め込み不可)をかけ、管理画面と API では HSTS を送ります。
公開サイトの基本ヘッダー
すべての公開サイトには nosniff、Referrer-Policy、X-Frame-Options(SAMEORIGIN)、Permissions-Policy をつけます。
外部ページの安全な取得
WordPress の取り込み、ブログカード、リンク切れの確認でサーバーが外部のページを読むときは、公開されたアドレスだけに接続し、リダイレクトのたびに確認し直し、サイズと時間に上限を設けています。
Webhook の署名確認
Stripe と Shopify からの通知は、署名を確認してから処理します。
読者のプライバシー
同意バナー
オフ・EU の読者のみ・すべての読者から選べます。同意を得るまで、Google アナリティクス、タグ マネージャー、Google 広告、AdSense、埋め込みのスクリプトや iframe、独自のコードを読み込みません。Plikli 自体は Cookie を設定しません。
外部送信規律の公表ページ
電気通信事業法の外部送信規律に向けて、送信先・送信される情報・目的を一覧にしたページ(/third-party-services)を用意します。GA4・GTM・Google 広告・AdSense と、テーマの Web フォント(Google Fonts)は自動で載り、ほかの項目も追加できます。
プライバシーポリシーのひな形
個人情報保護法に沿ったひな形(GDPR の注記つき)。【】の部分を埋めて使います。法的助言ではありません。
集めないデータ
アクセス数は記事ごとの日別の数だけを保存し、IP アドレスは保存しません(重複を除くため 30 分だけメモリに保持)。コメントとお問い合わせでも IP アドレスは保存しません。