Jump to content

Protecting Licensing With PHP Applications


JustinK101

Recommended Posts

Hey all,

 

So I am working on a idea where I want to provide a PHP application as a software as a service solution. Mainly, customers pay a set price per month which includes the application all setup and hosted. I need to protect the application licensing though. Here is what I am planning:

 

Every page will make a call to:

 

require("includes/licensing.php");

 

Inside licensing.php the file will simply connect to a remote mysql server and verify their local license key against what I have stored in my remote global valid licence key table. If their local license key exists in my table, then they should be using a valid key. One big issue, the username and password used to connect to my global valid license key table must be stored in plain text meaning, if they were smart they could write their own queries using the username and password and get all license keys.

 

What are some other flaws and things to consider?

 

One major one, is that they could do a find and replace and simply remove the require("incluldes/licensing.php") call? Is there a better way to do this sort of thing?

Link to comment
Share on other sites

In licencing.php have a required variable. If the variable isn't found then the script doesn't work.

Then if they remove licencing.php it won't work. Again though. If they know what they're looking for they could put the variable on another page.

You'd probably need to combine several different methods of anti-theft.

Another idea is encrypting all of the code using zend or something similar, but most of them charge. It will mean that if you require a variable or file, they wont be able to find the part to remove to stop it being required.

Link to comment
Share on other sites

that or force the program to access its libraries on your server and when it goes to your server it returns from a mysql table their licensing and if their aren't up to date it doesn't release the library baubblefish key to their computer to access the libraries. And say if it doesn't have libraries it can't do anything.

Link to comment
Share on other sites

and for the mysql user that acceses the server give them execution only rights.

 

Yeah clearly I would only have SELECT rights for the user that all customers would use to verify their license key, but this doesnt help. Also the user would only have access to the db licenses. For example, lets say my includes/licensing.php file was this:

 

$dbh = mysql_connect('my_server_ip', 'username', 'password');
mysql_select_db('licenses');
$sql = "SELECT license_key FROM licenses WHERE license_key = '" . $local_key . "' AND is_active = 'true'";
$result = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($result) > 0)
{
    $_SESSION['current_license_key'] = $local_key;
}
else
{
     echo 'Invalid License Key...';
     die();
}

 

So if a customer has free will to this code, simply changing the query to pull all license keys, and then sticking one of the valid keys into their local variable $local_key, and they have a fully valid copy.

 

cooldude832

 

I am interested in your idea of storing libraries on my remote server? How do I do this? Would I simply require("my_server_ip/includes/licensing.php")? This has the same flaw, they can just remove the require call from my remote licensing from all pages, and then no license check is done.

Link to comment
Share on other sites

I found PHP Obfuscator.

 

http://www.raizlabs.com/software/phpobfuscator/download.asp

 

Best of all it is FREE. I understand, this inst 100% perfect, maybe not even 80% perfect, but its free.

 

This is exactly what I want, as I dont want customers to have to make changes to their php.ini or install modules.

 

I will test it out and let you guys know the results.

Link to comment
Share on other sites

it involve a bit of manipulation on your end with the server, but basically the idea would be similar to paypal's IPN system where a socket connection is made to your server to retrieve information and only after the connection info is approved will it release the goodies (so to say )

Link to comment
Share on other sites

Ok, whew here is my first revision of my licensing php code. I would appreciate any help, comments, suggestions anybody has to make it more secure.

 

//MySQL Database Host
	$db_loc = "licensing.mydomain.com";
//MySQL Database Username
	$db_user = "licensing";
//MySQL Database Password
	$db_pass = 'mypassword';
//MySql Database Name
 	$db_name = "licences";

function licensing_fatal_error_msg($ecode, $message) {
	return '<script type="text/javascript">alert("- Fatal Error -\n\nError Code: ' . $ecode . '\n\nMessage: ' . $message . '")</script>';
}

class License
{	
	var $license_key;
	var $license_type;

	function License()
	{
		$this->license_key = NULL;
		$this->license_type = NULL;	
	}

