Angular 5 Best way to hide credentials in Http Post Method - http

For an Angular 5 application, I am hitting a login web API with the credentials. I am sending the user credentials in request (POST) body. The credentials which I sent is clearly visible in browser form data. How can we hide the credentials while sending to API?
Form Data in Browser(image)

I think there's basically two ways to treat credentials in a secure way (and it's not angular dependant):
The whole connection is end-to-end encrypted, i.e. using https as transfer protocol, making use of SSL to encrypt the data. I think you would still see the value in your console, but no-one else should be able to detect.
You don't store / send the password itself, but an anonymized version of it. I.e., you would store the hash of a password in a database, and as of that, you would also hash the value entered in the password field and submit that one.
So, I would conclude it's less an issue in terms of your angular (frontend) design, but more of the overall (security) architecture of the application middleware.

Related

Next.js restrict the api to my next.js application and my mobile app

Let me clarify my use case:
I have a next.js application which is a plattform for listing real estate objects. I have several api routes which im using inside my next.js app. for example:
/api/createpost ->
Takes informations from my form on my next.js app and creates a database entry to perform a new post
/api/getposts ->
fetching all the real estate posts from my database and displays it
/api/login ->
logs in a user by checking the credentials in the database and sends a jwt
/api/register ->
registers a user by taking the credentials from a form from my next.js app, registering a user and creating an entry in my database
Now in order to secure my apis I want to make sure to check if there is a valid user session if anybody is calling one of the apis (except the register/login api) to get the expected result. Im doing this by calling the /api/login route and getting a valid user session. Until here everything just works fine. Apis like the /api/createpost can only be called if we have a valid user session.
Now I want to create a mobile app and I want to use my api routes from above to provide full functionality in my mobile app too. It should work the same, if i want to call the /api/createpost on my mobileapp for example, i need a valid user session.
But I want to restrict my api by asking for a key in my database which is pointing to my app and saying okay if you call the /api/createpost api, first of all i need to verify that its the mobile app asking. The mobile app will provide the key in the request then.
I didnt try this yet, but it should work i think. Now the big mess: If we call the /api/createpost and the api wants a valid token to check in the database, which will work for the mobile app, because we are giving it a valid token to check in the database, how can we provide a token if we are calling the api from inside our next.js application? Since I have to do the api call clientside, there is no way for me to provide a secret key or something to validate that the call is coming from my next.js application.
If your application is private
(to be used only by you or a few select people)
You can send a private API key over SSL with each request from your application to the server and verify it. Or you can limit your API to only accept requests from certain IPs.
If your application is public
Unfortunately there's no way to determine where the request is coming from, since anything your app can send, an attacker can send it manually.
Think about it, if your app is trying to make a request to your API, any user can intercept this request before its sent out of his/her machine, and send the exact same request from a different app on the same machine.
You might say, well I can encrypt the requests and responses so that they are of no use to the attacker. But such an encryption will require either a key that's already agreed upon, or some way to provide a new key at the beginning of each session.
If the key is already agreed upon, the app must contain it, as you've already guessed in the question, the attacker can retrieve this key no matter how well you try to hide it.
If the encryption key is a new key provided at the beginning of each session, that's almost how SSL works, your browser handles this transaction. Your server sends a public key to your browser to encrypt the requests which the server can then decrypt with a private key. In this case you've circled back to the same problem, how can you verify to whom you give out an encryption key? What would stop an attacker from requesting the encryption key?
There has to be some way you'd be able to design apps that don't require this restriction. I think the question you should be asking isn't how to restrict your api to a certain app, but how to design apps that don't require this restriction.
We might be able to help you out if you could tell us why you need this restriction.
Update
There is actually a way to verify that requests are coming from your app, but not with an api key.
For Webapps
You can use Google's reCAPTCHA to verify a user on your /register and '/login` routes, and provide an access token or start a valid user session on successful captcha response. With reCAPTCHA v3, you could even verify every user action without interrupting the user. This eliminates both the problems I mentioned in my answer above -
You don't have to store an api key into the app/web app.
The request can't be spoofed as it requires human user interaction within your app. The captcha verification success will arrive to your API from Google's reCAPTCHA server, not from your client app. This communication will be authenticated with a pre-mediated private API key shared by Google to you, which works in the same way as to how you authenticate your external domains.
For Android apps
A similar way to achieve the same thing would be via Android SafetyNet Attestation API. This checks the runtime environment and signs the response with a dynamically generated nonce that your app provides the SafetyNet API.
Please read its docs carefully to understand how you could create potential security loopholes and how to avoid them while using this API.
For iOS apps
DeviceCheck works in a similar way, except the device validity is provided to you by Apple server.
Important edit: "secured" is not the right word here! You cannot tell that a request comes from your app just because the domain is yours. The domain name is not a safe information, as it can be altered easily. See #Mythos comments below.
Initial answer:
Web applications access is secured not based on an API key, but based on a whitelist of domains. That's how we achieve security, because only you have access to the domain where you host your own application: so the request has to be coming from an app you own.
If you try some 3rd party services that provides API for web apps, that's often how they'll work: they will let you configure a set of whitelisted domains that can access your data.
If they provide you an API key, this API key is always meant to be used by a server, not a client-only app.
So if I understand you question correctly, you would do like this for each request:
Check the domain. If it's in the whitelist, perfect, you can keep going. This is meant for web apps (look for "CORS").
If not, check for a valid API token in the headers. This is meant for any app that can store this API token securely (another server for instance, or a mobile app in your scenario though I don't know mobile enough to tell how you store such a key)

What is the surest way to authenticate (login) via HTTP?

First of all, I am sorry for my bad English.
I am writing an app with a backend, which I want to make safe. I am using HTTPS for the connection, but a lot of people say that this is not enough protection.
At the moment, my user credentials are sent to the server via JSON format as plain text, which isn't a good way, I guess. At the server, my password is hashed with a random salt and stored in the database.
If the login is successful, an authentication token is generated and sent to the client. The client is using it as a header.
Do I need to do more? I read something about digest access authentication. Should I implement this authentication method, or is there a better way to make my login safe? Or is this the right place to use this authentication method?

ASP.NET Web API 2 - How to implement OAuth2.0 for SPA applications

I am trying to implement WEB API 2 (for Single Page App, not as part of Visual Studio project) OAuth2.0 protocol. As per Which OAuth 2.0 flow should I use, using refresh tokens is not an option. However, I am not sure I understand Implicit Grant flow with eventual Silent Authentication.
Does Implicit Flow mean only issuing normal access tokens? In that case, how do we allow user to stay logged in for long time? How should Silent Authentication endpoint look like, what should it receive and return to client? Is using refresh token really an issue - most of people have their usernames / passwords saved in browser?
Does Implicit Flow mean only issuing normal access tokens? Yes.
In that case, how do we allow user to stay logged in for long time? You can set timeout using "expires_in" parameter.
Refer for Complete Detail here: https://oauth2.thephpleague.com/authorization-server/implicit-grant/
How should Silent Authentication endpoint look like, what should it receive and return to client? Upon authentication of the user during login, the server sends & set the authentication key in the session/browser. So, during every page call, only authentication key is send to server. You shall find many examples of implementation online.
Is using refresh token really an issue - most of people have their usernames / passwords saved in browser? No, it's not an issue. If token expires, you can easily reissue token after authentication. Password & username is not saved in the browser. Only authentication key is stored.

Authenticate native mobile app using a REST API

Like the Facebook application, you only enter your credentials when you open the application for the first time. After that, you're automatically signed in every time you open the app. How does one accomplish this?
There's a commom line in all auto-login implementations
Upon an initial login, a token is received and stored on the client side
Upon subsequent visits, if token is available on the client side, the server resolves the identity and logs in automatically
Now concrete implementation variations can be numerous. The token can be a session ID (encripted or not), OAuth token, custom token, username and password should be avoided. Storing token can be on within a browser cookie, browser local storage, can have a server counter-part. Security is the major concern. Generally about the topic you can read more here https://softwareengineering.stackexchange.com/questions/200511/how-to-securely-implement-auto-login
You have an interesting explanation of how does Stackoverflow do it https://meta.stackexchange.com/questions/64260/how-does-sos-new-auto-login-feature-work.

Asp.NET WebAPI custom authorization

I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.

Resources