Use Curl to securely access data on another server

Viewed 52

I want to validate license in my plugin.

User on his website enters token (provided by me) and I want to validate this by contacting my server using curl.

For example,

Code in plugin:

function curl_url( $url ) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url );

    $cr = curl_exec($ch);

    curl_close($ch);

    return $cr;
}

$confirm = 'https://my-website.com/some_folder/some_file.php?token=' . $token;

$response = json_decode( curl_url( $confirm ) );

Code on my website in some_file.php:

if(isset($_GET['token'])){
    validate();  

}

function validate(){
    $token= $_GET['token'];
    //check if valid, provide response...
}

MY questions:

  1. How good or bad approach is this, what do you advise to me?

  2. What is some advanced user sees code in my plugin and then uses this url for some malicious attacks?

    https://my-website.com/some_folder/some_file.php

1 Answers

Currently if I try to reach my server from another domain, I dont get any errors and request works so I ma not sure why I need CURLOPT_CAINFO. – Toniq

Compare the results between the two domains.

curl_getinfo is very useful.

CURLINFO_HEADER_OUT
echo curl_getinfo($ch,CURLINFO_HEADER_OUT);

Other useful curl info.

CURLINFO_SSL_VERIFYRESULT
CURLINFO_HTTPAUTH_AVAIL
CURLOPT_HTTPAUTH the HTTP authentication method(s) to use.
CURLINFO_SSL_ENGINES
CURLINFO_CERTINFO true to output SSL certification information to STDERR on secure transfers
CURLINFO_APPCONNECT_TIME

Options

CURLOPT_UNRESTRICTED_AUTH
CURLOPT_SSLVERSION Your best bet is to not set this and let it use the default. 
CURLOPT_SSL_OPTIONS
CURLOPT_KEYPASSWD
CURLOPT_PINNEDPUBLICKEY
CURLOPT_SSH_PRIVATE_KEYFILE 
CURLOPT_CAPATH A directory that holds multiple CA certificates
CURLOPT_CAINFO The name of a file holding one or more certificates to verify the peer with. 
CURLOPT_SSL_VERIFYHOST 0 to not check the names. 1 should not be used. 2 to verify that a Common Name field 
CURLOPT_SSL_VERIFYPEER  false to stop cURL from verifying the peer's certificate. 
CURLOPT_SSL_VERIFYSTATUS  true to verify the certificate's status. 
CURLOPT_CERTINFO true to output SSL certification information to STDERR on secure transfers. 
CURLOPT_FRESH_CONNECT   true to force the use of a new connection instead of a cached one. 
CURLOPT_SSL_ENABLE_NPN
CURLOPT_SSL_ENABLE_ALPN
CURLOPT_SSL_FALSESTART  true to enable TLS false start. 
CURLOPT_SSH_AUTH_TYPES
CURLOPT_LOGIN_OPTIONS
CURLOPT_SSL_CIPHER_LIST
CURLOPT_SSLCERTPASSWD
CURLOPT_SSLKEY
CURLOPT_SSLENGINE
CURLOPT_SSLKEYPASSWD
CURLOPT_SSLKEYTYPE
CURLOPT_SSL_CIPHER_LIST
CURLOPT_SSH_PRIVATE_KEYFILE
CURLOPT_SSH_PUBLIC_KEYFILE
CURLOPT_USERNAME
CURLOPT_PASSWORD
CURLOPT_USERPWD [username]:[password]
CURLOPT_XOAUTH2_BEARER  Specifies the OAuth 2.0 access token. 

CURLOPT_VERBOSE
CURLOPT_STDERR  A file handle to output errors to instead of STDERR. 
$errno = curl_errno($ch)
$error_message = curl_strerror($errno);

You should be checking for errors.

CURLOPT_VERBOSE
CURLOPT_STDERR  A file handle to output errors to instead of STDERR. 
$errno = curl_errno($ch)
$error_message = curl_strerror($errno);  

CURLError codes

CURLE_SSL_CONNECT_ERROR (35)
CURLE_SSL_ENGINE_NOTFOUND (53)
CURLE_SSL_ENGINE_SETFAILED (54)
CURLE_SSL_CERTPROBLEM (58)
CURLE_SSL_CIPHER (59)
CURLE_PEER_FAILED_VERIFICATION (60)
CURLE_SSL_ENGINE_INITFAILED (66)
CURLE_LOGIN_DENIED (67)
CURLE_SSL_CACERT_BADFILE (77)
CURLE_SSH (79)
CURLE_SSL_CRL_BADFILE (82)
CURLE_SSL_ISSUER_ERROR (83)
CURLE_SSL_PINNEDPUBKEYNOTMATCH (90)
CURLE_SSL_INVALIDCERTSTATUS (91)
CURLE_AUTH_ERROR (94)
CURLE_SSL_CLIENTCERT (98)

Can you provide this header example? – Toniq

Add header to curl:

$token = 'token';
$request = array();
$request[] = "X-Token: $token";
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);

When received by the server:

Content-Length: 55098
Content-Type: application/x-www-form-urlencoded
Connection: close
X-Token: token

The code for server to read header:

foreach (getallheaders() as $key=> $value) {
   $header[$key] = $value;
}
$token = $header['X-Token'];

It appears you may be in over your head. You should have known this considering what you are trying to do. This is the very easy part. You still need to deal with the SSL (CURLOPT_CAINFO).



You probably need to specify the SSL certificate or the path to the CA.
From PHP manual's curl_setopt page

Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.

In the url script try this code to get the details of your request.
It should help you find the problem in your request.
I've been using it for years and it has helped so many times.

I copied this code a PHP script, here is the script.
You could use this link as your curl URL.

LINK to the code below

<?php
header('Content-Type: text/plain; charset=UTF-8');
$decode = false;
foreach (getallheaders() as $name => $value) {
    if(strpos($value,'urlenc')){$decode = true;};
    echo "$name: $value\n";
}
echo "\nBODY\n";
$body = file_get_contents('php://input');
//if($decode){$body = urldecode($body);}
echo $body;

echo "\n\n\$_SERVER['QUERY_STRING'])\n";
echo urldecode($_SERVER['QUERY_STRING']);
echo "\n\nargv\n";
foreach($_SERVER['argv']as $key=>$value){
  echo "\n$key = " . urldecode($value) . "\n";
}
echo "\n\$_POST\n";
var_export($_POST);

echo "\n\$_GET\n";
var_export($_GET);

echo "\n\$_REQUEST\n";
var_export($_REQUEST);

echo "\n\$_FILES\n";
var_export($_FILES);
echo "\n\$_SERVER\n";
var_export($_SERVER);
exit;
Related