I have made a API script for my website, so people can login from another website.
It's using PHP cuRL to POST data to my website.
I'm using a api key (md5 hash of the website) to verify the website with my MySQL database.
But when someone is using my API Client (PHP cURL), they also can save the username's and passwords of my user's.
How can i prevent this?
You might want to consider using OAuth. It's designed for exactly what you want to do.
I someone is typing their username and password onto a website other than your own, there is no way for you to prevent the owner of the website from capturing it...
What you'll want to do is have your site generate a secure set of credentials for the users account, similar to a username/password, but only to be used by the API. Also, prevent this new set of credentials from having the ability to do things like delete the user's account or change email address.
Also, give the users the ability to have their API credentials changed if they want (in case a third party gets it and the user no longer wants them to have access).
Related
Let's say I have a MySQL database with thousands of user accounts in it. These accounts contain lots of data, but for verification purposes, they each contain a username and a (hashed and salted) password. Now, when a user requests signing in, I will take a username and password from them, transfer it via WSS to a Node.js server then transfer it via HTTPS to a PHP file on another server. On that server I will look up the username in the MySQL database, and if I find an account, I will hash the password and see if it matches that username's password. If they both match, then I want the PHP file to create a "verification token" of sorts, save it (and associate it with the account verified) and send the token back to the Node.js server. I then want the Node.js server to send that token back to the client and for the client to save that token. Now the next time the user connects to the Node.js server via WSS, I want the client to check for an existing token, and if it exists I want it to send that token via WSS to the Node.js server, the Node.js server to send that via HTTPS to a PHP file, and that PHP file to see what account that token belongs to, and complete the sign in...
So I guess my first question would be: Is this a good model? Would this be a good idea, and would this be secure, or should I do this differently?
My second question is: What would be the best way to go about generating this token? Should it be completely random? Should it be a combination of letters+numbers? Should it be a hash of some random values? How should I go about the generation of this "token"?
To clarify, I'm not asking how to build a server or make requests or transfer data or anything of that sort, I'm merely asking what is the most secure way to generate a "token" that can be used as authentication to the same degree that a username+password can be used.
Thanks in advance! I'm sorry if this is a really stupid question.
I think you are describing a JWT. There are several packages implementing this in PHP.
I am using Instagram API by mgp25.
Here, you can gain access to the IG api via "logging in": the API (in php) requires a password and account id to be in plain text format when gaining the access.
Here is the setup that I have:
I have a site where there are users and the site has IG API integration. These users can input their Instagram User/Password (not the user info to log into the site) to gain access to the API.
However, these API only accepts plain text for password (since the password will then be verified within the IG server).
Problem:
The problem that I am having is the password security. Obviously I can't store the IG password as plain text, but if I hash them, it can't be used to login to the API either (as it is one-way only).
Methods:
I can only think of encrypting the password (not hashed) and decrypt them when needed. However, I can see a few issues with that approach as well.
I wanted to ask you guys what you guys think of the best way to address this issue.
(note. The official IG API has some limitation and are only allowing official business partners to have more functions which I need them. So the API by mgp25 is the only viable option at the moment).
You could require the password only once. The private API will save the cookies / session forever and you do not need to do a login again.
So this way you don't have to store passwords and, if for some reason the user is logged out, then you ask for password again. Does it make sense?
I've only known how to use the authorization URL to have a user connect their account to my website. Is there a way to do this authorization via an HTML form? For instance, the user inputs their Google email and password on my website and it authenticates that account without them ever having to sign in and out of accounts on Google and then visit the auth URL.
The reason for this is to connect multiple Google accounts to one account on my website. It would be a huge pain to ask them to log in and out of Google for every single account they want to attach. It'd be a lot better for the user experience to just type the info in a form on my site and have it authenticate. Is this possible in PHP or in any language?
This is a bad idea, do you really want to be responsible for user's Google password? Do you think users will trust you with that information? I know I wouldn't and I'd be highly suspicious that your sight is a phishing scheme with that behavior implemented.
Use OAuth 2.0 or OpenID instead and save yourself the headache of dealing with user passwords.
I am trying to submit credentials inserted by users through a Facebook application, which must be validated by an external system. I'm trying to submit them by this sitehttps://studenti.unisalento.it/. I read a lot of articles about the data posting by the PHP extension libcurl, management of cookie, ecc (like thishttp://www.herikstad.net/2011/06/logging-to-https-websites-using-php.html) but I can not post credentials to a login prompt system like this https://studenti.unisalento.it/auth/Logon.do
Any ideas??? Thanks!
Edit:
I noticed that you can login entering credentials in the url with this scheme: https://username:password#studenti.unisalento.it/auth/Logon.do?p_p_id=58&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&saveLastPath=0&_58_struts_action= You can take advantage of this using libcurl functions?
The correct answer even though it's not the answer you are looking for is: Don't do it.
You want students to enter their university login and passwords into your Facebook application?
Have you talked to the university about this?
How do they know your app isn't storing the submitted login and password somewhere so that you can hack into the student accounts later?
The likely answer is: They don't.
This is why things like OAuth and Shibboleth were invented. They allow you to authenticate users from a third party without collecting the user's actual credentials.
unisalento.it appears to have a Shibboleth installation. If you are running a legitimately sanctioned application, look at using that or some other authentication scheme that doesn't involve you collecting the username and password.
Since you're using PHP, simpleSAMLphp may be useful.
We are building a PHP multi-tenant application. Each company's account will run on their own subdomain abcorp.example.com. The application allows companies to write and publish content (faqs, etc) for their customers to read.
They will tell their customers to visit: abcorp.example.com/ to read the content. Or they will put a link to that URL in their secure web application.
However these companies may not want just anyone reading the content by going to abcorp.example.com/
So, the question I have is there any way to provide some basic authentication without getting into username and password authentication. I was thinking about some kind of hidden token added to the hyperlink or something like that
My goal:
If users type abcorp.example.com/ directly in the browser, they will not be able to see the web page because they didn't authenticate or pass the token in.
Avoid using username and passwords
Another option would be Referring URL Authentication
Of course, if someone makes the token public, it will open up access to whoever finds it.
I suppose each company could link to their page using a shared token, for example:
abccorp.example.com/?t=4rrfwr23rwads3
Each token could be stored in a file or a database.
When someone requests a page, it checks the value of $_GET['t'] with the one stored on the server. If it matches, it loads the rest of the page. Of course, this variable would have to be carried throughout the site, and included in every link.
Again, this will not be very secure. An exposed token could give access to the site to the entire world.
Your "hidden token" idea is essentialy the way sessions work. A session can be used to identify a user (ie. keep track of what a user does as they browse through the site), and is propagated either by passing the session ID along in links or by storing it in a cookie.
However, using a session without any other sort of authentication is inherently insecure! When you expose the way to authenticate and track users to the user itself, the user can modify or forge their authentication. For instance, the user could change the value passed along for the session ID or change the value stored in the cookie.
Please read the PHP manual section on sessions and security.
Client-side certification. Check out http://en.wikipedia.org/wiki/Mutual_authentication.
You could also use the clients IP address as a token, giving different IP addresses access to different (parts / instances) of the system. But gain, this is not very secure, as
you have no way of knowing who is behind the client PC and
IP addresses can be spoofed. Perhaps you could develop additional specs; giving IP addresses only access during office hours, or check the clients browser (user agent) and check it against the user agent officially being used at the client.
You can use basic hashing whereby a shared secret password or "key" is stored on your system and each company system (a different key for each company and not published publicly), and then you hash the secret password with the subdomain in the link and include the digest as a parameter. Then you validate it by running the same algorithm on your side and compare to the digest.
the link might look something like
abc.example.com/?d=b5939ca22f5dcf345b4000641995478c5910dbd1607b1bdadcbf4a8618a95211
where digest is:
$d = hash('sha256', $secret_password.$subdomain);
or including the referer:
$d = hash('sha256', ($secret_password.$subdomain.$_SERVER['HTTP_REFERER']));
The hurdle to get over is making sure each of the companies can support the correct generation of these links based on the company specific key/algorithm - and that it is different for each company so one company cannot produce links for another.
It is better than no authentication, or a public shared token that is not validated at all, but I'm sure it still has vulnerabilities.