JustinK101 Posted June 26, 2007 Share Posted June 26, 2007 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? Quote Link to comment Share on other sites More sharing options...
Dragen Posted June 26, 2007 Share Posted June 26, 2007 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. Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 26, 2007 Author Share Posted June 26, 2007 Yeah I think I need to do code encryption. It is the only way to really protect the code and licensing. That way I can simply encrypt every page and they cannot remove the require() statement. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 26, 2007 Share Posted June 26, 2007 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. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 26, 2007 Share Posted June 26, 2007 and for the mysql user that acceses the server give them execution only rights. Quote Link to comment Share on other sites More sharing options...
ToonMariner Posted June 26, 2007 Share Posted June 26, 2007 if you refer to having this on other peoples servers then you shoudl look at ioncube or zend guard or similar... Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 27, 2007 Author Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 27, 2007 Author Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 27, 2007 Share Posted June 27, 2007 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 ) Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 27, 2007 Author Share Posted June 27, 2007 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(); Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 27, 2007 Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 27, 2007 Author Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 27, 2007 Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
JustinK101 Posted June 27, 2007 Author Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted June 27, 2007 Share Posted June 27, 2007 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.