Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm putting together read and write methods to my database and exposing them via URL (I'm using CodeIgniter framework and using URL segments to pass parameters to these methods). The original idea was to have my Ajax script call these methods. However, now I am thinking I could potentially expose these methods to any developer.
What should I do to make sure only authorized developers use my API? I'm thinking they should pass an API key and possibly password to each method call. If I were to provide them with such details, would that be secure enough?
Also, I'm thinking that I should support POST instead of GET as some of the required parameters may not fit in nicely with URL segments. Thoughts?
Implementing OAuth http://oauth.net/documentation/getting-started/ would work for what you're trying to do. I'm not certain of what type of data you're securing, but I agree with TradyBlix this probably best. I've implemented it before, it's not too hard to figure out, it's well documented with many APIs that handle user-data utilizing it.
Another thing you should think about is limiting API Keys to domains, so a developer can only use their API key from their own domain-essentially preventing an unauthorized developer from gaining access, at least without gaining access to an authorized domain and corresponding key.
First: require HTTPS.
HTTPS ensures that a secure channel is established before any request data is sent. Yes, before any request data is sent: URL, headers, cookies, GET or POST parameters... anything. This means that you can use simple methods such as HTTP Basic authentication over HTTPS without putting the user's credentials at risk.
This is really not negotiable, unless the data you are passing over the API is truly public. If you aren't using HTTPS, then any communication with your API (including HTTP Basic credentials) can be sniffed in plain text.
The only reason major sites (like Facebook) don't use HTTPS is because it gets expensive at massive scale.
If you absolutely can't run HTTPS, then you should look into OAuth, which is making strides in API authentication in exactly this situation. With OAuth you can authenticate users while keeping credentials secret over unencrypted channels.
Second: authentication is not authorization.
Don't blindly trust data from authenticated API users. Make sure that the methods and actions they are accessing are appropriate, otherwise you may give your users a backdoor into other users' data or administrative functions.
There's a lot more to it than this, but if you follow these two principles you're on your way.
Maybe you should check out OAuth. It's An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.
I haven't tried it myself to be honest but it's the first thing I thought of when you mentioned authorized developers use my API. Just an idea.
Related
I'm developing an API service and I would like to allow the users to restrict access of their tokens by domain, so an API key can only be used from one site/domain/host (it could be a server calling the API, not necessarily a browser), like Google Maps API allows you to do.
Now my question is, how do I check which host/domain the request comes from - in PHP (Laravel) - so I can compare it to the allowed domain(s) or pattern?
Is $_SERVER['REMOTE_HOST'] the right variable to check? Or should I look at a request header? Like $_SERVER['HTTP_ORIGIN'] though that seems to be browser related and, if I'm not mistaken, another client (a server or Postman for instance) would not necessarily have the Origin header, while $_SERVER['HTTP_HOST'] is not required and can be faked.
Edit: just to be more specific, I don't think this additional check on the requesting domain is supposed to replace the access token for auth, but it is an additional layer of protection and helps with token management and misuse - a user might have multiple tokens for different clients/apps calling your API so this way you can discriminate the traffic.
If Google can do it I assume there is a way for implementing it. Could it be not possible in PHP? I don't know, but I was hoping somebody here could suggest a way to implement this check/restriction, maybe underlying the limitations of the proposed solution. Even if the solution is not 100% reliable (again it is not suppose to authenticate the client) it would still help improving protection - in fact Google considers it best practice to "protect" the API keys this way.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have a very limited understanding of PHP, as well as the internet for that matter. I'm wondering if someone could simply send a POST request to my PHP script (assuming its public). Wouldn't that have the potential to mess up my entire script?
Answer: YES.
The end.
I think this question comes from some security concerns that are not being worded.
First off, know you can check the request method (a.k.a HTTP verb) with $_SERVER['REQUEST_METHOD'].
Second, you can send HTTP request from the browser, or from other software with whatever request method, to whatever public server (read: reachable on the network). And yes, you can handle other things aside from GET and POST in PHP.
I have found the browser extension "Requestly" useful for testing.
You might be interested in Cross-Site Request Forgery and Cross-Site Scripting.
Let us talk mitigation...
It should be evident... but: validate all input. Do not trust that the input comes from a well intended user of your own site.
After validation, it could be necesary to have a sanitation step. For example, if you are going to display the values you got from a request to your users, sanitize the input so it does not contain HTML code. By doing so, you are preventing the attacker to inject potentially dangerous code in your page (being the classic example, injecting javascript).
You probably know this already also, however: Use prepared statements. If you are sending the data you got from a request to the database, using prepared statements will protect you from SQL injection.
Yes, I know the question is not about javascript or SQL injection. However Injection reminds the most common vulnerability according to OWASP TOP 10 and people who wonder if third party can make requests to their page is the kind of people who needs to be told this.
Alright, next up, you need to know if the request comes from an authenticated user. Again, you are probably doing this already, use sessions. What you might not know is that PHP session cookie is not HTTP only by default, meaning that it could be stolen on the client (see Session Hijacking). To fix that use ini_set('session.cookie_httponly', 1);.
Now, of course, the cookie could be stolen from a Man In the Middle attack, which brings me to: use HTTPS. You can get an free SSL certificate to set up HTTPS in your hosting from Let's Encrypt, if you are new to this, I suggest using ZeroSSL which will make it easy to get a certificate and uses Let's Encrypt behind the scenes.
Finally, there are scenarios where you need to make sure the request does not come from a malicius party and you cannot depend on a session being open. In this situation you need to issue a token associated with an specific action, and only allow the action to proceed if the token is presented... for example, if the user wants to recover access (forgot password) you can send a link with a token to their email account, and if the email is presented (and optionally if a captcha is resolved) you allow the user to set a new password.
I hope I do not need to tell you How NOT to Store Passwords!.
For more information see OWASP Cross-Site Request Forgery Prevention Cheat Sheet.
I'm wondering if someone could simply send a POST request to my PHP script (assuming its public).
Yes, though not via XHR/fetch from a modern browser if you haven't allowed CORS. (This doesn't stop a regular form on another web page posting to your script.)
Wouldn't that have the potential to mess up my entire script?
How so? You're responsible for properly handling anything posted to you.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been reading/googling for the last week on best approach to this issue/application.
I have an app that is bascially a database front end, currently it stores data locally, all works happily (available in the app store).
What i want to do next is store this data on a server.
(Before this i had no experience in server at all so everything from this point on from my own research and asumptions, if something is incorrect please point it out to me).
I decided that a RESTful webservice design would be best for what i wanted.
Basically intention is iPad/Android will be able to talk to web service, web service sits on top of a MySQL database, web service will receive strings, vidoes, photos.
My current situation is i can get the webservice to talk to the MySQL database, i can send simple requests from iPad for data (strings) and to post data (strings), (Still need to figure out best way of handling photos and videos, but thats a different issue).
My Question: What is the best way of making this web service Login/Secure.
The data is sensitive so has to be secure. Currently the user can't access the app without a username & password, but obeviously i need to take precations in the web service also.
I have done loads and loads of googling research and even topics on here i seem to be constantly seeing comments along the lines of "This method is out of date" etc.
It seems to be there are two fundamental approaches,
1) Basically having a GUID which is configered on inital start up <-I think
2) On every request for data also transfering password/username.
Any help guidance would be greatfully recieved.
Thanks
P.S. Sorry about the essay
It is possible to encrypt and sign the data exchanged between the server and the client. For that you can generate your own trusted certificate for free. You'll have to look for the methods based on the technologies you are using. This will protect you against man in the middle attacks as an intruder can't read or alter the data.
Any passwords you use in the code should be encrypted to protect against reverse engineering (at least for amateurs)
Use key based encryption algoritms
Capture all the exceptions, an error should never be transmitted to the client as it's a door to your system.
Protect your wsdl file (if you have any) against public viewing.
Validate your forms, the user shouldn't be able to inject special characters like "<",">","'","=","-"...
This is what I can think of for now.
You can use the following approaches to make your API secure.
oAuth implementation to send and receieve data with authentication headers.
SSL certicificates to make sure the communication between your server and client is encrypted. You can easily buy a private certificate for as low as $15/month.
Hash database fields such as password. (Make sure NOT to use MD5 as it is not secured. Use SHA1 or SHA2 instead).
Don't store user passwords in mobile applications, store some sort of hashed auth key, instead.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How secure is sending sensitive data over https?
JSON data to web service- how do define expected JSON data
I am building a REST web service that accepts JSON as its payload.
Now, my web service is very simple. It simply accepts data from a client system and creates an order in our system ( the web service is basically a wrapper for existing functionality).
Now, I authenticate users through a username and password in the application. Do I simply ask them to provide their username/password in the JSON data that they send? Is this secure?
The service runs over HTTPS.
As I also wrote in the comments above, it's not really clear what you would like to know. Perhaps because there is a lot of "it depends" potential.
Let's see what you can do:
You can put the authentication on the transport layer, here HTTP. That would allow you to authenticate pretty early, e.g. on the (web-)server level.
You can pass the credentials with the json payload and then authenticate within your application. This can be combined with 1.
You can create an authenticated session, and pass a session key along. API requests then need to have a session, otherwise they are not accepted. This can be combined with 2. and 3.
As long as the transport layer is secure enough for you (here TLS/SSL), do whatever pleases you. Depending which pattern you choose, you will have some more work to do.
Also often next to user-credentials there is a so called API key that is used by web services to be able to map each API request to some entity, which also can play some role in authentication. However, an API-Key is something like a username and password in one, so it is not that flexible.
Back from the Symfony Live 2012 in Paris, where I luckily participate to "Designing HTTP Interfaces and RESTful Web Services" conference, I'v much questions on how to build a RESTful API while keeping it private and member only.
Currently I used to generate an API key to make my API private (I mean available to third-party application on my own but end-users).
To make sure signed up users can use the API (through mobile app) I use Cookie, well, I used SESSION.
But afaik, it is not the correct way to do, according to the talk (and other resources I read over the web).
My needs are the following:
Provides a private API which only my mobile app can use
Allows member (of different roles) to do different actions (ie: a Member can post a comment, while an Administrator can edit them all)
As REST constraints are Stateless (amongst others) I can't use Cookie/Session as they need to be initiated by the client and will result in some non-idempotent result.
I read here and there that a way to keep my API RESTful is to provide on each request the credential.
Currently, to authenticate my API key (to keep it private) I use a custom HTTP Authorization scheme, something like Authorization: MyApp SoMeToKeNV3RYPR!V4T3 and then authenticate my member (login) with a POST method (as I would do in any browser web application).
How would you implement such cases? Is it acceptable to use such private scheme and keep using sessions?
After some reading I may think that working with some Signature over each requests can help to solve such problems.
The signature may be generated using the user credential provided in the third-party client while encrypting it with a public/private key (to keep the API private).
On each request, the signature will be checked against a CRC (or something like that) while the credential will be against a database (it doesn't seem worth than checking for a session, does it?)
Any help/advices would be appreciated.
PS: What about OAuth? I don't know much about it, but may it be a solution to such problem?
You're definitely going to want to use OAuth. This will allow you to securely authenticate that your users are who they say they are. No messing with CRCs or anything is needed on your end, once a user is authenticated they have an access token they can use to sign future requests.
You would just need to handle the authentication scheme and handshake and then securely store the access tokens once they have been given out. However, if it were me I would not trust myself to handle all of the secure cases when designing such a system. There are a couple of third party PaaS companies that will do this type of thing for you. I know of the following companies which have some API management tools that will probably help you, and afaik they handle OAuth implementations as well:
Apigee
Layer 7
Ping Identity
If you are so concerned about security though that you don't trust a third party to handle it for you you are going to want to follow the OAuth protocol.