method to authenticate via a php script on my server - linux

I am using a new service to pull xml data from a server.
The service provides two methods of logging in, one via a url query:
http://<server>/login.asp?username=<User Name>&password=<Password>
and the server returns a cookie valid for 7 days. This means instead of logging in for every query (and making my script less efficient), I only need to login once a week.
I have just realised that I can't do this since the script is not run from a web browser but from a cron script on the server. Is there a way to store cookies on my server, or do I have to go for the second method:
Token
The token is the username, passwork
and usergroup encrypted using the DES
algorithm with a key and a timestamp.
The token can be generated by any
application using the DES algorithm
with the appropriate key or the secure
call below can be used: the token is
contained in the body of the returned
page and is valid for one hour
I know nothing of this method. Can you point me in the right direction? Thanks.
Ed

Is there a way to store cookies on my
server?
Yes. Here's how:
curl -c cookies.txt http://<server>/login.asp?username=<User Name>&password=<Password>
That will write them in netscape format to cookies.txt.
Noah

If you have access to the actual login script, you could instead always include some sort of unique id only you know..
Even better would be to use some HMAC-(MD5/SHA1) scheme like OpenAuth does. If you're lazy, just include something like '?key=somethingonlyyouknow' to every url you access, bypassing username + password. User + password scheme 'should' only really be used by humans, not by machines.
If all that fails, change your script to store the cookie. If you use 'curl' you can specify cookies should be stored, and in which file that should be.

Related

ssh based authentication in expressjs

I am currently using expressjs with node.js as my rest server for my website. Currently users can login on to my website and start some actions through ui. They want to automate this stuff and I am looking for ways to achieve that. Some of the ways I can think is:
Create a new request which can take login creds as part of reuest parameters and execute the desired the actions. My users would have to save their password as pain text for automations which doesn't seem OK to me.
login using ssh similar to how bitbucket/github takes our public ssh key and lets up do codepush with out writing the password everytime. How do I implement this kind of setup. My users want to execute everytime they deploy in test machine. So they will put my script in server restart script.
If I have to adda new ssh based authentication, are there any npm modules which can help me with implementation?
I am using mean.io boiler plate code and login is currently is based on default login protocol of theirs, where in I save the hashed password and compare that during login.
I think dealing with public-private key pairs is probably more trouble than it is worth. Perhaps you can go with a third option:
Allow users to generate API keys from your web interface. The keys will be "long" randomly generated strings (GitHub uses a 40 character long hexadecimal string for its keys). They can be used for making API requests in place of a password in a username-password pair. For additional security, allow users to limit a key's usage to a certain IP (range).
Also, make sure your application is being served over HTTPS if it is not already.
Example flow:
User tim generates a random API key on your site (aisjd8auasdjsd80j43j).
tim wants to make a request to your API. In the request, tim sets an authorization header:
GET /api/v1/list-all HTTP/1.1
Host: example.com
X-API-Auth: tim:aisjd8auasdjsd80j43j
...
Your API verifies the X-API-Auth header, checking if tim owns the given API key.
Your API returns the requested information on sucess.
Also, it may be worth using using HTTP basic authentication instead of the custom X-API-Auth header, as I did in the above example. I believe it would be slightly easier in command line tools like curl to make HTTP basic authentication requests, rather than setting a custom header.

Authentication system - is my one secure?

