-
Notifications
You must be signed in to change notification settings - Fork 2k
Is the ACL working correctly? #1385
Comments
Just remembered - lower down in the policy is the line were we bypass all acl checks as long as the user is the same person that created of the article. |
On second thoughts there is a fault here! The fault is that as long as you make a valid request for a article once, this will act as the key to being able to do a subsequent illegal request. Note that the request that is checked is always the previously cached one. This is also true of the window.user https://github.com/meanjs/mean/blob/master/modules/articles/server/policies/articles.server.policy.js#L49-L54 |
@Wuntenn Can you describe the steps to reproduce this issue? |
@Wuntenn that part of the code doesn't show any key caching.. can you be more descriptive where do you think the problem is? |
If @Wunteen means that it is possible to modify the window user object and use this to bypass the server authentication, I briefly tried this and of course it did not work. |
Sorry I didn't explain the steps well. In your Facebook Dev Account set up a test app and add details for OAuth to your app. Whilst in FB select the app you created, add a test user. Then follow these steps: 1 - Log into the MEANJS app as your normal Facebook user using OAuth (from the details in the This is because of the way that our authentication works. Passport only deals with authentication but nothing after that point. It was designed and scoped to only handle this part. The problem is that we don't poll FB (or any of the other providers) beyond the point of login to revalidate their authentication when accessing or creating resources. This means that as long as you make a valid login, it stays active and doesn't switch appropriately with new OAuth sessions. |
@Wuntenn This seems like a very complex edge case. In most cases, when testing an app, the dev would just use their own FB account for testing. As you mentioned this is definitely behaving as designed. IMO, we can't expect to know exactly how a user would want the MEAN application to behave. If the user doesn't explicitly take action, then how do we know that the user doesn't want to remain logged in as the "original" logged in FB user? We can't assume anything in this scenario. @Wuntenn Can you explain a real-life scenario where this would affect an application's end user? How have other application developers solved such a problem? For devs, I don't really see a security/data-integrity issue. For end users, it doesn't seem like a typical situation. Perhaps, this could come up in a public/shared device. However, users in these cases should already be aware that they must log out of the application in question. Most of all, I think the desired behavior can vary greatly from one application, to the next. We should leave this up to the MEAN user to decide what is best for their application's needs. |
@mleanos It means that a userA can be logged into the app using any of the providers. That user may not explicitly log out. If another person userB whilst also logged into any provider and visited the app, they will be actually be resuming action(s) as userA. If I sit at an internet cafe and public machine and logged into Facebook then visit Trello or Slack or some service where I can use OAuth, I might be surprised to see other users details there. I would see it as a nice to-have if they recognised that I wasn't the original user and subsequently logged me out, but I wouldn't call this their fault (yet); it's more the fault of the user. If they failed to log me out and I was able to start using the service as if I'm that user and post on their behalf, also if that app has socket chat built in, there may be some entertainment value there! I don't see this as an edge case. With knowledge of this flaw, apps made with MeanJS could be targeted intentionally to access users personal information so it's definitely nothing other than a security risk. I've not been able to find implementations where people have implemented the remainder of the OAuth user flow past Passport login. Search results are quite noisy, however within the Facebook SDK they do mention the case in the second paragraph under the section "Roundtrips to Facebook's servers": https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus They use FB.getLoginStatus:
The FB SDK is easily added to the core as it's client based. It allows us to use the existing authentication and to hook into it at the stage we're at currently. I'm thinking, call like this could be wrapped into a middleware and chained into the routes just before the ACL to prevent new data from being accessed. Additionally (and optionally) we can implement a service that wraps the FB call. It would be attached to the core layout template and would use the expiry time as a trigger, checking user login status to automatically log them out if their OAuth is no longer active (we're able to subscribe to to user login events) |
@mleanos I've been considering which direction to move with my app. For a moment Facebook SDK seemed like a clear winner but then I looked into Google API and now... I'm confused. They both look good! One thing I've noticed is that they look like they are both moving away from OAuth in favour of asynchronously loading the JS into the page. I hardly see a reason to keep passport around. Both offer a similar snippet that simplifies the login process. Here the code to use the sdk: Facebook SDK: https://developers.facebook.com/docs/javascript/quickstart Both SDKs allow for the user login status to be polled after login:
I'll see how far I can get with a solution and share what I find. |
@Wuntenn IMO, MEAN or any other application has litte to do with it. A similar scenario is when user logs in using application specific credentials and leaves without logging out. Anyone can access the session !!. It is not the responsibility of application to keep session in sync with the authorization provider's session. And it shouldn't. |
I see your point if you want to say that developers should do it themselves - they should! However the whole point of using a MEAN Stack or the any of Frameworks that comprise it, is to solve commonly faced problems so that the community adopting the stack or framework gain by leveraging time and skills (best practice). @shanavas786 You're right it's not a problem specific to MEANJS. Anyone who implements authentication using Passport has successfully handled Authentication. However, there are more things to consider beyond authentication. IMO anyone who pulls user information from a secure source into a browser, subsequently has the responsibility of keeping that data safe! (hence, most/all users of this stack - common problem!) This project already considers authentication important to the point where this generic problem has been partially solved via integration of Passport. The rest of the problem being equally prevalent should be prioritised accordingly.
Again, you're right; This is exactly why both Google and Facebook have gone to the efforts of ensuring that their API's handle this case so that application developers don't have to. I'm not saying that we should invent a solution. I'm saying that we should incorporate officially implemented existing ones. A number of open/closed issues derive from problems caused by keeping the access token in sync and indicate the demand for a best practice solution like this. See issues: #1070, #1062, #288, #511, #1086, |
@Wuntenn can you please sum up in a nutshell the issue and your proposed solution? (also you can submit a PR with the fix so we can review what it entails) |
Passport does the authentication step which is all Jared intended it to do. However it is up to us to do things like:
There are quite a few attacks that make use of obtaining the token, (see fb vid linked above) so taking these kinds of steps at this level would encourage people to continue with best practice. I've got code doing all three for FB. The real-time call for detecting the user change of status is expensive and uses a flag. Trying to balance using this call vs the cached flag-less call which takes longer to poll. My code isn't using the latest version of MEANJS (now merging). I diverged so after going Angular Material. I should be able to create and submit PR's for each of the steps once I sort some time out. |
@Wuntenn Is this still an issue? I'm moving this to the back-log since there hasn't been any PR's open to address this. |
Thanks @mleanos. This should buy me some time. I have it currently logging users out after users switch devices or log out of their profile but it's not instant. It also logs them out after being inactive for a while. I'm not 100% happy with it. |
https://github.com/meanjs/mean/blob/master/modules/articles/server/policies/articles.server.policy.js#L28
The ACL for articles creates a whitelist for
users
methodsGET
andPOST
on the route:'/api/articles'
and aGET
only on'/api/articles/:articleId'
https://github.com/meanjs/mean/blob/master/modules/articles/client/services/articles.client.service.js
The angular client-side service creates the
user
methodPUT
for updating'/api/articles/:articleId'
.The documentation on the Angular side doesn't give any indication that the
PUT
isn't authentic https://docs.angularjs.org/api/ngResource/service/$resource (scroll down/ find in page:Creating a custom 'PUT' request
).I'm just curious how user is able to update using
PUT
when it's not been added to the ACL especially after seeing examples showing whitelisting ofPUT
in the documentation. https://www.npmjs.com/package/acl.The text was updated successfully, but these errors were encountered: