RESTful PUT and hacking the URI - security

I'm learning about RESTful interfaces. To update a server resource, say for a Contact with (id = 1) I'd PUT it:
PUT /contact/1
Now suppose the current user belongs to Organization 1, which owns Contact 1. There is also Organization 2, with Contact 2. The current user doesn't belong to Org 2 and has no rights to it. If the user hacks the web page (using Firebug for Mozilla or the "F12 debugger" for MSIE) and changes the web page request to point at /contact/2, the browser will merrily submit the request.
My server must protect against such cross-organization attacks. In my current web site design, once the user logs in I store a data object in the session (I'm using Tomcat/Java). That object stores which organization the user belongs to. Safety checking code compares the organization for the passed-back PUT request against the organization the user belongs to and sees if the passed-back data belongs to the user's organization. On detection of a hack (the user for org 1 is trying to modify contact 2, belonging to org 2) an error is returned to the browser.
I understand that REST is supposed to be stateless, but I'm currently using some state. Yet, if I pass the user information into the web page I think that this, too, can be hacked through Firebug, et.al.
How to achieve this safety without invoking server state?
Thanks,
Jerome.

RESTful services are usually stateless.
This means that every request has to be authenticated with an apikey or something else.
So the request will be /path?apikey=MYKEY and the server will handle the rights of that apikey.
By the way I've also tried stateful rest services, and the server is able to understand the session by a cookie initialized during the login (but that's not really RESTful).
If you want to try them with curl do something like:
curl -c cookie.txt -d "user=username&password=pass" "my.login.path"
curl -b cookie.txt "do.something"

Related

How is Application insight tracking the User_Id?

