How to track unique visitors on my local web-server? - php

I have local PHP web-server (internet is not available here). How could I track identify and track unique visitors? Believe, mac-address is not available to my web-server.

You can only access the storage mediums available to you on the web to distinguish users. You can store a flag saying visited: true.
You can store this flag at
LocalStorage
Session Storage
Cookie Storage
IndexedDB
WebSQL
Devices you might be able to differentiate on IP. But same user can come from different IPs and this process happens in the backend

Related

Evercookie for longterm sessions and session hijack prevention

I am implementing classroom check-in system that is tied to specific desktops. Unfortunately all I have is a public facing webserver to work with and don't want students able to copy the checking url and falsify check-ins, or login with staff credentials and get access to other tools on the site. Also the computers are on a network where they DHCP regularly reassigns ip's so pinning on IP is not a reliable method of client validation. So I was thinking evercookies, I could have a staff member log into the check-in website from the computer set an evercookie then logout to prevent use of lat login for accessing other tools on the website. When the check-in site is loaded it does a check for the evercookie and as long as a certain threshold is met the check-in page is presented. This has the added benefit of bypassing php/apache's session timeouts.
Or am I barking up the wrong tree and there is a better way to fingerpint the authorized client?
Relying on an evercookie leaves you open to cookie hijacking.
In your case, someone could steal the evercookie id, and use it from another machine, making your application believe it's receiving requests from one of the specific desktops when it is not. The evercookie id could be stolen by a sophisticated user directly from the machine.
Using a strong cookie id, a strong hash, lots of entropy, etc., will not help in this case.
Changing the evercookie identifier often would invalidate any previously stolen cookies. However, this would require that someone manually intervene to regenerate the cookies periodically. This could be automated, and the updated cookie IDs could be pushed to your server with custom software over a secure connection, but that opens the possibility of the software being stolen and used on another machine.
As a rule of thumb, depending on the client to uniquely identify itself is not reliable.
If your IP addresses are assigned via DHCP, but come from some predictable set, you could implement IP checking based on a known range of IPs.
You could deploy custom software on the machine and "handshake" to it from the server. It could generate a unique id based on the hard drive serial number, a MAC address, etc. However, your custom software could be stolen and installed elsewhere by a sophisticated user, or reverse-engineered.

Restrict php script to only one computer without login

I want to make a php webpage accessible from only one computer.
IP checking isn't suitable for that (Dynamic IP).
I could set a cookie (with no expiration date) with a token. Then I could check if the cookie has the correct token and display the page, else I could die(). I think that this isn't a secure solution, because a cookie can be stolen, can't it?
So, what to do?
P.S. Obviously I can't login every time.
So here are a couple of options:
Client side certificates
Create a client side certificate and configure your webserver to authenticate using client certificates. Problem solved. In future, if you need to have more computers connect to the server, give them client certificates as well.
IP based : using Dynamic DNS
Give your computer a dynamic-dns name (myclient.dyndns.com) and install a dyndns client on your computer. The dyndns client keeps checking its own IP and updates the nameserver entry whenever your computer's IP changes. On server side all you need to check is if the IP that the requester presents is same as myclient.dyndns.com and allow access if it is.
A slight gotcha in this one is that there is a small (configurable) window of time between when IP changes and the dyndns client pupulates it to the nameserver. So, whenever your IP changes, until the dyndns client on your computer detects it and updates the nameserver, your server will not allow any requests from your computer in that time window. Thats because your computer will present the new IP and myclient.dyndns.com will resolve to your old UP. This time window can be made as small as you want (even 1 second). The other small gotcha is that in this n second window, any random computer that gets your old IP assigned by the ISP can access your server. The probablity of this is very small but just mentioning as a possibility.
There are many free dynamic dns services out there. You can google them.
Cookie Based
You could use cookies. However as you correctly identified, cookies can be stolen. Now, there are two ways they can be stolen:
Copying the cookie off the computer: Someone who has access to the computer can copy that specific cookie and impersonate as your computer to your webserver. If this is possible (if potential malicious users can remote desktop or physically access your computer), then cookie based solution is not for you.
Sniffing over the network: Cookies can be easily sniffed over the network. A easy way to prevent sniffing is enabling SSL. Given that you are confident that cookies cannot be stolen off the computer by copying it over, cookie+SSL option works in your case. In this case its just like a shared secret key. You do it via cookie or querystring, it doesn't matter. Cookie obviously are preferred over querystring because cookies aren't normally logged in browser history or webserver logs.
Also just a thought: For all the computers that aren't authenticated, send a standard 404 response rather than some custom "Access denied" page. This way anyone who is running a crawler/bot/scanner on your site will not be intrigued by this custom response and will not attempt to circumvent your security controls.
Couldn't you just use a unique passphrase as a parameter in the uri?
e.g. http://www.example.com/index.php?passphrase=sfauh452h8243nf2489ht8924t48nf3984
and check to see if it matches the one stored in the server?
Well I get if you are not the user it is someone else... then you need only that specific client (computer) to be able to access the page
Either way the first time there must be some sort of registration. Maybe the example uri above works like this:
you request: http://www.example.com/index.php?passphrase=sfauh452h8243nf2489ht8924t48nf3984
the passphrase is checked of being correct and a boolean value is stored in the server as to never be able to "register" again.
If it is correct, a cookie is being generated with a unique key.
This same key is also stored in the server (file, database or something)
Therefore on subsequent requests when you just compare the key stored in the server and the key in the cookie you know who is the client

Dealing with session in PHP across Linux user accounts

