セキュアなアップロード

2 月の Discourse 2.4 リリース で追加された「Secure Uploads(安全なアップロード)」機能により、Discourse インスタンス内のすべてのアップロード(画像、動画、音声、テキスト、PDF、ZIP など)のセキュリティが大幅に向上します。

前提条件

サイト上で S3 アップロードが有効になっている必要があります。そのためには、以下の設定を入力済みであることが必須です。

  • S3 access key id
  • S3 secret access key
  • S3 region
  • S3 upload bucket

また、パブリックバケットポリシーが設定されていない S3 バケットを使用している必要があります。さらに、既存のすべてのアップロードが public-read S3 ACL を持っていることを確認してください。詳細は後述の「Secure Uploads の有効化」をご覧ください。

これらの前提条件を満たした後、「secure uploads」サイト設定を有効にできます。

Secure Uploads の有効化

:dragon: :warning: HERE BE DRAGONS(危険地帯) :warning: :dragon:

これは高度な機能であり、エンタープライズプラン以外のサポートは限定的です。専門知識を持つユーザーのみが有効化してください。


Secure Uploads を有効にするには、以下の手順に従ってください。

  1. S3 アップロードが設定されていることを確認してください。
  2. S3 バケットにパブリックバケットポリシーが設定されているか確認してください。設定されている場合は、追加の手順(手順 4)が必要です。
  3. uploads:sync_s3_acls rake タスクを実行してください。これにより、すべてのアップロードが S3 で正しい ACL を持つようになります。これは非常に重要です。手順 4 をこのタスク実行前に実行すると、一部のアップロードにアクセスできなくなる可能性があります。
  4. 手順 1 で確認したように、バケットにパブリックバケットポリシーが設定されている場合は、それを削除してください。
  5. 「secure uploads」サイト設定を有効にしてください。オプションとして、「prevent anons from downloading files(匿名ユーザーによるファイルのダウンロードを防止)」サイト設定を有効にすると、匿名ユーザーが公開投稿からの添付ファイルをダウンロードするのを防げます。これ以降のアップロードは、以下の条件に応じて安全なものとしてマークされる可能性があります。
  6. 過去のすべてのアップロードを分析し、安全なものとしてマークし直す場合は、uploads:secure_upload_analyse_and_update rake タスクを実行してください。

:exclamation: S3 バケットポリシーに関する注意 :exclamation:

アップロード先のバケットに パブリック バケットポリシーが設定されていないことを確認してください。パブリックバケットポリシーには、以下のような記述が含まれます。