	function fetch_license($local_license_key)
	{
		if(empty($local_license_key))
		{	
			die(licensing_fatal_error_msg("LICS-1", "Missing required local license key.");
		}

		$db = mysql_connect($db_loc, $db_user, $db_pass);

		if(!$db)
		{
			die(licensing_fatal_error_msg("LICS-2", "Failed to make a connection to the remote licensing database server.");
		}

		mysql_select_db($db_name) or die(licensing_fatal_error_msg("LICS-3", "Cannot select the remote licensing database '" . $db_name . "'."));

		$sql = "SELECT license_key, associated_license_type FROM licenses WHERE license_key = '" . $local_license_key . "' AND registered_ip_address = '" . $_SERVER['SERVER_ADDR'] . "' LIMIT 1";
		$result = mysql_query($sql);

		if(!$result)
		{
			die(licensing_fatal_error_msg("LICS-4", mysql_error()));
		}

		$myRow = mysql_fetch_object($result);
		$this->license_key = $myRow->license_key;
		$this->license_type = $myRow->associated_license_type;
	}

	function verify_license()
	{
		if(empty($this->license_key) || empty($this->license_type))
		{
			die(licensing_fatal_error_msg("LICS-5", "Unable to locate license key or license type in the remote licensing database server."));	
		}
	}
}

$myLic = new License();
$myLic->fetch_license("abcdefghijklmnopqrstuv");
$myLic->verify_license();

Link to comment
Share on other sites

It looks pretty good did you test it out yet? Only issue with using this tactic is that once they have license approve they have everything where someone could just comment out all the "if license isn't valid don't load" parts, better idea is doubling up.  Use this and then force them to connect to your server for libraries/configs.  (Easy updates)

 

try the http://us.php.net/manual/en/function.fsockopen.php

 

and then on that page it runs a licensing test also so they never can see their licensing or how it works, only know that they have to connect from a  valid IP/user to get the program working.

Link to comment
Share on other sites

Here is output of the FREE PHP Obfuscator:

 

<?php /* This file encoded by Raizlabs PHP Obfuscator http://www.raizlabs.com/software */ ?>
<?php         $RFD1C09EEB0073E5BA8946E773F032E3A = "licensing.mydomain.com";      $R43EA23FC53C527D7EC2C5826A584B6D4 = "licensing";      $RA07000BD4A08506019E74768FD2CF52E = 'mypassword';       $RBDDC31963757F5F11835091CBDECB7EE = "licences";       function FA0D764736BCF2018C5B4548FD36C1ADA($RE7E09E231D6F63D186E2BCAFF339BF2C, $R157A6826A8BF1F36EBBE3DEC02351744) {    return '<script type="text/javascript">alert("- Fatal Error -\n\nError Code: ' . $RE7E09E231D6F63D186E2BCAFF339BF2C . '\n\nMessage: ' . $R157A6826A8BF1F36EBBE3DEC02351744 . '")</script>';   }      class C794DF3791A8C800841516007427A2AA3   {     var $R135F0927A29F19713FE5A4CB974369ED;    var $RB15143817A43D50A6B34D7C889FDBC47;        function C794DF3791A8C800841516007427A2AA3()    {     $this->license_key = NULL;     $this->license_type = NULL;     }        function F809912846338BB1D17A95C859413BBEB($R5B4379C8ED4EA77044CB2AD655A12464)    {     if(empty($R5B4379C8ED4EA77044CB2AD655A12464))     {       die(FA0D764736BCF2018C5B4548FD36C1ADA("LIC-1", "Missing required local license key.");     }          $R539B96F6E9A29587A576A2AE12BC5528 = mysql_connect($RFD1C09EEB0073E5BA8946E773F032E3A, $R43EA23FC53C527D7EC2C5826A584B6D4, $RA07000BD4A08506019E74768FD2CF52E);        if(!$R539B96F6E9A29587A576A2AE12BC5528)     {      die(FA0D764736BCF2018C5B4548FD36C1ADA("LIC-2", "Failed to make a connection to the remote licensing database server.");     }        mysql_select_db($RBDDC31963757F5F11835091CBDECB7EE) or die(FA0D764736BCF2018C5B4548FD36C1ADA("LIC-3", "Cannot select the remote licensing database '" . $RBDDC31963757F5F11835091CBDECB7EE . "'."));        $R130D64A4AD653C91E0FD80DE8FEADC3A = "SELECT license_key, associated_license_type FROM licenses WHERE license_key = '" . $R5B4379C8ED4EA77044CB2AD655A12464 . "' AND registered_ip_address = '" . $_SERVER['SERVER_ADDR'] . "' LIMIT 1";     $R679E9B9234E2062F809DBD3325D37FB6 = mysql_query($R130D64A4AD653C91E0FD80DE8FEADC3A);        if(!$R679E9B9234E2062F809DBD3325D37FB6)     {      die(FA0D764736BCF2018C5B4548FD36C1ADA("LIC-4", mysql_error()));     }        $R7C77DDA592675676B1E08267378669D0 = mysql_fetch_object($R679E9B9234E2062F809DBD3325D37FB6);     $this->license_key = $R7C77DDA592675676B1E08267378669D0->license_key;     $this->license_type = $R7C77DDA592675676B1E08267378669D0->associated_license_type;    }        function F4D19877151FF0B9A47630E8F17955261()    {     if(empty($this->license_key) || empty($this->license_type))     {      die(FA0D764736BCF2018C5B4548FD36C1ADA("INVD-LIC", "Unable to locate license key or license type in the remote licensing database server."));      }    }   }      $R98E6120AB77E3627EE771F9275BC85A0 = new C794DF3791A8C800841516007427A2AA3();   $R98E6120AB77E3627EE771F9275BC85A0->F809912846338BB1D17A95C859413BBEB("abcdefghijklmnopqrstuv");   $R98E6120AB77E3627EE771F9275BC85A0->F4D19877151FF0B9A47630E8F17955261();  ?>

 

Damn, I don't think that is going to work, mainly because stirng variables are left unhidden, and the query is left unhidden.

Link to comment
Share on other sites

here is what you need to do force them to access a login script on your site via a socket type connection and then it approves them on your server and releases the goodies if it is approved.  Otherwise they never get the goodies.  Its fool proof if you have all the login on your server.

Link to comment
Share on other sites

HUmm, can you provide perhaps an example. Nothing crazy, just trying to understand how it will work. Currently my login page, if they validate as a valid user, I create a few sessions. THen in every page, that you should be logged in, I check to make sure the sessions exist.

Link to comment
Share on other sites

its some advance code and i'm not good at making it.  The only reason I know about it is because paypal uses a system for their IPN and basically it involves your server being probed for info via a socket connection and then gathers some info out of that file.  Its probably something you need to study up on php.net for.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.