On a Linux-hosted sever, I have the same web app installed on two user's accounts (http://host.com/~linux_user)
As you might guess, I have problems because sessions are shared between user accounts.
From now on, I'll store them as a session array ($_SESSION['linux_user']['my_data']).
Is this a good approach?
You can also get rid of the problem with using a custom session handler, which handles session storage as you want it to : database, memcache...
More info here : http://php.net/manual/en/function.session-set-save-handler.php
"From now on, I'll store as session array $_SESSION['linux_user']['my_data']. Is this a good approach?"
No, as those session variables will only be available in one user account. What you need is a single-sign-on technology, like if you want to stay logged in over multiple domains. For example you may use OpenID.
Or you store the PHP-session at an explicit location (within the filesystem or in a database).
But why/how do you have the PHP-app installed into two different user accounts? If I set up an Apache web-server, it runs as a separate user…

How can i differentiate LAN computers in php

I want to find each LAN connected computer separately. I am fetching ip address but i am assuming if many computers are connected to LAN they may give same ip.How can i differentiate all computers separately in php ?
Just use Sessions and Cockies.
easiest and best way: use phps session-management - every client is given an id, stored in a cookie (if enabled) or given as a get-variable on every link and form. (alternatively you could set a cookie on your own)
identifying every client by ip is a bad idea and won't work. clients that use the same router will have the same ip's - clients connected through a proxy-pool could have another ip with every page load.
EDIT: if you need a solution that can't be manipulated by the client in an easy way, try to do a combination of those, using all that are supported by the clients browser and compare them on each page-load:
"normal" HTTP Cookies
Local Shared Objects (Flash Cookies)
Storing cookies in RGB values of auto-generated, force-cached PNGs using HTML5 Canvas tag to read pixels (cookies) back out
Storing cookies in and reading out Web History
Storing cookies in HTTP ETags
Internet Explorer userData storage
HTML5 Session Storage
HTML5 Local Storage
HTML5 Global Storage
HTML5 Database Storage via SQLite
You can't. The only thing would be to use sessions (i.e. cookies) to differentiate them, but that's not a safe way.

Persistent login info from server to server

I am currently working on 2 web servers, One Coldfusion and the other PHP.
Right now, the Coldfusion server is my main server where users log in to access restricted data.
However, I have also begun using a PHP server and want to make it transparent for users to access a specific page on that server - that server requires log in information as well.
I do not want the users to log in twice.
Is there a way to accomplish this ?
Thx
UPDATE: Working in an Intranet environment, so I can't use any public solution.
UPDATE: Reason I am asking for this is because we are moving from a MSQL / Coldfusion environment (Initial server) to a PHP / ORACLE (new server). So I have 2 user tables as well (although they contain mostly the same information).
I am trying to faze out the use of our initial server in favor of our new server transparently to the user and thus I have to work in parallel for the time being.
Most single-sign-on solutions work a bit like this...
Main system authenticates use
User opts initiates a need to move to system 2
Main system authenticates the user with system 2 in the background
System 2 supplies a random, long and disposable token to Main system
Main system redirects the user, with the token, to system 2
System 2 checks the token (and other factors such as IP address) to validate the session
System 2 disposes of the token to ensure it can't be replayed
You would want to ensure that the transmission channels had some security on, especially where Main system and system 2 are talking to each other. You would want that to be a secure transport.
Store sessions in a database, and share them between the two apps.
You could use xml-rpc to get user data and log the user into the other site when they have a login cookie for the first one and vice versa.
Php manual page for XML-rpc
Here is what I have done, in running my own game server, had users on sql server, and on mysql, and wanted to integrate them both.
I made sure that if a user was created on 1 system, was also created on the other.
So you can modify code in both applications, to automatically create a user in other system if it is created on here.
Depending if both servers share a domain, can you do cross-domain sessions or cookies...But my best guess is to store and retreive data...
Or..
as a person logins/registers record their current ip address, on both servers, then check if this person was on the other server within 2-5 minutes, if so, use the ip address to identify them....
This system is tricky because timing is important, so your not leaving a huge hole in your security....But for short term, going between servers, this is simplest solution, in my own opinion.
Good Luck.
If you are on an intranet, you can actually sniff out the network username of the user from the PC they are logged into the network on using PHP. This assumes that:
You are using IIS to host your PHP application.
Your users are using Windows.
Check the section "2.2 Enabling Support for Detecting Usernames" here.
After that, all you need to do is investigate if the same is possible from Coldfusion, and you have the basis of an SSO solution based on the network usernames.
How about implementing an OpenID solution, much like the one apparent on StackOverflow?
You may benefit from dropping a shared object on the client machine via Flash or Flex. This object could then be read from ColdFusion/PHP/Python on servers that otherwise had no connection to each other or access to a common database.
Here is a simple example from the Adobe Docs
Maintain local persistence. This is
the simplest way to use a shared
object, and does not require Flash
Media Server. For example, you can
call SharedObject.getLocal() to create
a shared object in an application,
such as a calculator with memory. When
the user closes the calculator, Flash
Player saves the last value in a
shared object on the user's computer.
The next time the calculator is run,
it contains the values it had
previously. Alternatively, if you set
the shared object's properties to null
before the calculator application is
closed, the next time the application
runs, it opens without any values.
Another example of maintaining local
persistence is tracking user
preferences or other data for a
complex website, such as a record of
which articles a user read on a news
site. Tracking this information allows
you to display articles that have
already been read differently from
new, unread articles. Storing this
information on the user's computer
reduces server load.
Full Information: http://livedocs.adobe.com/flex/3/langref/flash/net/SharedObject.html

Categories