is it safe to pass the user to view in laravel? - laravel

Is it? I mean if you get the user with $user = Auth::user(); and then send it to the view with return view ('somepage')->with('user',$user); the browser will get all user data in the view (uername, password, user_id etc..). I know you can then show what you like example {{$user->username}} but the point is, is the rest of the data somehow accessible to an 'hacker', 'script kiddie' or the likes?

Auth::user() is accesible from all views anyway.
Browser will not get all info like password, user_id etc. Browser gets only HTML generated by Blade template engine and it contains only things you want to share.
For example, you'll do {{ Auth::user()->username }}, browser will get username, but nothing else.

Related

Laravel Socialite - Use socialite to fill in fields and redirect back to the form without losing other information

I have a website, which has a form. Within the form, I have a button linked to socialite where a user can click on it and it will retrieve the name and email from Facebook. Then, I redirect the user back to the form to either fill in the remaining information or submit the form.
However, all of the other information is lost upon return to the page.
I have tried to pass a 'Request $request' within the function. However, it never actually gets the information as the button isn't exactly submitting the form.
Is there any way of ensuring that the previous information is pushed through to the Route and that this information is then pushed back to the redirect?
Here is my code so far:
web.php
Route::get('login/{service}', 'Auth\LoginController#redirectToProvider')->name('social');
Route::get('login/{service}/callback', 'Auth\LoginController#handleProviderCallback');
LoginController.php
public function handleProviderCallback(Request $request, $service)
{
$user = Socialite::driver($service)->stateless()->user();
return redirect()->back()
->with(['social' => 'social', 'name' => $user->name, 'email' => $user->email])
->withInput($request->all);
}
(Note: within the view, I am, of course, using {{ old('input_name') }} to get the inputs whenever the form fails after submission.)
Is there any way to get the information from Socialite and return back to the form without losing the previous information?
All suggestions, help, and comments are highly appreciated :)
Thanks!!
The problem is when the user is redirected to social provider, say facebook, the form data will not in that request, so when facebook redirects to the callback you will not find the form data there! ( facebook will not carry it for you )
You likely need to use some javascript here. look at hellojs

Laravel 5/ Form security (require clarification)

Not entirely confident I have understood security in Laravel forms enough. For example, if a form contains
<input type="hidden" name="user_id">
then obviously a hacker could change the value before submitting an update.
While I have looked here at CSRF, I've not fully understood if this is enough protection?
E.g. Taking the above, if I go to a site and open a form to edit a record I'm permitted to view but not change, and maliciously alter the "user_id", is it enough that the form is protected with {{ csrf_field() }} or must I employ some further security such as Crypt::encrypt($id) to hide the user_id (held in a database) and Crypt::decrypt($id)?
Is it considered a bad practice to expose a row id (like a user id) in a client browser (even though everything is sent over https)?
Many Thanks
No, it's not enough to use just CSRF token in this case. You also need to use policies, guards, middleware to protect your app.
In this case, someone can alter the user_id if you read it from the form and use after that, so you need to use a policy like this one to protect data (this example is from the docs):
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
Also, when you need to use user ID, always use auth()->id() or auth()->user() if you need whole object. Never read user ID from the form.
The Laravel framework stores the value of this CSRF field like a session variable and matches it when you submit it.
When you submit the form Laravel checks that value from the session value stored. if there is a mismatch an error is thrown !
:)
CSRF token protect the site from cross-site requests, means an external user can't duplicate the form and send a post request. Laravel create a random session token which we place in the hidden field using csrf_field() or Session::token() function. Laravel checks the session with hidden field value from the form before processing the form.
Try removing the form action. It should work.

Laravel sending id via route

I have posts, where users able to delete or edit them. And when I redirect them I was sending url with id number, like: test.dev/delete/15, where 15 is my id of post which should be deleted. Then I tested sending id in route like route('delete',['id' => $post->id]). In the end I realized that both methods include id number in url. I mean, for url it shows url test.dev/delete/15 and for route it shows test.dev/delete?id=15
So I was wondering if we can send id, without showing them in url, I am afraid that curious users may try to get use of these flaws
As you will always have to display the id somewhere on the page to send it through either a hidden field or id in the url all of which a user can change. That is why you should check in the Back-End if the user has privelege to delete that post or not

change laravel resource url

is there a way to customize Laravel 5 resource URLs ?
For example, change user/1/edit to user/edit.
That's because I don't want anybody to see the id in the URL. I think it is database information and shouldn't be revealed.
The point is that I want to do this without changing my routes. On the other hands I want to do this by using resource routes I have and not by adding some new routes to them , as you know when you define a resource route in your project it automatically adds some predefined routes to the route table and you are forced to use them in the way they are. For example you have to send a GET request to user/{user} for showing the user. Now I want to have a URL like user/{username} for doing this without adding a new route, IS THAT EVEN POSSIBLE?
if there is a way for achieving this I appreciate it if you share it here.
Thanks a lot
Since in most cases id is an auto incremented value and guessable, better you can use any other unique column of users table here, e.g username and then using that column instead of id in resource controller. Suppose you've an unique username column in your table So, if you use that instead of id your call to user edit will be like:
{!! route('user.edit', $user->username) !!} // let's say username is shahrokhi
which is equivalent to
user/shahrokhi/edit
Now for example, in your resource controller to edit a user details code may be like:
public function edit($username)
{
$user = User::where('username', '=', $username)->firstOrFail();
// rest of your code goes here
}
And so on for other methods.

Laravel Hide Div ID From View

On the page, there will be several posts by a user. Each post has an id # to identify it which is used when editing or deleting the post. With blade, I can make it so that hidden ID div only shows up when the authenticated user is on their own profile (since only they are allowed to edit or delete the posts).
However, I also have a liking feature that also uses that hidden ID div. I don't want someone to view the page source, change the ID, then click the like button. Is there a way to include the ID in the view, but not allow it to be changed?
I could try do to some validation on each like such as match the user, body, time posted, and ID and if that doesn't match then throw an error. Curious if there's a better way.
View:
<div class="post-like">
Like
</div>
Controller:
The $postId is that hidden ID div
public function getLike($postId)
{
$post = Post::find($postId);
if (!$post) {
return redirect()->back();
}
if (Auth::user()->hasLikedPost($post)) {
return redirect()->back();
}
$like = $post->likes()->create([]);
Auth::user()->likes()->save($like);
return redirect()->back();
}
It's not wise expose users' ID like this, but if you really need it, Laravel provides a way to handle users' action authorization. It can be done using either policies or model scopes.
Alternatively, you can ignore those authorizations and use UUID instead ID.
There is a nice package that handles it for you. Basically you'll just need to add a new field to the users' table.
In my applications I use both of them.
If I understand your question correctly, here's one idea: you can hide the actual post ID by concatenating your ID with some server-side only "key" and hashing.
For example:
In your app.php you add something like "post_mask_key" => "super_secret_123456"
...and in your code, something like:
$maskedPostId = sha1(\Config::get("app.post_mask_key") . $postId);
Then, share $maskedPostId with your view, which will be embedded into the HTML. The user can try to change it but when it is submitted, you can re-generate the hash easily (since you know both the key and ID server side) and compare the two.
Note: this approach is cryptographically weak but should be sufficient for masking a non-critical item like a post ID.

Resources