現在のユーザーのアクションに対する論理的なセキュリティ

やあ!元気?

現在のユーザー情報に基づいて論理的なセキュリティに関する作業を進めているんだ。例えば、「このトピックの作成者(topic.creator.username)が現在のユーザー(User.current().username)と一致する場合」に、そのユーザーがトピックを編集したり削除したりできるようにしている。

問題は、ユーザーのセッションに基づいて特定の動作を保証する必要があることだ。いくつかテストを進めているので、今ここで質問しているわけだ。

Web ブラウザの JavaScript を通じて(本番モードであっても)、Discourse.User.current().set(‘username’, ‘sometestename’) のようにユーザー名を変更できる。これにより、システム内のいくつかの動作がその変更だけで有効になってしまう。99% のユーザーがそのようなことをするわけではないことはわかっているが、このケースを超えて、ユーザーがユーザー情報を操作できないようにする方法をご存知だろうか?

よろしくお願いいたします、
フェリペ

ローカルブラウザ上の情報を変更しても、バックエンドには何も反映されません。

ユーザーは認証トークンでログインしているため、バックエンドに対して他人になりすますことはできないはずです:

サーバーをだますことはできないため、他のユーザーとして変更を加えることはできません。

ブラウザをリフレッシュすると、ローカルの変更はすぐに消去されるでしょう。最悪の場合、JavaScript のアプリの状態が破損し、キャッシュを削除する必要が生じる可能性があります。

やあ!いいね!

おっしゃる通り、最も良い方法はバックエンドサーバーから現在のユーザーセッションを取得することです。

こうすれば、ブラウザ側のキャッシュ変更の影響を受けなくなります。論理的なセキュリティがバックエンドサーバーのユーザーセッションに基づいており、PreloadStore には依存していないことを確認できる場所をご存じでしょうか?

もし私の考え方が間違っていたら教えてくださいね!ロバートさん、サポートありがとうございます!

よろしくお願いいたします、
フェリペ

セキュリティの専門家ではなく、アプリ開発者ですが、永続的な変更はすべてサーバー側でのみ行われます。EmberJS のブラウザ上での動作は、ユーザーの利便性と優れた使いやすさを実現するためのもので、例えば速度向上のためのキャッシュや、アプリのような自動的なインターフェースの動作などです。しかし、最終的にはすべての永続的な変更を Rails サーバーと交渉する必要があり、その際、ログイン中のユーザーに対してのみその権限が与えられます。

データ取得についても同様で、Rails サーバーはログイン中のユーザーのみがアクセスできるデータを送信します。

この点について心配する必要はないと思います。もし誰かがこれを回避しようとしても、最初の関門でつまずくでしょう。API をだます方法はないからです。

ご懸念されている点はどのようなことでしょうか?

あるアクションの可否がユーザーによって異なる(トピック作成者か、投稿作成者かなど)ため、バックエンドのユーザーセッションに基づいて検証する必要があることに懸念があります。

例えば、投稿の場合、投稿作成者であれば編集できます。

追記:Discourse の投稿権限のように確認します。

よろしくお願いいたします。フェリペ

セキュリティ対策はまずバックエンドで実装すべきです。

Rails のシリアライザーは、送信されるデータを決定します。

Guardian は許可されるアクションを保護します。

これらすべては Rails コントローラーによって管理されます。

フロントエンドがどのような不要なデータを送信したり、どのようなリクエストを送って取得を要求したりしても問題ありません。なぜなら、それらの要素がサーバーを保護しているからです。

フロントエンドの動作でもこれを再現できますが、フロントエンドはゲートキーパーではありません。

いくつかの主要なプラグインを確認すると、シリアライザーの例や Guardian の使用例が見つかるでしょう。

ロバートさん、ありがとうございます。このフィードバックは本当に必要でした!

必ず確認いたします!

よろしくお願いいたします、

ヤッ、ロバート!

ポスト制御(アクション)に関するプラグインコードとコードベースを分析していました。セキュリティ対策として最も効果的なものを探るためです。

分析の結果、フロントエンド側ではユーザーがポストを編集できるかどうかを確認するいくつかのステップがあります:

  • 第1段階:SiteSetting.post_menu_hidden_items
  • 第2段階:attrs.canEdit
  • 第3段階:editPost() - !post.can_edit - controllers/topic

しかし、フロントエンドで操作されたとしても、posts_controller.rbupdateメソッドでサーバーサイドに送信されると、Rails がポストを再度取得し、最終的なチェックとして以下の処理を行います:

  • !guardian.public_send(“can_edit?”, post)
  • guardian.ensure_can_edit!(post)
  • PostRevisor

ご示唆いただきありがとうございます!
とても参考になりました。

よくやりましたね。諦めずにさらに深く掘り下げてくれて、とても嬉しいです👍🏻