{
    "Version": "2012-10-17",
    "Id": "ComputedBucketPolicy",
    "Statement": [
        {
            "Sid": "AllowWorldRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

ここで重要なのは、* に対して GetObject を許可している点です。これは、バケット内のすべてのファイルを誰でもダウンロードできることを意味します。また、ポリシーがパブリックである場合は、このラベルにも表示されます。

これらの設定は 変更しないでください。以下は「Block public access(パブリックアクセスのブロック)」タブの理想的な状態です。

機能の説明

Secure Uploads を有効にすると、Composer 経由でアップロードされたファイルは、以下の基準に基づいて「安全」または「安全でない」としてマークされます。

  • 「login required(ログイン必須)」サイト設定が有効な場合、すべてのアップロードが安全としてマークされ、匿名ユーザーはアクセスできなくなります。
  • プライベートメッセージ内で何かをアップロードした場合、それは安全としてマークされます。
  • プライベートカテゴリ内のトピック内で何かをアップロードした場合、それは安全としてマークされます。

S3 上のアップロードはプライベートな ACL を持つため、S3 上のファイルへの直接リンクは 403 アクセス拒否エラーを返します。安全なアップロードへのアクセスはすべて、S3 の 署名付き URL を介して行われます。ただし、これはユーザーには非表示です。アップロードが安全な場合、その参照は /secure-uploads/ という Discourse URL 経由で行われます。

権限とアクセス制御

/secure-uploads/ URL は、現在のユーザーがメディアにアクセスする権限を持っているかを確認し、許可されている場合は提供します。アップロードが作成されるとき、それが最初に現れる投稿がその「アクセス制御投稿」として設定され、すべての権限はその投稿に基づきます。

  • 「login required」サイト設定が有効な場合、匿名ユーザーが URL にアクセスすると常に 404 エラーが表示されます。
  • アクセス制御投稿がプライベートメッセージであるメディアにアクセスする場合、ユーザーはそのプライベートメッセージトピックの一部でなければメディアにアクセスできず、そうでない場合は 403 エラーが表示されます。
  • アクセス制御投稿がプライベートカテゴリ内のトピック内にあるメディアにアクセスする場合、ユーザーはそのカテゴリにアクセスする権限を持っている必要があります。そうでない場合は 403 エラーが表示されます。

/secure-uploads/ URL を投稿やトピック間でコピーして使用するのは避けてください。Discourse フォーラム内では、ユーザーごとにアクセスレベルが異なるためです。新しいアップロードは常に Composer 経由で作成してください。Onebox やホットリンクされた画像も、安全なアップロードのルールを尊重します。サイト設定によるアップロード、絵文字、テーマのアップロードは、公開されている必要があるため、安全なアップロードの影響 を受けません

:warning: アクセス制御投稿が削除された場合、添付されたアップロードは アクセスできなくなります:warning:

安全なアップロードを含む投稿の移動

「アクセス制御投稿」を異なるセキュリティコンテキスト間で移動すると、添付されたアップロードのセキュリティ状態が変更される可能性があります。アップロードのセキュリティが変更される可能性のある状況は以下の通りです。

  • トピックのカテゴリを変更する。トピック内のすべての投稿を循環させ、アップロードのセキュリティステータスを更新します。
  • トピックを公開トピックとプライベートメッセージの間で変更する。上記と同じ処理を行います。
  • 投稿をあるトピックから新しい、または既存の別のトピックに移動する。ターゲットトピックに対して上記と同じ処理を行います。

メール内の安全なアップロード

メールへの安全な画像の埋め込みはデフォルトで有効です。さらに制御するために、以下のサイト設定を構成できます。

  • secure_uploads_allow_embed_images_in_emails:これを無効にすると、メール内の安全な画像が抹消されます。
  • secure_uploads_max_email_embed_image_size_kb:埋め込む安全な画像のサイズ上限です。デフォルトは 1MB で、メールが大きくなりすぎないようにします。最大値は 10MB です。email_total_attachment_size_limit_kb と連携して動作します。

安全な画像は、メールクライアントでの base64 URL サポートがまだ不安定であるため、メール添付ファイルとして追加され、cid: URL 形式を使用して埋め込まれます。

secure_uploads_allow_embed_images_in_emails が有効になっていない場合、または画像がサイズ制限を超えた場合は、安全な画像の代わりに以下が表示されます(埋め込まれていない安全な音声や動画も同様です)。

image

ホスト型顧客について

現時点では、Secure Uploads はエンタープライズプランの顧客のみが利用可能です。詳細については、お問い合わせください

「いいね!」 51
Files/Download Manager For Discourse
Prevent guests from watching images
Register to download
Need log the who downloaded attachments
S3 Bucket objects restricted access policy as per Discourses groups
Signed Google Cloud CDN URLs
Search engines and private messages?
How to make uploads available only to logged-in users
S3 Object Storage for uploads- possible to make private? (and CDN question)
Discourse jumps back 20 posts in post history when navigating to new topic
Discourse jumps back 20 posts in post history when navigating to new topic
Why run UpdatePostUploadsSecureStatus even when secure uploads is disabled?
SSL_connect returned=1 errno=0 peeraddr=162.243.189.2:443 state=error: certificate verify failed (Hostname mismatch)
Understanding Uploads, Images, and Attachments
Capacity planning / Resource requirements
Why you should use Discourse internally for your company/team instead of Slack (4 years use case)
Can't always select any category in composer
S3 Object Storage for uploads- possible to make private? (and CDN question)
Personal Message attachments accessible to unauthenticated users (missing auth check)
Potential Directory Traversal: /uploads/* allows cross-directory file access
S3 Storage with no Public access
Are the images published in the Staff category publicly visible?
Login Only - Does it actually stop all traffic access without login?
为啥我的七牛云s3附件上传成功后,论坛中无法加载出来?
How the media in the posts look like when secure uploads are enabled?
Remove images from emailed reply to forum
Files/Download Manager For Discourse
Topic replies invisible until topic owner decides to reveal them?
Securing private group/category resources
PDF embedding and reading help
Inline PDF Previews
Upload objects to private S3 is not working
Spammers using uploaded images in spam e-mails. Any advice how to resolve?
Secure Media Uploads breaks Category Logos
How to allow downloading images along with other user data (csv) from activity section?
Discourse 2.6.0.beta3 Release Notes
Lock Downloads in discourse
What’s the suggested method to use secure images?
Page Publishing
Errors on Exporting Data from Teams to Self Hosted Discourse on Digital Ocean