Saving information from being compromised by url change - asp.net

In some webpages or views, I have information displayed in table. Column values are rendered as links.
Problems:
When I hover over the link, it's URL is visible at the bottom of browser.
When I click on link, I show information for the resource requested in URL. (www.someurl.com/Employee/67 gives me information of employee with id = 67).
Now, this URL is displayed in browser. If you change URL to www.someurl.com/Employee/88, it shows information of employee with id = 88 though the logged in user is not supposed to see information for employee id 88
This are serious security breaches.
I am thinking of following as possible solutions:
URL masking at application level
Base64 encoding of URL to shorten and obfuscate it, so that users can't just throw values in the URL.
#Html.AntiForgeryToken() and ValidateAntiForgeryTokenValidation mechanism
Is there better and more secure approach other than above to solve this issue?

Check in Controller serving www.someurl.com/Employee/88 if currently authenticated user has access to Employee with ID 88 and throw exception if he does not - no need to mask url.

If the user is not supposed to be able to see the employee with the id of 88 then they should not be able to see the information for the employee with id 88. The URL is more or less irrelevant and is in your case only giving them an obvious clue as to how to gain unauthorised access to data in your system.
You need a proper security plan where data is only served from the database to the UI via the business layer if the logged in user if authorised to see that data.

Here is my idea about your first approach security breach:
Mix your id with some GUID or complex structure while sending it, and when you receive it, took out your id from this and then proceed. [ Your masking idea]

Related

How should I name an endpoint that checks whether a user has authority to edit a resource?

The background first:
I have an application where a logged-in user(employee) X can see a list of all other users (employees). If the logged-in user X is a manager (their designation), then they can also edit certain attributes of the users they manage. For example, the location, designation, and the department of the user being edited. It should be noted X can edit only those employees who report to him/her, which means there are users which X is not allowed to edit.
When X clicks on a user to edit it, they navigate to a page like http:myapp.com/dashboard/editUser/<ID_OF_THE_USER_BEING_EDITED>
Obviously, X can get smart and manually edit the URL and put in the id of a user they are NOT allowed to edit, so before loading the edit form I need to check whether X has the authorization to edit user Y.
if X is authorized to do so, then that page displays a form (with the current attributes of the users pre-filled in the appropriate fields) to edit the user. Else, I display an 'Access Denied' kind of message.
Right now I have created a very badly named temporary endpoint (/api/v1/maybe_edit_user/?jwt=<TOKEN>&userId=<USER_BEING_EDITED>).
This grotesque-looking endpoint does 2 things:
It extracts the currently logged-in user from the token, and checks whether it has the required access level to edit the user (passed through the GET parameter userId)
If yes, then it returns the current attributes (name, email, location, designation, and other stuff) in the response, which is then pre-filled in appropriate fields when the form is displayed.
Once X submits the form, a PUT request is sent to another endpoint (/api/v1/users/<USER_ID_OF_Y> PUT) and the user Y is updated.
While this works, I don't find it attractive. I am trying to learn to write better, cleaner, and more organized code that is compliant with the standards.
The best practices for REST suggest that all endpoints should be nouns. My endpoint, on the other hand, is not even a simple verb. It's a god-forsaken phrase at the very minimum.
So, the questions here are:
How should I name my endpoint.
Should I use a single endpoint to check for permission, AND fetching the attributes of the user being edited, like I am doing right now? Or should I break them into 2 separate endpoints?
The fact that there is an access control list is an unrelated concern; ignore it.
Resource identifier identify resources. Resources are generalizations of documents.
You want an identifier that is consistent with the production rules of RFC 3986, and it is often convenient (but not required) to choose spellings that enable leverage of URI Templates (RFC 6570), but otherwise the machines don't care.
That means you can choose a spelling that makes things easier for humans; you get to choose which humans get priority here.
it returns the current attributes (name, email, location, designation, and other stuff) in the response
That's your hint as to what the document is; some sort of digest of Bob's... profile? employee record? dossier? that is apparently optimized for use in this specific kind of form.
So the identifier could be as simple as
/this-specific-kind-of-form/source-data/Bob
and a request might look like
GET /this-specific-kind-of-form/source-data/Bob HTTP/1.1
Authorization: Bearer <token>
The implementation looks largely like your sketch - verify the token, compare the claims to those that are required, and return either the resource or some flavor of Client Error (4xx).
The best practices for REST suggest that all endpoints should be nouns.
Don't read too much into that.
Notice that all of the following resource identifiers work:
https://www.merriam-webster.com/dictionary/get
https://www.merriam-webster.com/dictionary/post
https://www.merriam-webster.com/dictionary/put
https://www.merriam-webster.com/dictionary/patch
https://www.merriam-webster.com/dictionary/delete
You can click on any of those links, and your browser will create the correct HTTP request, and the server will do the expected thing.

Linkedin profile image url giving access denied

