Home > OS >  Is it necessary to protect destroy method in Laravel from an authenticated user that did not create
Is it necessary to protect destroy method in Laravel from an authenticated user that did not create

Time:09-23

I have the following middleware in my PostController.

public function __construct()
    {
        $this->middleware('auth')->except(['index', 'show']);
    }

I understand any authenticated user can still edit a post by visiting localhost/posts/{post}/edit so I've protected that by the following code.

 public function edit(Post $post)
    {
        if(auth()->user()->id === $post->user_id){
            $categories = Category::all();
            return view('edit-post', compact(['post', 'categories']));
        } else{
            abort(403, 'Unauthorized.');
        }

    }

Now, I'm wondering is it necessary to protect the destroy method? Is it possible for an authenticated user to delete a post they didn't create in this case? If they can could I kindly know how they can?

My destroy method

   public function destroy(Post $post)
    {
        Storage::disk('public')->delete($post->imagePath);
        $post->delete();
        return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
    }

CodePudding user response:

First, you should be read about Laravel policy, which will make your code more clear.

For destroy method,

I will give you an example, you can try it BTW

post_table

id user_id title
1 40 Post1
2 50 Post2

If the user id: 40 tries to delete the post witch id is id: 1 there is no problem, BUT let's say the user knows about the web app and just changes the id in the URL localhost/posts/2/delete, He/She will delete any post without policy.

CodePudding user response:

one easy way to protect all your methods that need authentification is to use relations.

You are sending a post id in the URL by use model injection to preload $post from DB. Avoid that and use the id of the post yourself

public function destroy($postId)
    {
        $post = auth()->user()->posts()->findOrFail($postId);
        Storage::disk('public')->delete($post->imagePath);
        $post->delete();
        return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
    }

The route will return a 404 if the post id is not one of the user owned posts.

Same for the edit

public function edit($postId)
{
    $post = auth()->user()->posts()->findOrFail($postId);
    $categories = Category::all();
    return view('edit-post', compact(['post', 'categories']));
}

As for the change in response code 404 instead of a 403, it is on purpose, since the user is authenticated and you dont want any user to know if another post with random ID that is not his exists or not hence 404. like if he put a non existing post id to delete or edit.

  • Related