I need to reliably get the id of a user from the PC using PHP.
I tried using
gethostbyaddr($_SERVER['REMOTE_ADDR']);
but that returns the network name of the pc, not what they actually logged in with.
I then tried
var WshShell = new ActiveXObject('WScript.Network');
document.form1.item('uid').value = WshShell.UserName;
which returned the value I needed, but has inherent issues:
browser security
being able to completely bypass by using browsers other than IE
Is there a way to get the ID that I am just not finding?
Looking at the discussion in the comments, the correct answer is to build a proper, run-off-the-mill login system like millions of sites already employ.
There is no safe mechanism to uniquely identify a PC to a server side application, plus as you say, users could switch machines on a daily basis.
You could set a cookie, but that is laughably trivial to fake.
See e.g. here for some good answers on authentication libraries for PHP.
You can figure out all sort of client-side tricks which will possibly work in some combinations of operating system and browser. But, in the end, everything will be transmitted to the server using good old HTTP. That's all that the server (the only side you have full control on) will receive: a bunch of text. There's no way to tell out whether the request came from your fancy ActiveX or was typed in a telnet command prompt.
Of course, there are ways to authenticate requests. That's one of the usages of cryptography. But, again, all you'll ever know is whether the signature was generated with the appropriate key. You cannot be sure of who the user is or what computer he's using, all you know is that it's someone who got a copy of the key.
Now, it's really complicate to build a login system that does not have its own users. As far as I know, even OpenID-based systems bind remote users to local users. Are you sure it's a requisite?
If you have a single-signon type of system running on Windows Active Directory, consider getting user data via LDAP
Related
I've a rather odd requirement: I want users to be able to verify the live source code of a web app before they input data or extract data from it.
Or, on a more higher level, the users need to be reasonably assured of what is being done (and not done) in the back end. Of course, if you inspect the stream from a process external to the web server, this becomes a useless exercise. But I only need a reasonable level of assurance.
What are the options? I'm willing to use pretty much any server side language/platform, provided it serves the purpose better than the alternatives. It cannot be a method that can be used to easily spoof the source code -- there has to be some assurance that the code is live and not a separate copy (something equivalent to making /var/www/app and apache conf world-readable, but not exactly).
Update: this should be read-only
Giving them access to your Git sources is simple and straightforward. If you cannot convince them that you deploy what you show, you lose anyway. There is no way to prove that with a more convoluted system either (short of giving them write access!)
No server-side solution will do. If the users don't trust the server to begin with then showing them some code will not convince them that the code is actually what processes their input, or that no one is listening in on the traffic or on the server-side process.
If the server is not a trusted platform as far as the users are concerned, then you will have to execute the code somewhere the users do trust. On a trusted 3rd-party, or even better on the user's machine itself. Be that as a downloable module they can inspect and run themselves (something interpreted, most likely, like Python or node) or even better: in their browser.
I was wondering about creating something that would compare to the titles implications.
There are so many websites that compare prices on goods and how they go about it is quite simple.
Please a file on the clients server, target it with your own server at any specific point in time.
So, within that file any code that is executable would only execute on authorisation.
What I commonly see is:
$required_ip = gethostbyname('admin.mydomain.com');
if ($_SERVER['REMOTE_ADDR'] != $required_ip) {
die('This file is not accessible.');
}
// Do some stuff like turn the remote product data into xml format and export to your local server
What I would like to find out is firstly, how secure is this method? I am quite sure there are a few ways to get around this and if anyone could suggest a way to bypass this situation then that would be great!
My goal however, is to reverse this process. So that once authenticated, data can be pushed to the remote server. It is one thing to extract but another to input so I am worried that this type of functionality could create serious security issues. What I would like to do, is find out how I could possibly work around that to make what could be a safe "datapusher".
Any advice, feedback or input would be greatly appreciated; thanks in advance!
(Paraphrasing your questions:)
How secure is it to do a DNS lookup and use that to authenticate a client.
Reasonably secure, though by no means perfect. The first problem is that the IP it resolves to may encompass quite a number of different machines, if it's pointing towards a NATed network. An attacker could pose as the correct remote IP if they're able to send their requests from somewhere within that network; or simply by tunnelling requests through it in one way or another. Essentially, the security lies in the hands of the owner of that domain/IP address, and there are numerous ways to screw it up.
In reverse, an attacker may be able to poison the DNS resolver that's used to resolve that IP address, allowing the attacker to point it to any IP address he pleases.
Both of these kinds of attacks are not infeasible, though not trivial either. If you're sending information which isn't terribly confidential, it's probably a "good enough" solution. For really sensitive data it's a no go.
How to ensure the identity of a remote server I'm pushing data to?
With your push idea, all your server really needs to do is to send some HTTP request to some remote server. There isn't even really any need for anyone to authenticate themselves. Your server is voluntarily pushing data to another system, that system merely needs to receive it; there's no real case of requiring an authentication.
However, you do want to make sure that you're sending the data to the right remote system, not to someone else. You also want to make sure the communication is secured. For that, use SSL. The remote system needs to have a signed SSL certificate which verifies its identity, and which is used to encrypt the traffic.
Have done some research and found some stuff that may be helpful.
I would like your opinion about my approaches on this.
THE GOAL
I will develop an application in PHP (That's the only language I know and unfortunately I don't have time to learn another one right now). I want this application to be able to run offline and locally to any pc. I will use Wamp server and cakePHP framework for this.
THE PROBLEM
This application will be for sale. So I will need some activation method to prevent each app from being used in multiple computers. I don't want something complicated or very very secure. I just need something simple, to prevent non-programmers to run this app in any computer. Of course, the more secure, the better! :)
POSSIBLE SOLUTIONS I AM THINKING OF
First of all, I am thinking to force users to activate their application, by going online during installation. That way they could get a unique KEY from my online database.
I found php's shell_exec command. So I am thinking, during online installation, to get the Host ID (Machine ID) of that computer, send it to my server and store it to my database next to a unique KEY. Then Machine ID and unique KEY can be stored to a php file. (Could I store it somewhere more secure? Maybe encrypt it?)
Every time the user opens the application, php will read machine ID. If not the same with the one stored in php file, an activation will be required. (Maybe could store computer's name too or some other id?)
Is that a good approach? Would it be possible?
Another approach I am thinking of, is to have a guy create a non php installation file. When run, will promp wamp installation and when installation finishes, will transfer all necessary files to wamp root folder (automatization for the user). I can only guess though this will work, as my knowledge over other languages is limited...
Could I benefit from this in validation terms? Can a non php file interact with my php application and validate it, for only one unique computer?
Any info will be very appreciated. I have just started building the application and want to know if there is a good way (or non) to secure it.
Thanks!
There is no point in all of this because if people want they can simply crack any of the copy protection methods you came up with. This also applies to any other app written in any other language. If people want to use it without permissions there are ways to do that.
There are some ways to obfuscate the code (see Is there a code obfuscator for PHP?) but these solutions are just silly because if people really want they can get the code in plain text anyways.
A better idea might be to run the app on your server and allow people to pay for it monthly, Software as a Service like Google Apps for Business.
Currently I sell a program, that accesses my webpage. The program is HWID (Hard Ware ID) locked, and the only reason I use the program to access the webpage instead of direct access via a webbrowser, is so that I can use HWID authentication.
However, I've just been told I can code a script to get computer information, such as hardware ID etc.
Is this actually possible completely server-side? If so, can I do it with PHP? If not, what language would this be, and what functions would I have to look into for this?
Whoever told you that is confused with something else.
Browsers do not expose that kind of hardware information to a web server at any point, so there is no existing mechanism for a server-side PHP script to get a visitor's HWID. JavaScript provides very limited information about display resolution and color depth, but certainly not something like HWID. A very long time ago, it used to be possible to use ActiveX objects in JavaScript in IE to retrieve hardware information via WMI, but you can bet that's not possible anymore, especially on a non-intranet zone site. You'd most certainly need some kind of browser plugin or extension; Flash does not provide the HWID, so you're looking at something custom-written by you that must be installed on a visitor's machine either prior to or during their visit.
You're better off continuing to sell the app that gets the HWID itself and then accesses your web site, because that's going to be far less painful than writing browser extensions and plug-ins for all major browsers to provide that information in a secure way.
I wrote a PHP web-application using SQLite and sessions stored on filesystem.
This is functionally fine and attractively low maintenance. But, now it needs to run on a shared host.
All web-applications on the shared host run as the same user, so my users' session data is vulnerable, as is the database, code, etc.
Many recommend storing sessions in DBMS such as MySQL in this situation. So at first I thought I will just do that, and move the SQLite data into MySQL too. But then I realized the MySQL credentials need to be readable by the web application user, so I'm back to square one.
I think the best solution is to use PHP as a CGI so it runs as different user for each web-application. This sounds great, but my host does not do this it uses mod_php. Are there any drawbacks from an admin's point-of-view for enabling this? (performance, backward compatibility, etc)? If not then I will ask them to enable this.
Otherwise, is there anything I can do to secure my database and session data in this situation?
As long as your code is running as the shared web user, anything stored on the server is going to be vulnerable. Any other user could write a PHP script to examine any readable file on the server, including your data and PHP code.
If your hosting provider will allow it, running as PHP as a CGI under a different user will help, but I expect there will be a significant performance hit, as each request will require a new process to be created. (You could look at FCGI as a better-performing alternative.)
The other approach would be to set a cookie based on something the user provides, and use that to encrypt session data. For instance, when the user logs in, take a hash of their username, password (as just supplied by them) and the current time, encrypt the session data with the hash, set a cookie containing the hash. On the next request, you'll get the cookie back, which you can then use to decrypt the session data. Note however that this will only protect the current session data; your user table, other data, and code will still be vulnerable.
In this situation, you need to decide whether the tradeoff of the low cost of shared hosting is acceptable considering the reduced security it provides. This will depend on your application, and it may be that rather than trying to come up with a complex (and possibly not even very effective) way to add security, you're better off just accepting the risk.
I don't view security as all or nothing. There are steps you can take. Give the web db user only the permissions it needs. Store passwords as hashes. Use openid login so users provide their credentials over SSL.
PHP on cgi can be slower and some hosts may simply not want to support more than one environment.
You may need to stick with your host for some reason, but generally there are so many available that it is a good reminder for people to compare functionality and security as well as cost. I have noticed many companies starting to offer virtual machine hosting -- nearly dedicated server level security in terms of isolating your code from other users -- at what is to me reasonable cost.
A shared host is no way to run a web site if you are conscious about privacy and security of your data from the sites that you share the server with. Anything accessible to your web application is fair game for the others; it'll only be a matter of time before they can access it (assuming they do have incentive to do that to you).
"you can place your DB connection variables in a file below the web root. this will at least protect it from web access. if you're going to use file based sessions as well, you can set the session path in your user's directory and again outside the web root."
I don't have an account so I can't downvote that.. but seriously it is not even relevant to the question.
Duh you store stuff outside the webroot. That goes for any hosting scenario and is not specific to shared hosting. We're not talking about protecting from outsiders here. We're talking about protecting from other applications on the same machine.
To the OP I think PHP as CGI is the most secure solution, as you already suggested yourself. But as someone else said there is a performance hit with this.
Something you might look at is moving your sessions and db to MySQL and using safe_mode and/or open_basedir.
I would solve the problem with a infrasturcture change instead of a code one.
Consider upgrading to a VPS server. Nowdays you can get them very inexpensive. I've seen VPS's starting # 10$/mo.