Moorcam Posted October 23 Share Posted October 23 Hello folks, I am trying to create a script that will check the current domain, compare it with an array of domains that are stored externally in domains.php. If we have a match, great. If not, show an error. I am using CURL because of the vulnerabilities used using allow_url_include() so don't want to use that. Here is domains.php <?php // domains.php // Prevent direct access if (basename($_SERVER['PHP_SELF']) === basename(__FILE__)) { die('Access denied.'); } // Array of allowed domain names $domains_content = [ 'test1.com', 'test.com', 'mywebsite.org' ]; ?> Here is the function for checking: // This script checks if the current domain is in the allowed domains list. // Function to fetch the external PHP file using CURL function fetchDomains($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception('CURL Error: ' . curl_error($ch)); } curl_close($ch); return $response; } try { // URL of the external PHP file $url = 'https://www.domain/domains.php'; // Replace with the actual URL // Fetch the domains $domains_content = fetchDomains($url); // Evaluate the fetched content to get the array eval('?>' . $domains_content); // Get the current domain $current_domain = $_SERVER['HTTP_HOST']; // Check if the current domain is in the allowed domains if (!in_array($current_domain, $domains_content)) { throw new Exception('Error: The current domain "' . $current_domain . '" is not allowed.'); } echo 'Domain check passed. Current domain: ' . $current_domain; } catch (Exception $e) { // Handle exceptions and display error message echo 'An error occurred: ' . $e->getMessage(); } I haven't included the actual domain I am checking for privacy reasons but you get the drift. Here is the error I am getting: [24-Oct-2024 00:04:58 Australia/Melbourne] PHP Warning: in_array() expects parameter 2 to be array, string given in includes/header.php on line 85 Here is that line: if (!in_array($current_domain, $domains_content)) { throw new Exception('Error: The current domain "' . $current_domain . '" is not allowed.'); } If anyone can help resolve this I would appreciate it. The domain the script is hosted on is actually listed in the array. Quote Link to comment Share on other sites More sharing options...
Psycho Posted October 23 Share Posted October 23 What you have defined for $domains_content in your first bit of posted code is irrelevant to your error, because 1) it is defined outside your function and 2) you redefine that variable shortly before the error // URL of the external PHP file $url = 'https://www.domain/domains.php'; // Replace with the actual URL // Fetch the domains $domains_content = fetchDomains($url); So, what is the result of that call? It's apparently not an array. try adding this right after the last line above to see what is actually returned: var_dump($domains_content); EDIT: Correction, the error is in a block of code outside your function, so #1 in my response is not valid Quote Link to comment Share on other sites More sharing options...
Moorcam Posted October 23 Author Share Posted October 23 8 minutes ago, Psycho said: What you have defined for $domains_content in your first bit of posted code is irrelevant to your error, because 1) it is defined outside your function and 2) you redefine that variable shortly before the error // URL of the external PHP file $url = 'https://www.domain/domains.php'; // Replace with the actual URL // Fetch the domains $domains_content = fetchDomains($url); So, what is the result of that call? It's apparently not an array. try adding this right after the last line above to see what is actually returned: var_dump($domains_content); Using var_dump I get 301 error "Permanently Moved" Quote Link to comment Share on other sites More sharing options...
Psycho Posted October 23 Share Posted October 23 47 minutes ago, Moorcam said: Using var_dump I get 301 error "Permanently Moved" I assume you got more than that from the var_dump. But, in any case, that response is not an array - correct? That would be why the in_array() function is failing with that error. So now you need to debug why passing your domain (which is not the same in your code above) is causing this error. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted October 23 Share Posted October 23 the curl code is making a http(s) request to the URL, just like a browser would. because it is to a .php page, the php code is being executed on the target server and what you get back is whatever that page outputs. you do not get the raw php code. because you are trying to transfer data, i recommend that you use JSON and use echo json_encode($domains_content); in the domains.php code, then after you successfully receive that JSON string from the curl call, you can use json_decode() on it to get the array of data. 1 Quote Link to comment Share on other sites More sharing options...
Moorcam Posted October 23 Author Share Posted October 23 16 minutes ago, mac_gyver said: the curl code is making a http(s) request to the URL, just like a browser would. because it is to a .php page, the php code is being executed on the target server and what you get back is whatever that page outputs. you do not get the raw php code. because you are trying to transfer data, i recommend that you use JSON and use echo json_encode($domains_content); in the domains.php code, then after you successfully receive that JSON string from the curl call, you can use json_decode() on it to get the array of data. domains.php: <?php // allowed_domains.php // Prevent direct access if (basename($_SERVER['PHP_SELF']) === basename(__FILE__)) { die('Access denied.'); } // Array of allowed domains $allowed_domains = [ 'example.com', 'test.com', 'mywebsite.org' ]; // Return the allowed domains as a JSON encoded string echo json_encode($allowed_domains); ?> site.php // This script checks if the current domain is in the allowed domains list. // Function to fetch allowed domains function fetchAllowedDomains($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception('CURL Error: ' . curl_error($ch)); } curl_close($ch); return json_decode($response, true); } try { // URL of the external PHP file $url = 'https://www.site.com/domains.php'; // Fetch allowed domains $allowed_domains = fetchAllowedDomains($url); // Get the current domain $current_domain = $_SERVER['HTTP_HOST']; // Check if the current domain is in the allowed domains if (!in_array($current_domain, $allowed_domains)) { throw new Exception('Error: The current domain (' . $current_domain . ') is not allowed.'); } echo 'Domain check passed. Current domain is allowed.'; } catch (Exception $licenseMsg) { // Handle exceptions echo $licenseMsg->getMessage(); } Error: [24-Oct-2024 02:04:42 Australia/Melbourne] PHP Warning: in_array() expects parameter 2 to be array, null given in includes/header.php on line 83 Thanks guys. Your help is appreciated. Quote Link to comment Share on other sites More sharing options...
Psycho Posted October 23 Share Posted October 23 I'm not well versed in using cURL, but based on what you provided previously your call to the URL you are using is returning the response: 301 error "Permanently Moved" But, you expect to be getting the JSON encoded output for the $allowed_domains array you are creating. I would assume you have tested the url in a browser and verified you are seeing the JSON content? If not, start there. If the content is correct when access via a browser then my best guess is that the web server maybe has some logic to detect programmatic access to pages and is blocking it. I'm pretty sure I've seen something like that before. But your issue has noting to do with the error you first reported. You need to figure out why your cURL request is not retrieving the JSON content you think it should be returning. Although, this is a good opportunity to add additional error handling to your code to cover a scenario where the cURL request doesn't fail, but does not return contents you expect. 1 Quote Link to comment Share on other sites More sharing options...
Moorcam Posted October 24 Author Share Posted October 24 Ok it's weird. Have directly accessed the file in a browser and get the array of domains. However, when I access via the script, I now get: [24-Oct-2024 11:35:34 Australia/Melbourne] PHP Warning: in_array() expects parameter 2 to be array, null given in includes/header.php on line 76 I have also rewritten the code to add error and exception handling: // This script checks if the current domain is in the allowed domains list. // Function to fetch valid domains from the external file function fetchValidDomains($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Execute cURL request and handle potential errors $response = curl_exec($ch); if ($response === false) { throw new Exception('cURL Error: ' . curl_error($ch)); } curl_close($ch); // Decode the JSON response and handle potential errors $domains = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('JSON Decode Error: ' . json_last_error_msg()); } return $domains; } try { // Get the current domain $currentDomain = $_SERVER['HTTP_HOST']; // URL of the external PHP file $externalFileUrl = 'http://www.site.com/domains.php'; // Fetch valid domains $validDomains = fetchValidDomains($externalFileUrl); // Check if the current domain is in the valid domains array if (!in_array($currentDomain, $validDomains)) { throw new Exception('Error: The current domain is not authorized.'); } // If the domain is valid echo 'The current domain is authorized.'; } catch (Exception $e) { // Handle exceptions and display error message echo 'An error occurred: ' . $e->getMessage(); } I'm at a loss. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted October 24 Author Share Posted October 24 Further to the last post, I am also getting this: An error occurred: JSON Decode Error: Syntax error Quote Link to comment Share on other sites More sharing options...
Solution Moorcam Posted October 24 Author Solution Share Posted October 24 Ok, it now works. I changed the domains.php file to the following: <?php // domains.php // Array of domains $domains = [ "example.com", "example.org", "example.net", "example.edu" ]; // Set the content type to application/json header('Content-Type: application/json'); // Encode the array to JSON and output it echo json_encode($domains); ?> Changed the domains to be encased in double quotes rather than single quotes and also set the type to application/json Although it will not work in localhost because of local certificate errors, it does work in a live server environment. Thank you both for your help. It's appreciated. So, for anyone wanting this, here is the rest of the code: <?php // This script checks if the current domain is in the allowed domains list. // Function to fetch domains from the external PHP file function fetchDomains($url) { $ch = curl_init(); // Set cURL options curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Execute cURL request $response = curl_exec($ch); // Error handling for cURL if (curl_errno($ch)) { throw new Exception('cURL Error: ' . curl_error($ch)); } curl_close($ch); // Decode the JSON response $domains = json_decode($response, true); // Error handling for JSON decoding if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('JSON Decode Error: ' . json_last_error_msg()); } return $domains; } // Main execution try { $url = 'https://www.site.com/domains.php'; // Replace with the actual URL of the external PHP file $domains = fetchDomains($url); // Get the current domain $currentDomain = $_SERVER['HTTP_HOST']; // Check if the current domain is in the fetched array if (!in_array($currentDomain, $domains)) { echo "Your domain, ($currentDomain) is not on the list."; } } catch (Exception $e) { // Handle exceptions echo "An error occurred: " . $e->getMessage(); } ?> 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.