LoginSignup
0
0

Rails 別のユーザーの投稿を消せてしまった件

Posted at

はじめに

  • 製作した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が一致しなければ投稿一覧へリダイレクトするように設定。

スクリーンショット 2023-07-09 18.36.45.png

これで、仮に、悪意あるユーザーが「url直打ちで消してやる〜」なんぞ思っても大丈夫。
気づいてよかった。

まとめ

  • 脆弱性があると、urlで不正なアクセスがなされてしまう
  • before_actionなどで、不正アクセス対策を忘れずに

⚠️学習4ヶ月目の初学者による投稿です。
⚠️間違いがあるかもしれません。ご容赦ください。
⚠️ご指導、ご教授いただけると幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0