I have used Spring social for integration with linkedin.
When the integration completes we save the users profile image which has below url:
https://media.licdn.com/dms/image/C5603AQHQ0C7xKhQehg/profile-displayphoto-shrink_100_100/0?e=1527508800&v=alpha&t=vkxX_3Uw7qe8d_9ZSqPwQGpwa6nfUmkzMgEKtMdgf1g
But this url is giving access denied error. Is there something I am missing?
This may help, As per https://developer.linkedin.com/docs/ref/v2/media-migration,
The new id will be dynamic and can change from time to time. We recommend retrieving at least once every 60 days to update your media-typed URN.
This could be one of the issue which you might be facing.
In order to fix this, I save the image, the moment it is received on to personal storage(AWS S3).
I looked at the URL of my picture of my In Public profile and the one returned from the API.
The picture URL in the XML returned after the ? for params v and t had &amp ; instead of &:
e.g.
https://media.licdn.com/.../profile-displayphoto-shrink_200_200/0?e=152800"&amp";v=beta"&amp";t=LJTrw_oj9npH06X1u0HjQ
Replacing it with something like:
pictureURL = pictureURL.replaceAll("&amp ;","&");
fixed the issue for me.
Hope this helps
Note that there is an extra space between &amp and ;. It would have formatted otherwise.

ASP.NET MVC URL query string parameter renaming

I have looked through SO and the internet in General and I can't seem to understand whether the following is possible
I have a link to an action:
Link to Subject
This works fine, I can use the id, to get the Subject and all other info I need for the model.
In the browser it shows:
http://www.example.com/Main/Subject/1
This is just fine, but it is not pretty or very helpful for the user.
I would like to be able to look up the subject from the Id in the Action and modify the URL to look like:
http://www.example.com/Main/Subject/Science
Is this possible and if so, could someone give me a steer on where to find out how to do it.
I cannot change the parameter to a string because the subject name is not unique, only the id.
well you can use the dBprovider feature in urlrewrite 2.0 forr iis 7 and above. what you have to do is create a table in database that store both urls i.e
'http://www.example.com/Main/Subject/Science'
and
'http://www.example.com/Main/Subject/1'
it will match with the url you want to show 'http://www.example.com/Main/Subject/Science' and redirect to the actual url i.e is to 'http://www.example.com/Main/Subject/1' for more info check this
http://www.iis.net/learn/extensions/url-rewrite-module/using-custom-rewrite-providers-with-url-rewrite-module

Passing a Session Variable via a URL (ASP.Net)

I have an aspx page, which is a "User Log-In" area. I want to pass the userid to another page which is linked from the aspx page.
the link I have looks something like this:
www.abcdefg.com/Home/Redirect/?authtkn=123456abcd=xxxx
I need the xxxx to be a session variable which in this case is userid.
**userid is not sensative information, this is simply to redirect the user to another page for specified information.
Any thoughts on how to pass a session variable to a URL, or if this can be done. The example www.abcdefg.com is a different domain (on a different server) from the original aspx page.
Why not appending like this?
string.Format("www.abcdefg.com/Home/Redirect/?authtkn=123456abcd={0}",
Session["UserId"]);
if i understood you correctly.
Think your question is how to maintain cross domain session or authentication.
Check this link Maintaining Session State Across Domains, may give you some idea
Or this one How can I share a session across multiple subdomains?
You don’t need to pass a session variable via the url. You can just start session on the next page and have access to all your session variables! If you do want the variables up there so you can quickly get to different userids with just a quick url change, send userid to the url on your previous page with with $_GET[ ].

Restrict page access only can enter from a specified page?

I am kind of new to ASP.NET.
I wonder is there any way to restrict user can only enter from a specify page?
Like, I have a Page A to let them enter some information, then when submit, I will use Response.Redirect to Page B. But I don't want the user can go into Page B directly from URL....
If I use Session, then if the user didn't close the browser to end the session, the another user can just go into Page B directly...
Because the computer that access to these pages is using by the public, so I want to see if there is anyway to make sure they only do one way process? Can't go back to previous or jump to another page.
Thanks in Advance.
If you control the other page, start a session and set a session variable to a value that can be reversed that only your server could (or should) create, much like serial keys. For example 72150166 because the sum of every second number equals the sum of every other number (7 + 1 + 0 + 6 = 2 + 5 + 1 + 6) but you could choose an algorithm as complex or as simple as you want. When the user navigates to the second page, check the session variable. This is not invincible security, but it is better than checking the referrer (especially since some browsers do not set it) and I imagine security based on coming from a certain page doesn't have to be that strict.
Edit: You should also add it to a database and link it with the particular user's IP so someone else can't use the same key.
You can use Request.UrlReferrer property in the Page Load of PageB to see which page is the request coming from. If the request is not coming from PageA then redirect the user to PageA.
Check this link for more information: http://msdn.microsoft.com/en-us/library/system.web.httprequest.urlreferrer.aspx
Note: UrlReferrer is dependent on a request header and someone can set the header to mimic the request coming from PageA.
You could have the page that redirects send some sort of specifically generated hash/key in the query string that expires quickly and/or once viewed. This should be a lot more solid on the security side.
You will still need some way to store this key or value producing the hash so you can validate it on the receiving end- I would think your DB.

Resources