Im running a Azure Webapp with application insight.
I know Microsoft cant show the real IP (Client_IP) so I add the real IP address to all requests (Ip).
I have a visitor client_id="h9zbt" that in the last 24h is using 48 different client_IP adresses.
The same user also has several real IPv6 adresses.
I like to block this IP from my website, but I think this looks so strange.
Is it really the same user?
How is Application insight tracking the User_Id?
Image link
Usually application insights is automatically opening a session automatically for each user (look for the ai_session key). Therefore the default user scope would be a session scope.
You can override this behaviour by sending a user context if you have some kind of sign-in. (https://learn.microsoft.com/en-us/azure/application-insights/app-insights-usage-send-user-context)
I find it likely that it's the same user on the same device, just using several IP-addresses, maybe as an unsuccessful attempt to stay anonymous.
User IDs should persist across user sessions to track how users behave
over time. There are various approaches for persisting the ID.
A definition of a user that you already have in your service.
If the service has access to a browser, it can pass the browser a cookie with an ID in it. The ID will persist for as long as the cookie
remains in the user's browser.
If necessary, you can use a new ID each session, but the results about users will be limited. For example, you won't be able to see how
a user's behavior changes over time.
The ID should be a Guid or another string complex enough to identify
each user uniquely. For example, it could be a long random number.
If the ID contains personally identifying information about the user,
it is not an appropriate value to send to Application Insights as a
user ID. You can send such an ID as an authenticated user ID, but it
does not fulfill the user ID requirement for usage scenarios.
mentioned in Azure doc.
https://learn.microsoft.com/en-us/azure/application-insights/app-insights-usage-send-user-context

Obtaining Instagram Access Token

We have a client who has a simple Instagram feature on the site to pull photos by a certain tag. They just noticed it isn't working. Getting an error - invalid access token. I guess since the 1st because of the updates. We didn't used to need an access token since we're not doing anything with users - just tags.
Now it looks like we need one and the documentation makes zero sense on how to obtain one. And it seems like they're not accepting most apps. The app is in sandbox mode too. So I'm assuming it's because it got switched to that? Got no notification of this happening.
The first step in documentation to get an access token is "Direct the user to our authorization url." What does that even mean? There's not a link provided or anything. It also says "Company Name, Contact Email and Privacy Policy URL are required to start a submission." Our app doesn't have a privacy policy... it's just a simple tag feed. I don't understand why everything is so complex to have a simple tag feed.
Is there a wait time to get the app approved..if it gets approved... Do I have to have it approved before getting an access token? This isn't outlined anywhere.
You got it right. As of June 2016 any Instagram API calls require an access token.
Getting an access token is described in the documentation. App approval is not required.
There are two ways to get one: server-side or client-side. The second option (called implicit authentication) can only be used when implicit OAuth is enabled in the client settings (Manage Clients > Edit Client > Security > Disable implicit OAuth). It is disabled by default.
In either case you need to redirect the user to the authorization URL to obtain an access token.
The URL for explicit mode (server side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
The URL for implicit mode (client side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
After this you will be redirected to the REDIRECT-URI, which will be passed an argument. For explicit mode this will be a query string with a code, while for implicit mode you will get the access token directly as a hash:
http://your-redirect-uri?code=CODE
http://your-redirect-uri#access_token=ACCESS-TOKEN
For implicit mode you can then get the access token from the window.location.hash in Javascript.
For explicit mode, however, you need to further process the code to obtain the access token. You can read how this can be done in the API Documentation. I'm not going to take this any further here.
The problem is that every user who wants to see your feed needs to login to Instagram (and have an account) in order to view it. In your case this might not be desired. However, there are a few options to get around this (rather annoying) problem:
You can reuse your own (already obtained) access token(s) to display the Instagram feed for every user. You will need to be aware of rate limits for each token. For sandboxed apps this is 500 API calls / hour, while live mode allows 5000 API calls / hour. [source] You could store tokens in a table and use them in a round-robin manner, to allow more API calls. This involves manually obtaining a bunch of tokens which your application can use (the more the better). This might not be the ideal solution considering Instagram doesn't warrant access tokens to have an unlimited lifetime.
You can retreive JSON data without authentication by appending /media/ to a user page URL, as described in this post. No tokens or client IDs are required for this to work. However, this only works for users, not for tags. Besides, Instagram doesn't document this feature so it is not garanteed to work in the future.
You can use an aggregator like Juicer or Dialogfeed instead which will handle access tokens for you. This is usually not free of charge.
I'm also in the process of making an Instagram feed for my website, and this is what I concluded from my research. Please bare with any errors I made.
Edit: Here are some more limitations for sandbox apps.
In sandbox mode you can only access data from sandbox users (thus users who received a sandbox invite). This means that:
Media retreived by user, e.g. /users/{user-id}/media/recent, will return an empty response if the user is not any of the sandbox users.
Media retreived by tag, e.g. /tags/{tag-name}/media/recent, will only contain tagged media belonging to sandbox users.
Thus, for a tag feed to work, it needs to be live (reviewed and approved). If you don't want to do this, the only alternative is to use an aggregator as I mentioned above.

Adding Social Login to Shopify

I wish to add Social Login feature to a Shopify store that I am building. (I'm using the professional plan.)
I explored a few of the available social-login apps on the Shopify App Store. Upon studying closely as to how they actually work - I have come to the following understanding of the general scheme being followed by all of them.
The Shopify shop owner sets up a social app (e.g. Facebook app) with their store identity, but configures the Callback-URL/Redirect-URL to one supplied by the App author (i.e. pointing to their infrastructure).
Upon successful login by a shop customer on the social platform (via a link/button inserted on the shop login page), the request gets redirected to the App.
The App retrieves the user's email address from the their social profile (that they now have access to).
They then lookup their own database to see if this is an existing customer. If so they go directly to step 7 below.
If it's a new customer, they use Shopify API to create a new 'customer' on the target Shopify store. They set the customer up with a randomly generated password.
At the same time they also make an entry of this customer account (email + generated password) in their own database.
They then redirect the request back to the Shopify store's login page but this time with the customer's email address (retrieved from social platform) and their password (from the App's own database) included as part of the data that comes back to the users browser as part of loading the login page.
Then the App's javascript embedded on the shop login page uses the customer email address and password to programmatically submit the login form - thus establishing a valid customer session on the Shopify shop.
My questions are as follows:
Has someone else also looked closely in to this, and thus can validate if my above understanding is correct or not?
If it is correct - is this the only way to achieve social login on Shopify (without using Shopify Plus/Enterprise plan)?
I am trying to understand if this indeed is the only way, because I strongly feel that this method is not at all secure. And thus I'd rather not use this method; or if I just have to - then I'd rather write my own (private) app for this so that at least I am in control of the security of the app/database that holds sensitive users credentials.
Would appreciate any help/thoughts I can get with this, please.
If you are rolling your own you probably want to look at Multipass. It would be the thing to use if you can set up another web service that handles the trusted partner registration process.

Deployd: How to implement dpd-passport and securely authenticate

Let me start by saying I really like Deployd. I want to use it in production, but I want to incorporate OAuth and social logins, so I installed the dpd-passport module. It works great, except for two little (big) problems:
When a user signs in via an OAuth provider (e.g. Facebook, Twitter, Github) a new user record is created...but if the same user clears their cookies or uses a different browser to log in, a new user record is created.
If I do something clever (read: hacky) and assign users with social logins an ID based on the socialAccount and socialAccountId (something unique but constant for each social account), someone could use the standard method of user creation to spoof a user by making a POST request to the /users endpoint if they knew that user's socialAccount and socialAccountId.
My question is: How can I A) prevent #1 from occurring, or B) disable the standard method of user creation without also preventing OAuth user creation?
Has anyone ever successfully used Deployd and dpd-passport in production? If so, I want to speak with you...
Thanks in advance!
First of all, I think you haven't added the custom fields per the docs.
https://www.npmjs.com/package/dpd-passport#requirements
I hadn't either, and observed the new user feature (because it couldn't lookup the response from the auth service to find the user from before). Adding these fields fixed it.
Also, there is a google group here:
https://groups.google.com/forum/#!forum/deployd-users
Hope that helps.

Auto authentication through email link

I have written an agent which takes the username and authenticate user, if authentication is successful then it redirects to the actual URL of the database.
For taking name of the user, I am using #Formulas. Hence, I can use my method of authentication in any link or hotspot or button in Notes Client. But, I face problem to send this method through reminder email links.
When I create a URL through backend agent, this URL/hotspot should have my code with #formula. In simple words, I want to pass #Dblookup inside URL/hotspot through my email link. How to accomplish this task ?
Or is there any alternative to get user name if any person clicks a link in his email ?
Only Notes client has to be used.
Edit#1: Adding scenario for better explanation:
Our users are not happy to re-authenticate themselves for web applications. So, we have been trying something like if they want to open a webdoclink, which they got through their email in notes client, so they shouldn't be asked to authenticate again (since they have already logged into notes client).
We could achieve this for static application links, where application name is not changed. Now, the challenge we are facing is how to do it for reminder emails, which have links to particular web document (links here are not static. They are differed by unique document ids).
For this to work, we need shortname of person who clicked that link from his email.
You probably need to be sending an Action hotspot instead of a URL hotspot; but it is very difficult to guess without seeing what your code is really doing. Also, I believe that creating an Action hotspot probably will require copying it from a previously saved rich text field, perhaps in a profile document and appending it to the rich text body field of the message you are sending. (That's a technique I've used in the past to create action hotspots, anyhow. I'm not sure if there are better alternatives.)
And since this is for Notes client recipients, the other technique that I would probably explore is the use of a store-form-in-document message instead of an ordinary email message. That way you just need to have a button containing the #DbLookup on the form that you send in the message.
I agree with leyer. The ACL (Access Control List) is the main tool to use to decide functionality. For instance a user can have access to the db. Then you can define who can create databases, create emails. It is best to use the ACL so you can also use Roles and other tools. Basic LotusScript can access the ACL on open events or do a test in buttons.
Regarding the scenario you are describing, if the issue is that users have to re-authenticate for every web application on the server, you would be better of implementing SSO/Session based authentication on the server then coding this workaround. With Session based authentication, users only have to authenticate once.
From the admin help:
Session-based name-and-password authentication sends the client's name and unencrypted password, and is sent with each request to the server. Session-based authentication differs in that the user's name and password information is sent over the network only the first time the user logs in to a server, not each time a request is posted. After login, the user's name and logon information is stored in a cookie in the user's browswer, and the browser sends the cookie to the server with each request. Before honoring a request, the server verifies the information in the cookie and uses the cookie contents to identify the logged-in user. The session is only valid within the browser in which the login was performed. If the user shuts down the browser in which the session login took place, the user's session will be ended and the cookie will be destroyed.
Using session-based name-and-password authentication provides greater control over user interaction than basic name-and-password authentication. For example, you can customize the form in which users enter their name and password information. It also allows users to log out of the session without closing the browser.
If you are using windows based servers, you could even implement SPNEGO, automatically signing the users in using der Windows account, therefore eliminating login prompts completely.
With Domino 9, you also have the option of using Security Assertion Markup Language (SAML) to configure federated-identity authentication.
In your case, I would start with Session-based name-and-password authentication to solve the multiple-login issue.

Resources