I developed a web application that has a "demo page". One of the business rules is to get rid of the login/password thing to the trial users - while requiring the user to have a valid e-mail to start the trial and log all the user's actions individually.
In my mind, it was easy: let's just use a "token" in the URL as a parameter. We ask the user to enter the e-mail and then send the access link with the generated token - pretty much like an API, but instead JSON and XML, we display an HTML with JS. Same thing in my mind.
Like this:
https://www.example.com/trial?token=abcdef123456
It was running well until I noticed that google had indexed one of our access links with a valid token. How?
For me, this is VERY strange. We have APIs that use the same functionality - passing the access token in the URL - for years. Google's and Microsoft's APIs works just like this. The only difference is that I am returning HTML instead of JSON.
We have digital certificates, HTTPS with SSL/TLS encryption. We use RNGCryptoServiceProvider to generate a secure token. We only send the tokens over a secure channel (e-mail or inside our https website).
What could have happened? And what can I do to prevent it?
My guess: Google Chrome, maybe?
Its is likely that one of your clients, whom you sent the access URL with embedded token ended up posting it to a forum/blog/page which eventually got indexed.
Scenario:
For eg. I got your URL via email and decided to blog about how cool your service is and list the URL to let people take a look at it. Google bots come scrape my blog page, come across your link, go visit it and then index it against all relevant keywords that are on that page. Next, when one searches for a relevant keyword pertaining to your website/business, this URL is displayed as a search result.
Self Test:
Try searching for that exact URL on google to reveal any page that might list it.
Remediation:
robots.txt
Why doesn't this happen for your JSON APIs: APIs are for machine consumption. Developers know the significance of a API key. Unless a developer is careless/stupid enough to post the API endpoint with the api key in it on a blog, its not likely this will happen.
In case of a 'demo' link, a business person might not know if he is not supposed to forward this link unless you state so in the email.
Related
I'm completely new to ASP.NET Web API. I've done some research but I haven't been able to find an answer to my problem. I am starting to become very confused about how to secure the data that is being responded to the caller.
My overall objective is to create an ASP.NET MVC web application and a Xamarain Android application that allow users to register and login into an account and their data stored in a MySQL database.
I thought that a Web API would be a good solution as both applications could call functions to get a collection of users, an individual user and put new users into the database through HTTPPost, HTTPGet requests.
So far I have created an ASP.NET Web API with one controller and one HTTPGet request which returns all the users from the database.
When I run it I get a response of all the user's details.
My Controller Code
public class UsersController : ApiController
{
// GET api/values
[HttpGet]
public IEnumerable<Users> Get()
{
using (NorthYorkshireContext context = new NorthYorkshireContext())
{
return context.Users.ToList();
}
}
}
My Response:
If I were to deploy this to a server what is stopping anyone from seeing all the users details? For example, If I deployed this to http://mydomain.co.uk what is stopping anyone from querying the API like http://mydomain.co.uk/api/users and seeing all the details?
P.S I understand passwords should be encrypted, sorry if this is a bad question.
This question reads as "I created a publicly accessible API endpoint that outputs my entire users table; why are APIs so insecure?". Why did you create this operation in the first place? What problem does it solve? When I make a human-sized hole in my house, can I rightfully complain that after a few days my computer and television are stolen?
For each API endpoint you must consider:
Do I need this? I really can't figure out why you would need a list of all users.
Do I need this to be publicly accessible, or should it be limited to localhost traffic (i.e. infrastructure)?
When publicly accessible, who may access it (authorization)?
When called, should it return all columns that are in its data source, or should there be some kind of mapping?
And no, passwords don't need to be encrypted, they need to be hashed. Use ASP.NET Identity for authentication, don't roll your own.
an API is a perfect solution for what you are trying to do.
When you build an API, that is exposed to the outside world, you need to secure it somehow. This is where something like OWIN, OAuth2 come into place.
A token based system (JWT) is usually a good solution to secure the API. I would start with some reading on the subject if I were you.
Once you secure you API from unauthorized access then you need to think what data you should provide to the users / apps who have the right to access it.
Having passwords in clear is a huge security risk, sending them to the app is an even bigger risk.
Normally you'd let the users authenticate, you would not send passwords to the app.
Make sure your API works over https and do not send anything private in URLs, use POST requests and put the sensitive data in the body.
Security is a big topic, I am afraid.
I am quiet confused about how to find the technical solution of my business need. I just want to be able to give third party web apps a temporary URL to a specific user so he can access his account without log in.
I have though about a certificate that I use for every external portal. So When I get a request from them with a specific address I send them a redirect URL that is available for 5 minutes.
My application is build over .NET MVC.
Could somebody help me find out how to implement this need ?
You could generate a token and set an expiry date and send the token as query parameter and create an authorization attribute class to check if you have the token and it is valid or any other authorization you have.
You have many ways to do it but you can begin with Basic Authentication which I ended up implementing. I advice you to read the whole tutorial, any misleading could end you up to a non working code with lots of headaches.
If you need more powerful security you can go for Certificate Authentication where you have to provide your clients with client certificates.
These link1, link2, could be useful too if you don't have experience dealing with certificate generation and implementation.
Introduction
Okay so I've got a website (PHP) with a database (MySQL). You can create an account on this website and edit your details and so on (let's say date of birth, real name, address, and so on).
Now, what I wanna do is to create a desktop application (most likely c# with WPF) that interacts with a REST api (in PHP) from the website, which will allow to :
Create accounts directly from the application
Log in to your account
Be able to edit your details directly from the application
As of now I only want to do a desktop application, but it might evolve into a mobile app. I don't think that is relevant though.
Creating accounts and logging in
I'm struggling with the create account / log in part. I want it to be as secure as possible. On the website, I'm using password_hash(PASSWORD_BCRYPT) with a cost of 10 to store passwords in the database, and password-verify to check log ins.
Regarding the application, I imagine the way to go is to pass the username and password to the REST api and do the encryption directly on the server side. But sending the password itself sounds terrible so I thought about encrypting it with a secret key that only the application and the website know, so the website can figure out the password and encode it correctly in the database.
If I'm right, what encryption algorithm should I use? If not, how should I do that?
Edit your details directly from the application
I'm thinking about doing the following : Let's say the user has logged in through the application. If the authentication is successful, the server randomly generates a token (I'll probably use ircmaxell's Random-Lib) and send it as a reply to the application. From then onward, when the application wants to make a request to the api, it adds the username to the datas string, and generates a hash (sha256 for example) with the data string plus the token; then the server can repeat the exact process using the token stored in database to make sure the user actually has the right to access/modify his details, and nobody is trying to pretend to be an user he isn't.
I feel like the problem is, if someone listens to the first api reply after the authentication, he gets the token and can use it to act as if he was the user. Would encrypting it with the same process used for the password be enough to make sure this can't happen?
Last but not least, if I want the user to be able to be directly logged in the next time he starts the application, I guess I have to give the token a permanent durability and store it in a file or something on the computer. But that doesn't sound really safe because anyone could just read the file content and figure out the token.
Final questions
So. What do you think ? Does it sound good or am I completely off the tracks?
The website hosting is in http://* so I guess using HTTPS communications is not an option here. I know that's a big problem to create something really secured, but I'd still like to make something as safe as possible with what I have.
Thanks a lot for your advices. :)
Btw I tried to make this as clear as possible, hope it worked. I have close to pretty little knowledge of security, encryption, ... so you'll have to speak like to a 3 years old to me.
I think the first, most important piece of advice I could give is to never try to roll your own security code, unless you are an absolute expert. You'll want to put together a solution based on the frameworks that .net provides for you.
First things first - your REST API. I'd suggest building on top of ASP.NET Web API. HTTPS is mandatory here - if your hosting provider can't give it to you, you need a new hosting provider. It also conveniently takes care of encryption for you.
There are various security options available for ASP, I'd read this for a detailed overview: https://docs.asp.net/en/latest/security/. Using the existing ASP options will also take care of your requirements around user account creation and self-service.
What are some ways to go about signing into a website that you did not build yourself using C# code. All I can really tell about the site is that it is ASP.net. Using Google Chrome, I can poke around the structure of the site. Under the Resources tab in Chrome, in the Cookies section, I see things such as: ASP.Net_SessionId, SiteAuthCookie, user_IsCultureSet, user_RptParams. Wasn't sure if those could be utilized. I know with certain URL's, you can append the username & password to the end of the string, but I figured that is not always plausible with every site. I've never attempted anything like this, so I had no idea where to start. Any ideas?
It depends on whether the site uses forms based authentication (manages its own username/password database) or an external authentication server.
The easiest way to find out what goes on when a user logs in is to start Fiddler or the debugging tools in your browser and look at the requests being made.
I need to implement authentication for some web services that we will be hosting. I want to use open standards, so I am interested in OAuth.
I will be using WebAPI for these services.
So here's where I'm running into trouble: Most (or maybe all) of the Api Key/OAuth scenerios that I have read involve (at some point or another) a user sitting in front of a screen.
I need to put together an API that a business partner will be calling. The calls will come from an automated process -- nowhere in the chain will there be a person who can be redirected to a web site with logon credentials.
However, I don't want just anyone coming around and calling my services.
So, I read about OAuth, and how it uses a shared secret to sign each request, and I think that's what I'm after. (I would either set up a session key, or could consider making one of the parameters a "ticks" value, and only accept requests within a short timeframe, etc)
I was kind of hoping that I could use DotNetOpenAuth to accomplish this (or something like it), but every example I come across begins with "the user gets redirected to a login page). I only need "2 leg" authentication.
Is there an example of using DotNetOpenAuth to do this?
Is there a better way to go?
If you are looking at OAuth 2 then the flow you are describing is the Client Credentials Grant
This kind of "two legged" / "service account" type flow is one that doesn't have a web page based flow.
DotNetOpenAuth supports the Client Credentials Grant. You can see an example of it in action here; however, be aware even though the author states it is the "Resource Owner Password Credentials" grant it is actually the Client Credentials Grant.
The blog post above was a little out of step with the latest DotNetOpenAuth code base but these are quickly identified and altered.
I believe that as it stands the DotNetOpenAuth only supports issuing a Bearer token using Http Basic authentication. There are other more exotic extensions OAuth 2 with a similar flow e.g. the JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (but as stated this is not yet part of DotNetOpenAuth).