RailsのStrong Parametersでやってはいけない書き方!初心者でもわかるpermit!の危険と安全な書き方
生徒
「Railsでフォームの値を受け取るときに、Strong Parametersって使うみたいですが、permit!って書いたら全部許可できるって聞きました。」
先生
「確かにpermit!はすべてのパラメータを許可する強力な方法ですが、とても危険な使い方なんですよ。」
生徒
「危険なんですか?書き方が楽だから便利だと思ったのに……」
先生
「便利そうに見えて、セキュリティ上の大きなリスクがあるんです。今日はその理由と、安全な書き方を丁寧に解説していきましょう。」
1. Strong Parametersとは?
Strong Parameters(ストロングパラメータ)とは、Railsのコントローラで受け取る値を明示的に指定する仕組みです。
これにより、想定外の値が勝手に保存されるのを防ぐことができ、セキュリティを強化できます。
例えば、ブログ記事を保存する場合、次のようにparamsから許可するキーを指定します。
def post_params
params.require(:post).permit(:title, :body)
end
:titleと:bodyだけを受け取るようにし、それ以外の項目はすべて無視されます。
2. permit!とは?なぜ使ってはいけない?
permit!は、すべてのパラメータを無条件で許可するメソッドです。
次のように書くと、送られてきた全データを一気に許可してしまいます。
def post_params
params.require(:post).permit!
end
これは非常に危険なコードです。たとえば、悪意のあるユーザーが管理者フラグ(admin)や、他人のuser_idを勝手に含めて送ってきたとしても、それらがそのまま保存されてしまいます。
3. permit!の危険性を具体例で確認
たとえば、次のようなユーザー更新フォームがあるとします。
<form action="/users/1" method="post">
<input name="user[name]" value="山田太郎" />
<input name="user[admin]" value="true" />
</form>
そして、コントローラ側でpermit!を使っていた場合、
def user_params
params.require(:user).permit!
end
悪意のあるユーザーが管理者になれてしまうという、大変な問題が起きます。
4. 安全なStrong Parametersの書き方
permitで明示的に受け取る項目を一つひとつ指定するのが基本です。
def user_params
params.require(:user).permit(:name, :email)
end
このようにしておけば、:nameと:emailしか保存されないので、予期せぬ項目が登録される心配はありません。
5. ネストされたデータを扱う場合もpermitを使おう
たとえば、投稿と一緒にタグの情報を送るといった、ネストされたパラメータも、安全に扱うことができます。
def post_params
params.require(:post).permit(:title, :body, tags: [])
end
tags: []のように配列として許可することで、指定されたデータだけが保存されるようになります。
6. 管理者だけ許可したい項目はコントローラ側で分岐
「管理者だけが:adminを更新できるようにしたい」といった場合は、条件分岐で対処します。
def user_params
if current_user.admin?
params.require(:user).permit(:name, :email, :admin)
else
params.require(:user).permit(:name, :email)
end
end
このようにすることで、一般ユーザーにはadmin項目が反映されないように防止できます。
7. Strong ParametersはRailsセキュリティの基本
Strong Parametersは、Railsで安全にデータを扱うための基本的なセキュリティ機構です。
面倒だからといってpermit!を使ってしまうと、アプリケーション全体が乗っ取られる危険性もあります。
初心者のうちから、明示的に項目を許可する癖をつけることで、安全なWebアプリを作る力が身につきます。