はじめに
- 製作したSNSサイトで、urlの直打ちをすると、他人の投稿編集画面に潜入できてしまった
- その対策をとった、学習したことの備忘録
修正前
posts_controller.rb
before_action :authenticate_user!
before_action :set_post, only: [:show, :edit, :update]
# 省略
def edit
end
def update
if @post.update(post_params)
flash[:dark] = "あなたの投稿を更新しました!!"
redirect_to post_path(@post.id)
else
flash[:danger] = "更新に失敗しました。"
redirect_to edit_post_path(@post.id)
end
end
def destroy
@post.destroy
flash[:dark] = "あなたの投稿を削除しました"
redirect_to user_path(current_user.id)
end
private
def post_params
params.require(:post).permit(:post_image, :explanation)
end
def set_post
@post = Post.find(params[:id])
end
このままでは、editもupdateもdestroyも、「before_action :authenticate_user!」によって、ログイン認証されたユーザーであれば可能になってしまう。
補足
authenticate_user!
・deviseのメソッド
・ユーザーがログインしているかどうかを確認
・ログインしていない場合はログインページにリダイレクト
修正後
posts_controller.rb
before_action :authenticate_user!
before_action :set_post, only: [:show, :edit, :update]
# 追記
before_action :ensure_correct_user, only: [:edit, :update, :destroy]
# 省略
private
# 省略
# 追記
def ensure_correct_user
@post = Post.find(params[:id])
unless @post.user_id == current_user.id
flash[:danger] = "この投稿への編集権限はありません。"
redirect_to posts_path
end
end
上記のように、privateに「ensure_correct_user」メソッドを定義。直訳すると、「正しいユーザーを確保する」なので、可読性としても申し分ないと思われる。
ここでは、
unless @post.user_id == current_user.id
によって、投稿のuser_idと現在のユーザーのidが一致しなければ投稿一覧へリダイレクトするように設定。
これで、仮に、悪意あるユーザーが「url直打ちで消してやる〜」なんぞ思っても大丈夫。
気づいてよかった。
まとめ
- 脆弱性があると、urlで不正なアクセスがなされてしまう
- before_actionなどで、不正アクセス対策を忘れずに
⚠️学習4ヶ月目の初学者による投稿です。
⚠️間違いがあるかもしれません。ご容赦ください。
⚠️ご指導、ご教授いただけると幸いです。