I want to authenticate my users based entirely on cookies and sql db.
What I do is:
1. Once they login, I generate a random string, create a hash from it, save it in the database along with the user id and his IP.
2. I send the hash to the user as cookie
3. Whenever he wants to access something, I verify if his cookie hash matches the one on the server and also if his IP matches. Of yes, he is valid or else, log him out.
4. (As pointed by Akhil) If he clears his browser cookies or anything does not match the information on the database, I clear all the rows with his username and log him out.
Note: I use a session cookie for storing the random hash, which again is generated using the timestamp, and as long as time doesn't repeat itself(I believe), its random in the corect way.
Is this fine? How can I make it better?
Once they login, I generate a random string
Make sure you use a cryptographically secure method to generate the random string. Do not use mt_rand use something such as openssl_random_pseudo_bytes.
create a hash from it,
Make sure to use a secure hashing algorithm (not MD5, and at least SHA-2).
save it in the database along with the user id and his IP.
One thing to bear in mind is that some internet connections share IP addresses or will sometimes change the client IP address (e.g. AOL or mobile).
I send the hash to the user as cookie 3. Whenever he wants to access something, I verify if his cookie hash matches the one on the server and also if his IP matches. Of yes, he is valid or else, log him out.
It sounds like a good way of doing it and there are no flaws in itself. I would implement a session timeout mechanism. For example, store the date last used in the DB for a sliding expiration and the query will only query records that have not expired. You could have a background process that runs to clear out old, expired records.
Also, use HTTPS and set the Secure and HttpOnly flags on the cookie. This will prevent them being leaked over HTTP, but I would not go as far as disabling HTTP on your system as there are workarounds for an attacker if it is anyway.
I would not be concerned with the cookie being stolen by another user on the same machine. If the cookie can be stolen in this way then the user's machine is probably compromised anyway and you cannot make your system protect data that is outside of your control. You could however renew the token (random string) on a periodic basis giving the user a rolling cookie. You would have to ensure only one user can be logged in at once under the same account though for this to be effective.
Your method only makes sure that the user possess the random string you generated and is using the same external IP address. There exists several way of abusing this system:
if your website doesn't enforce HTTPS then a user connecting using an unsecured public WiFi network could be at risk: if another user of the WiFi network is listening to all the packets being sent on the network, he could intercept your cookie and use it to access the website as your legitimate user. Your server would be unable to differentiate them because they'll both use the same IP address... (There is a Firefox extension available which enable anyone to intercept such login cookie easily: http://en.wikipedia.org/wiki/Firesheep)
This system is also more generally vulnerable to man in the middle attacks (without HTTPS)
If your cookie is stored on the user computer's hard drive it could be reused by another user.
So to answer your question, your system can be deemed as secured provided a few conditions:
you enforce the use of HTTPS on your website (unencrypted HTTP connections should be refused)
your random string is truly random (there exist right and wrong ways of generating random strings in PHP)
your cookie has a short expiry and preferably is set as a session cookie.
You should take a look at the following related question providing details about the proper way of doing what you want to do: How to secure an authentication cookie without SSL
One cannot say this is "bad". But in Web Development, and specifically in its security domain relativity talks. I recommend you to download a CodeIgniter (google it for more info) Session Class (standalone version) and use it. The basic idea is the same as yours, but it is properly more mature since it is developed in such a famous php framework. You can do your DB operations within that class too, since it allows session saving to DB.

When trying to create a SSL connection with LWP::UserAgent, what do I use for realm?

I've started a project to scrape my work's employee website to scrape the user's (in this case, mine) schedule and munge the data onto a google calendar. I've decided to go with Perl with LWP.
The problem is this, when trying to set up SSL negotiations I don't know what do put for the 'realm'.
For example: (http://www.sciencemedianetwork.org/wiki/Form_submission_with_LWP,_https,_and_authentication)
# ...
my $ua = new LWP::UserAgent;
$ua->protocols_allowed( [ 'http','https'] );
$ua->credentials('some.server:443',**'realm'**,'username','password');
# ...
I've looked at everything my browser can tell me and at a wireshark packet capture trying to find anything but to no avail. I assume that second argument to credentials() isn't optional.
Where do I find the 'realm' I'm supposed to use?
The credentials are for the HTTP authentication protocol (RFC 2617) (Wikipedia).
The server can challenge the client to authenticate itself. This response contains a string called “realm” which tells the client for what authentication is required. This allows the same server under the same domain to request authentication for different things, e.g. in a content management system where there might be an “user password” and an “administrator password”, which would be two different realms.
In a browser, this realm would be displayed alongside the username and password box which allows the user to type in the correct password.
To discover the realm, navigate to a page which requires authentication and look for the WWW-Authenticate header.
Note that HTTP authentication has become quite uncommon, with session cookies being used more often. To deal with such an authentication scheme, make sure that your LWP::UserAgent has an attached cookie storage, and then navigate through the login form before visiting your actual target page. Using WWW::Mechanize tends to make this a lot easier.

What pattern for constructing and verifying an access token for a web application?

We have a web application which consists of two parts (among others): a 'shell' written in Java running in Jetty using Windows authentication through Waffle, which shows a 'component' written in ASP.NET running in IIS using Windows authentication. Both parts are served from the same host, but (of course) from different ports.
As it stands, a user first must sign in to the shell, and then when the component is loaded the user must sign in again. We want to get rid of that second sign-in step.
From what I've seen and read, e.g. about claims-based authentication and OAuth, the standard pattern for that is the following:
After signing in to the shell, the shell constructs a 'token' with the user's Windows account name, which it sends back to the browser.
The component does not use Windows authentication, but instead the browser sends it the token.
The component verifies that it trusts the token, and uses the identity from that token.
(In our case the simplest technique is to put the token in a cookie, since both shell and component run on the same server, and HTTP cookies are not port-specific, so the browser will automatically send the shell's token to the component.)
Now I see several ways to construct and verify the token, like:
(a) The token contains the Windows account name, encrypted with a symmetric key that is hardcoded into both shell and component, or generated and agreed at installation time or start-up time.
(b) The token contains the Windows account name, signed using a private key, and verified using the corresponding public key. This key pair is generated at installation time.
(c) The token contains a GUID, and the component's server side makes a call to the shell's server side to verify its validity and get the Windows account name.
I think I prefer (b), since (a) seems too 'hardcoded', and (c) is more likely to give scaling issues. Also, we already have a private/public key pair in place in the form of an SSL server certificate in the shell which is trusted by the component.
My main concern with (b) is that the token will contain an (X.509?) signature, which means the token could become fairly large. (Would it?) Also I'm not (yet) familiar with techniques to create a signature in Java, and verify it in .NET.
My question: What is the standard/recommended pattern to use here? What alternatives have I overlooked? Is there a standard protocol that we could use here?
You are on the right track.
Yes, the idea is to have the shell generate a token that cannot be forged (generated by anything/anyone but the shell) that can be verified by the component.
You are right that the token can become quite large. It will not become so large as to be unworkable (i.e. larger than a browser can handle), but it can become a performance issue.
In general, any component that accepts HTTP traffic with any kind of cached authentication is going to have a preferred format for that cached authentication. In your current implementation, after the user signs into the component (the second sign in step) the component will issue some kind of cookie containing identification credentials it will accept for subsequent requests. So the best thing would be for the shell to create exactly those credentials.
Failing that, it's quite reasonable for you to use your option (b) of creating a signed certification form the shell that the component can verify and then replace with its preferred form of authentication credential.

How to make an API call on my server accessible only from one URL

I don't know if the title is clear enough, anyway what I need to do is quite simple: I have some content you can access by an API call on my server; this content is user-related so when you request access to it, you must first wait for the owner to authorize you. Since this content will be probably embedded into blog articles or form posts I want it to be accessible only from the URL the user authorized to.
The only way that came to my mind is to check in some secure way where the request is coming from: the problem with this approach is that anybody could create a fake request, using a valid URL but coming from a non-authorized URL actually.
I'm looking for a way to solve this problem, even if this doesn't involve checking the actual URL but using some other approach or whatever. Feel free to ask any questions if this is not clear enough.
With Sessions:
If you generate a secure token, most languages have libraries to do such a thing, you will have to persist it probably in a session on your server. When you render the page which will access the other content you can add that token to the link/form post/ajax request on the page you wish to be able to access it from.
You would then match that token against the value in the user session if the token doesn't match you return an error of some sort. This solution relies on the security of your session.
Without Sessions:
If you don't have sessions to get around server persistance, you can use a trick that amazon s3 uses for security. You would create something like a json string which gives authorization for the next 30 seconds, 5 minutes, whatever is appropriate. It would need to include a timestamp so that the value changes. You would use a secret key on your sever that you combine with the JSON string to create a hash value.
Your request would have to include the JSON string as one request parameter. You would need to base64 encode it or some other means so that you don't run into special characters not allowed over http. The second parameter would be the output of your hash operation.
When you get the request you would decode the JSON string so it was exactly the same as before and hash it with your secret key. If that value matches the one sent with the request it means those are the two values you sent to the page that ultimately requested the content.
Warnings:
You need to make sure you're using up to date algorithms and properly audited security libraries to do this stuff, do not try to write your own. There may be other ways around this depending on what context this ultimately ends up in but I think it should be relatively secure. Also I'm not a security expert I would consult one if you're dealing with very sensitive information.

Resources