I am new to REST APIs, I am actually not looking for any workarounds, I just need to clear my concept because I know I am missing some very important information which can easily solve my problem.
For E.g I made a small website, let's say using angular.js, where I will list some information or some items.
Consider it as an open website for now, everyone is getting same list. Anyone can come to the page and see the list of items. Simple.
Lets say the URL to this list is
https://www.example.com/api/list/v1
Result returned
1. abc
2. cde
3. efg
4. hij
Perfect!
Now my site got traffic, and I decided to implement user thing on my website, so that every user can only see his own information.
So I changed the rest api url to this:
https://www.example.com/api/list/v1/12345
where 12345 is userid.
The user with the user id came on the website, logged in, and browsed the list, by chance he went to the source of the page, and he found the url to list information.
He copied the url and started to use different user id's, he might get lucky any time.
I am not talking about implementing any type of security up til now, there must be several ways to secure it.
My main concern is that isn't it a large security hole, or we can call it an invitation, for injections?
So I just want to clear my understanding, where I am wrong?
Thanks
This is not some security loophole. This is the way it is supposed to work.
Let's put aside the case of APIs. Consider the simple example::
I have a url: www.example.com/jobs/
This will list all the jobs on my website. No authentication or permission of any sort is required to access this data. I am providing it to every user that visits my website. Now I need a way to figure out if the user visiting my website wants to filter the jobs available on my website. So I provide this option in url kwargs. This will look something like::
www.example.com/jobs/java/
So, now the list will contain the data only for Java jobs. Plain and simple.
Now some day I decide that I will let only the registered users to view Java Jobs. So, I introduce a new check in my View that lets you access the java jobs only if you are logged into my website. Otherwise it redirects you to the login page. Depending on the requirement, you put restrictions on the data being sent to the user.
Same is the case with APIs. If you allow the data to be available to any user that uses the API, there is a flaw with your design and not with the concept of APIs. APIs are just the implementation of your logic.
If you don't want a user with id 12345 to access the data of a user with id 123, you have got to restrict the permissions on the API code. You have got to handle themselves. The API will respond to your code.
Hope this clears out everything.
Related
I have one account in docusign which has 3 users for it. We have a requirement of retrieving templates of users for that account. The Template:List API is retrieving all the templates of the account. There is also one path parameter named user_id but it is not retrieving the templates of particular user account instead it is retrieving all templates.
Is there any way through Rest API we will retrieve list of templates of user account?
If there Please provide the Rest API details or link.
From my own testing, it appears you're right. This could be a bug, I'm not sure and I'll follow up but this may take time.
Two possible workaround.
Make the API call in the context of the user that you wish you get templates. Basically, you'll need to obtain an accessToken for the API for that user. With JWT that is very simple, just use the userID when you ask for the token (but you do have to get consent).
Filter the list of templates you get. The list does include information about the owner of the template (again, userID) but you'll get all of them and have to do the work to find the ones you want.
(Update 5/26/2020: confirmed with engineering this is a bug. It is tracked under TT-3290).
(Update 6/23/2020: bug was resolved, will be deployed shortly)
I'm new to Piranha CMS and just trying to get my head around it. I'm using the MVC implementation and I need to do the following:
I need to extend the User with a property that stores an account number.
I need a page that is only accessible once the user logs in
On this page, I need to call a REST API on another server, using the account number a parameter, to retrieve a list of documents that the user has stored on this server.
When the user clicks the document, it will be downloaded as a PDF using the REST API once again
I just need general guidance on how to do this. How do I store the account number against the user (and manage this) and do I need to create a new Region that will show the list of documents from the remote server. Is there an example of creating a new Region anywhere and maybe returning a list from SQL that I can adapt?
Any help gratefully received.
Thanks in advance
Mike
The easiest way is to implement an extension with your custom fields that you attach to the user where you store this information.
When editing a page, go in under "settings" and select which groups should have access to your page. For this purpose I suggest creating a new group for site users that are not admins.
This should be easily implemented in either the controller or model for your page. When the user is logged in "User.Identity.Name" is the user id. Get the user, load the extensions & use the account number.
See number three.
Regards
I'm kinda surprised I don't see this in more REST discussions, but I'm debating how to best provide a list of things to a user, based on who the user is, or what they have authorization to see.
For example, let's say that we have an API for a bookstore. I might have a resource URL of /books which would list all books. But if my application logic is such that some books are viewable to users who are anonymous, but others are only viewable to those who are logged in, I'm a bit more uncertain the best way to go.
Obviously, programmatically I could filter based on the identity of the user (gleaned from their API key or whatever creds I'm using) but I feel like that's a bit 'off' from the standpoint of REST design.
Feels more right to have two endpoints; let's say one for /books/public and one for /books/restricted and we can say that the latter returns a 401 if the user isn't logged in. Easy enough.
But that pattern breaks a bit if the books in question are just a list of books that the user has read or has bought or have some other relation to the user. I've seen some API's that would do something like /my/books in that case, but that (again) feels off since the /my/books isn't a unique URL per se, it changes based (again) on a header value (API key, etc).
This leaves me to think that maybe the "best" approach is to do something like /books/users/1235 or /users/1234/books to get the books that 'belong' to user 1234, and then return a 401 if someone not authenticated tries to hit that URL, or a 403 if they're authenticated but not authorized to view that resource.
I guess that's a lot of background to my main question: What's the best practice for REST API URL design when the resource data is dependent on user identity?
Rest is not a standard so there is technically no right or wrong way to accomplish what you're after. Having said that, I'll give you my opinion.
I propose you simply use /books unless there is a very specific need for a service or user to see which are unique to them and those that are public. In which case I suggest doing all three. The fact that there could be more or less content at the /books endpoint based on the user's privileges doesn't alter the intent, it enhances it.
But that pattern breaks a bit if the books in question are just a list of books that the user has read or has bought or have some other relation to the user. I've seen some API's that would do something like /my/books in that case, but that (again) feels off since the /my/books isn't a unique URL per se, it changes based (again) on a header value (API key, etc).
I believe providing a /my/books endpoint is ideal if the content is intended to be private. If your reading list IS private and specific to your account then having an endpoint without that is masked significantly dramatically reduces the risk of having user-identifying information leak via the url.
In the event that reading lists can be shared then you would want there to be a a discrete action. If a user wishes to share their reading list or a subset therein they would compose the list and a new endpoint would be created specifically for it like /book-lists/xxxx-xxxx-xxxx. If your user's reading list is public by nature then /my/books would simply redirect to /booklists/xxxx-xxxx-xxxx
This leaves me to think that maybe the "best" approach is to do something like /books/users/1235 or /users/1234/books to get the books that 'belong' to user 1234, and then return a 401 if someone not authenticated tries to hit that URL, or a 403 if they're authenticated but not authorized to view that resource.
I'm not sure if you are referring to the reading list or the first concept of filtered results by some form of credentials.
/books/users/1234 would suggest a correlation to users from the book's perspective. This would be more applicable for authors or publishers, people that are actually affiliated to books in some deeper connection other than your examples above elude to. The same logical connection, for me at least, applies to /users/3493/books but to a lesser extent.
I think as a general approach, you should scratch both of these out if you have any desire for the public links to be shared. You are potentially making a very convoluted structure that could ultimately result in people getting really confused why their friend can't see a list of novels because she sent her search results with a url had been "personalized" and thus secured.
Obviously, programmatically I could filter based on the identity of
the user (gleaned from their API key or whatever creds I'm using) but
I feel like that's a bit 'off' from the standpoint of REST design.
No, it is not off, because the credentials are part of every request and the response can be dependent on request parameters...
The url depends on whether you want to share personal data with others:
if you want to share the url
/users/{userId}/favouriteBooks/
/books/favouriteOf:{userId}/
if you don't want to share the url
/books/favourite/
Keep in mind that you always can change the url structure as long as your service applies the HATEOAS principle...
I have this question in mind and I wanted to get other developer's opinion on this issue.
For creating a user (like in Facebook or creating an account in Gmail), some people suggested to have an public/private (means we don't tell developers how to use it) action in API for it. I, however, think it is a security risk as even if it is not documented, a hacker can simple see the calls and http requests when our front-end app is using that api action to create a new user (using a web debugger like fiddler) and can find the url to that action so simple ! like this POST ~/api/user/create
and then he/she can send thousands of requests to create user, users needs to be verified but still he/she is adding a lot of junk users in our database and puts a lot of pressure on our servers.
So the question is how do we handle this? Allow this only on our website or what?
Thanks
You can use CAPTCHA to verify that's a real user.
I have a website and I want to accomplish the following:
my site's server is able to uniquely identify the viewer of the website (assuming he is currently logged in to FB). NOTE: I don't need any personal information. I just need to know that he is unique. So if he comes back again tomorrow, I'll know its him.
based on this unique identification, store data in my website's database about his actions (eg. he uploads something etc).
my site should also be able to know if he has "liked" an item on my website.
A) Is the above possible at all?
B) If Yes, is it also possible that my site doesn't use "facebook login" for my site, and still achieve items 1 to 3 above? My understanding is that users can "like" and "comment" (using the social plugins) without the need to explicitly "FB LOGIN" on my site.
Reason for my asking question B is that I want to make using my site as seamless as possible (ie. don't have to "ask" users to give app access to my site to their information)
A) Yes
B) No, it is possible with the facebook API to add simplified user sign-in and registration. A user will still need to confirm/allow the link to be made.
You can find more info here: https://developers.facebook.com/docs/guides/web/#login
Funny thing, StackOverflow uses several of these APIs for it's users...