I'm reading the API for a web service, and all methods involve sending an HTTP request to
https://example.com/api/APIVER/METHOD?apikey=APIKEY&user=USERNAME&password=PASSWORD
To be clear, both the API key and user password are sent in plain text via the URL. But is this OK because "all HTTPS traffic is encrypted" or not because they're still in plain text or because the URL is somehow different?
If this isn't secure, what is the minimum change the API maintainer needs to do?
Yes, HTTPS makes this more secure.
HTTPS makes this more secure.
You should also send sensitive parameters as POST parameters instead (HTTP BODY) of GET query string ones. Typically the query string will be logged by Web server logs (server side) in plaintext, so it will be accessible to system administrators that perhaps shouldn't be able to see it.
HTTPS will encode the URL in each request, so if you are worried about network sniffing then you're OK. HTTPS also adds a nonce value, so you aren't exposed to reply attacks.
It would be possible, depending on infrastructure to insert a fake SSL certificate that's trusted by the user device and route requests through a proxy using that certificate. However this would require admin/root access to the client machines to make such a certificate trusted (barring breach of a normally trusted CA), and once something needs admin access all bets are off anyway.
It's still not a wonderful idea though, I'd be concerned about developers forgetting to configure it for HTTPS. You have an API key, so why not take the password and hash it using the APIKEY as the salt. Now for the API calls the salt is a password equivalent but it would mean that the username and password couldn't be used for logging into elsewhere with those credentials, for example the web site that the API is running off (assuming you let users log in there of course.)
Even better would be to use a shared secret that doesn't go over the wire at all, and use that as the salt.
Related
I am developing a backend for a mobile application using Node.js to handle HTTPS requests. I have set up an SSL to connect from the client to the server and was wondering if this was secure enough.
I don't have experience with intercepting endpoints from the mobile devices, but I have seen that it is possible for people to monitor internet traffic out of their cellphones and pick up endpoints to server requests. I have seen hacks on tinder where people can see response JSON and even automate swipes by sending http requests to tinder's endpoints.
My real concern is that people will be able to update/read/modify data on my backend. I can implement OAuth2 into my schema as well but I still see cases in which people could abuse the system.
My main question is whether or not using HTTPS is secure enough to protect my data, or if a session authentication system is needed like OAuth2.
Thanks.
HTTPS, providing it is properly configured, will ensure the message was not read or changed en route and that the client can know the server it is talking to is not a fake.
It will secure the transport. It will not secure the application.
For example supposing you have an app that allows you to send a message saying https://www.example.com/transfermoney?from=Kyle&to=BazzaDP&amount=9999.99 and the server does just that based on those parameters. Then I could send that message myself - I've no need to intercept any app messages.
Normally the server needs authentication as well as HTTPS to, for example, verify only Kyle user can send above message and not anyone else. HTTPS normally only gives server authentication not client authentication (unless using two way certificate HTTPS).
So the question is, even if an attacker cannot read or alter any messages between app and server can they still cause harm? That is the measure of whether it is secure enough.
A SSL connection is only secure with the content you are sending.
SSL encrypts and ensures the authenticity of the whole connection, including the requested method and URL
So i would say just using the SSL encryption is save to transfer data between - i might consider OAuth2 for password etc.
But i would recommend to use GET for retrieval data and post for authorized data
You're building an armored tunnel between two open fields.
Assuming that you use current SSL protocols and settings, and valid certificates from trusted issuers, you can pretty much assume the network is OK.
However it's still entirely possible to compromise any or all of your transaction from the client. Security really depends on the device and how well it's configured and patched.
I have exposed some rest services in spring, using spring mvc, I have secured the webapp using spring security, that uses bcrypt on the server to encode the password and store it in the datbase.
The user will send the password in the url in plain text under https, And i have written a custom basic_auth_filter to check the uername and passowrd - basically authenticate. I also have set up a firewall that only allows one ip to connect.
Im no security expert, is there anything else i need to, should i encode the username/password in the url.. even though it will be coming via https?
regards
ps. this was a requirement to use username on the url?
Passwords, and all other non-ephemeral credentials, should never be sent in the URL, if for no other reason then because the browsers and other HTTP tools and servers will remember this in history, various logs etc, HTTPS or not, making it trivial to steal by anyone with local access, or even by someone just looking over your shoulder. This is why Spring by default rejects authentication via GET requests.
For this reason, you should move the sensitive parameters to the body of the request (thus requiring a POST).
If your login flow is based on username/passwords, I recommend you use UsernamePasswordAuthenticationFilter as it already encapsulates the logic and best practices for this type of flow.
In general your scheme is secure.
Consider pinning the server, that is validating the server certificate, to ensure the connection is to your server.
The password should not be used other than to authenticate using (in your case) bcrypt.
Re question update: "HTTPS encrypts the query string, only the actual server address portion is un-encrypted. But, the full URL including query string will probably be logged by the server so that has security implication. It is best to send confidential information in a POST.
https://blockchain.info/api/blockchain_wallet_api
Is it normal to essentially pass your username and password in the URL of an http.post? I'm using the blockchain.info api to send and receive bitcoin transactions on my website. Everything works, but I'm still uneasy about how their service is set up to send out payments. Seems vulnerable?
No it isn't normal, but it will be encrypted as it is sent over TLS.
Usernames and passwords in the address are usually avoided as URLs are often logged on their journey (e.g. by servers, proxies and browsers) but only systems that have a certificate trusted by your client machine can view the full URL over HTTPS (only source and destination will be exposed on the way).
The Base URL for all requests: https://blockchain.info/fr/merchant/$guid/.
The API endpoints are available through HTTPS, so every bit of data you send there (including the URL) is encrypted and protected from man-in-the-middle attacks, I'd say this is safe enough.
I am developing Restful API layer my app. The app would be used in premises where HTTPS support is not available. We need to support both web apps and mobile apps. We are using Node/Expressjs at the server side. My two concerns are:
Is there a way we could setup secure authentication without HTTPS?
Is there a way we could reuse the same authentication layer on both web app (backbonejs) and native mobile app (iOS)?
I think you are confusing authenticity and confidentiality. It's totally possible to create an API that securely validates the caller is who they say they are using a MAC; most often an HMAC. The assumption, though, is that you've securely established a shared secret—which you could do in person, but that's pretty inconvenient.
Amazon S3 is an example of an API that authenticates its requests without SSL/TLS. It does so by dictating a specific way in which the caller creates an HMAC based on the parts of the HTTP request. It then verifies that the requester is actually a person allowed to ask for that object. Amazon relies on SSL to initially establish your shared secret at registration time, but SSL is not needed to correctly perform an API call that can be securely authenticated as originating from an authorized individual—that can be plain old HTTP.
Now the downside to that approach is that all data passing in both directions is visible to anyone. While the authorization data sent will not allow an attacker to impersonate a valid user, the attacker can see anything that you transmit—thus the need for confidentiality in many cases.
One use case for publicly transmitted API responses with S3 includes websites whose code is hosted on one server, while its images and such are hosted in S3. Websites often use S3's Query String Authentication to allow browsers to request the images directly from S3 for a small window of time, while also ensuring that the website code is the only one that can authorize a browser to retrieve that image (and thus charge the owner for bandwidth).
Another example of an API authentication mechanism that allows the use of non-SSL requests is OAuth. It's obsolete 1.0 family used it exclusively (even if you used SSL), and OAuth 2.0 specification defines several access token types, including the OAuth2 HTTP MAC type whose main purpose is to simplify and improve HTTP authentication for services that are unwilling or unable to employ TLS for every request (though it does require SSL for initially establishing the secret). While the OAuth2 Bearer type requires SSL, and keeps things simpler (no normalization; the bane of all developers using all request signing APIs without well established & tested libraries).
To sum it up, if all you care about is securely establishing the authenticity of a request, that's possible. If you care about confidentiality during the transport of the response, you'll need some kind of transport security, and TLS is easier to get right in your app code (though other options may be feasible).
Is there a way we could setup secure authentication without HTTPS?
If you mean SSL, No. Whatever you send through your browser to the web server will be unencrypted, so third parties can listen. HTTPS is not authentication, its encyrption of the traffic between the client and server.
Is there a way we could reuse the same authentication layer on both web app (backbonejs) and native mobile app (iOS)?
Yes, as you say, it is layer, so it's interface will be independent from client, it will be HTTP and if the web-app is on same-origin with that layer, there will be no problem. (e.g. api.myapp.com accessed from myapp.com). Your native mobile can make HTTP requests, too.
In either case of SSL or not SSL, you can be secure if you use a private/public key scenario where you require the user to sign each request prior to sending. Once you receive the request, you then decrypt it with their private key (not sent over the wire) and match what was signed and what operation the user was requesting and make sure those two match. You base this on a timestamp of UTC and this also requires that all servers using this model be very accurate in their clock settings.
Amazon Web Services in particular uses this security method and it is secure enough to use without SSL although they do not recommend it.
I would seriously invest some small change to support SSL as it gives you more credibility in doing so. I personally would not think you to be a credible organization without one.
In Securing an API: SSL & HTTP Basic Authentication vs Signature HTTP Basic Authentication is cited as an adequate way to secure REST web service calls if the REST calls are made through SSL.
But it seems this method will still not work for an unsecured client page that uses Ajax to make calls to the REST service that is protected behind SSL & Basic Auth.
I am trying to design an application that performs password reset using the usual way:
user enters username and requests "reset password" email
user receives email with a password reset link that includes a verifiable token
user clicks on the link and (after the token is verified) types in their updated password
By definition these pages do not require login. Can this UI be implemented using Ajax that calls REST services to do things like validate token, send email, etc.? Even if those REST services are protected behind SSL & Basic Auth, the information that you need to call the service (i.e. the application's "username" and password) will be at best in cookies which would be accessible through the browser.
I know I am missing something. I just don't know what :-)
As long as 1 - 3 happen under SSL, the data will be safe over the wire to the server (assuming you trust the certificate authority)
During that process, the browser will hold those credentials in memory. You have no choice but to trust that if the user is going to enter the data.
It is the web sites code that determines whether to store info in cookies.
I think you should be OK if 1 - 3 are under SSL.
I've no idea what you're protecting so I'l just toss some thoughts out.
SSL and TLS are not meaningful if you (or someone else who gives a hoot) aren't in control of the root list of the relying party. I say this because I expect that if you don't trust the guy with the key to the lock then you won't put your money in his vault. So if the users loading the login pages are in the wild so to speak then user/pass through TLS is a low bar, definitely good enough for protecting my favorite movies list.
Carby praises to the all being FSM