質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

3回答

2043閲覧

【Rails API】DBからデータ取得の際のfind_by / whereに関して セキュリティも含めたベストプラクティス

nyako

総合スコア45

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2021/06/08 07:42

Rails + MySQL

Rails APIモードにて、フロント側にparamsで検索したレコードの一部を渡したいと思っています。
下記のようなusersテーブルとします。paramsはaccount_name: taro を元に検索を行います。

|id|name|nickname|email|password_digest|photo|
|:--|:--:|--:|
|1|taro|tarota|test1@gmail.com|test12345|~~~.s3.com|
|2|jiro|jiroro|test2@gmail.com|test12345|~~~.s3.com|
|3|saburo|sabusab|test3@gmail.com|test12345|~~~.s3.com|

find_byの場合

ruby

1 @user = User.find_by(account_name: params[:account_name]) 2 3 if @user.present? 4 render json: { message:"ユーザーはいます。", name: @user.name, email: @user.email } 5 else 6 render json: { message: "ユーザーはいません。"} 7 end

1, account_nameを元に検索を行なっており、一致したユーザーのレコードを取得するというのが特徴だとは思いますが、
実際にフロント側に渡したいデータはnameとemailのみになります。
その場合、一旦取得(find_by)の時点で、SQL側から返ってくるのは暗号化されたパスワードなど全て取得できてしまうので、セキュリティ的に大丈夫かどうかが気になりました。

whereの場合

ruby

1 @user = User.where(account_name: params[:account_name]).select(:name, email) 2 3 if @user.present? 4 render json: { message:"ユーザーはいます。", name: @user[0].name, email: @user[0].email } 5 else 6 render json: { message: "ユーザーはいません。"} 7 end

2, whereとselectを組み合わせれば、検索するときにselectで取得するカラムを制限しているので、
@userに入るのは、nameとemailのみです。

まとめ

1,2が質問の内容ですが、要するに

クエリを投げるときに最終的に必要なデータを絞ってから送るか(whereとselect) or find_byで一致するけど、最終的にJsonで渡すときに成形をすればいいのか
ということになります。

セキュリティ的な観点からが気になります。もしどちらでもいいのであれば、find_byのほうが楽な気がしました。

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

ウェブのAPIでは、知らないうちに「返してはいけない情報を返している」という脆弱性は時々みかけます。通常時にそうなっているケースもありますし、特定の操作をするとそうなるケースもあります。前者は、たとえば膨大なJSONを返す場合に、よく見たら返していけない項目が混じっていたようなケース。後者は、Acceptリクエストヘッダを操作する(例えば appliction/json や application/xml に変更する)とそうなるケースがあります。おそらく高機能なフレームワークがAcceptヘッダに自動的に対応することで発生するのでしょう。これらは弊社の脆弱性診断で検出例がありますので、事実として存在した脆弱性です。

このため、セキュリティの観点からは、データ取得時に「できれば余計なものは取得しない」というのはよい作法だと思います。

投稿2021/06/08 11:43

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyako

2021/06/08 15:52

ご回答ありがとうございます。 非常に勉強になりました。 脆弱性の部分から的確なご回答頂けて本当に感謝しております。 一旦書いたコードを再度見直し、 取得したいものはまず決めて、クエリを投げるロジックを取ることとしようと思います。 ありがとうございました!
guest

0

どちらも変わりませんが、selectによって取得するデータを絞る事がパフォーマンスにつながる可能性はあります。

試してはいませんが

ruby

1@user = User.select(:name, :email).find_by(account_name: params[:account_name])

が出来そうな気はします。


@user = User.where(account_name: params[:account_name]).select(:name, email)

これは単数形の変数名@userに複数を入れるという時点で論外です。
limit(1)が付いていないことも気になります。
whereで単数のレコードを探すのであればtakeを末尾につける事をオススメします。
find_byと何も変わりませんが

投稿2021/06/08 10:51

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyako

2021/06/08 15:45

asm様 ご丁寧にありがとうございます! 一旦selectで絞ってから、find_byやってみます。 whereでもし複数取得するのであれば、 まず代入する変数を複数系に。 もし1つだとしてもlimitで明示的に1つのレコードと指定する必要があるというこですね!
guest

0

渡すデータセットが同じなら、どちらでも同じなのではないでしょうか。

投稿2021/06/08 09:30

winterboum

総合スコア23284

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問