secure use of authorization token in cURL in PHP - php

I am developing single page application in PHP. I am fetching products data from external API using cURL. API is secured and I have to provide the token.
I want to know that is it secure way to add this token in my index.php page (like I did in the below example), I don't want that someone else misuse the token by inspecting or getting it from the server
<?php
$ch = curl_init();
$url = "http://example.com/v1/products";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = array(
'Content-Type:application/json',
'Authorization: Bearer abcxyzabac*******'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if($e = curl_error($ch)) {
echo $e;
}
else {
$decoded = json_decode($response, true);
}
curl_close($ch);
?>
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<?php
foreach($decoded as $dec)
{
echo $dec->name;
}
?>
</body>
</html>

Related

Post multiple form field data to 3rd party server after Google Invisible reCaptcha success?

So I am new to this so please excuse me if my question is not posted as expected. Any suggestions and advice will be kindly appreciated.
So I have a form with multiple fields that posts to an PHP file that verifies an Invisible Google reCAPTCHA and then proceeds to post to Pardot (third party software that notifies our sales team)
Following this post How to Post Form Data to 3rd Party Server After Google Invisible reCaptcha Success?
I can successfully send the email form field to Pardot but I can not seem to send any other fields and/or replace the email field with another one.
In other words I have two fields name="firstname" and name="email" when I send the email field it posts but if I change "email" to "firstname" in the PHP it does not fire.
Based on what I have read I am relatively sure I will need to create an array on the CURLOPT_POSTFIELDS section of my PHP that currently only sends one value ($pardotPost) but before I attempt to send an array I wanted to test the other form fields to see if works as mentioned above.
Here is my client side markup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Form</title>
<style>
input:required:invalid, input:focus:invalid {
/* insert your own styles for invalid form input */
-moz-box-shadow: none;
color: red!important;
}
input:required:valid {
/* insert your own styles for valid form input */
color: green!important;
}
</style>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
document.getElementById("pardot-form-full-width").submit();
}
</script>
</head>
<body>
<div class="mn-call-form-wrapper">
<form id="pardot-form-full-width"
class="uk-form uk-grid-medium uk-form-horizontal invisible-recaptcha"
action="reCAPTCHA.php"
method="POST"
enctype="multipart/form-data"
uk-grid>
<!-- First Name -->
<div class="uk-width-1-2#s">
<input placeholder="First Name *"
class="mix-contact-form-item uk-input"
type="text"
id="firstname"
name="firstname"
required=”required”/>
</div>
<!-- END - First Name -->
<!-- Email Address -->
<div class="uk-width-1-2#s">
<input placeholder="Email *"
class="mix-contact-form-item uk-input"
type="email"
id="email"
name="email"
required="required"/>
</div>
<!-- END - Email Address -->
<!-- Submit Button -->
<div class="mix-signup-submit-button-wrapper">
<button class="g-recaptcha"
data-sitekey="myGrecaptchaKeyIsHere"
data-callback="onSubmit"> Send <span uk-icon="arrow-right" class="uk-icon"></span>
</button>
</div>
<!-- END - Submit Button -->
</form>
</div>
</body>
</html>
Here is my server side markup (reCAPTCHA.php):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Results</title>
</head>
<body>
<?php
// reCaptcha info
$secret = "mySecretKey";
$remoteip = $_SERVER["REMOTE_ADDR"];
$url = "https://www.google.com/recaptcha/api/siteverify";
// Form info
$firstname = $_POST["firstname"];
$response = $_POST["g-recaptcha-response"];
// Curl Request
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
));
$curlData = curl_exec($curl);
curl_close($curl);
// Parse data
$recaptcha = json_decode($curlData, true);
if ($recaptcha["success"]) {
echo "Thank you, we will be in contact with you soon.";
$pardotPost ='firstname='. $_POST["firstname"];
$curl_handle = curl_init();
$url = "http://pardot.com/our/url";
curl_setopt ($curl_handle, CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl_handle, CURLOPT_POSTFIELDS, $pardotPost);
curl_setopt( $curl_handle, CURLOPT_SSL_VERIFYPEER, false );
$result = curl_exec ($curl_handle);
curl_close ($curl_handle);
}
else {
echo "Oh no, it seems something went wrong.";
}
?>
</body>
</html>
In the PHP sections below if I change the values from firstname to email I can confirm the data is sent and ingested by Pardot
// Does not work
$firstname = $_POST["firstname"];
$pardotPost ='firstname='. $_POST["firstname"];
// Does work
$email = $_POST["email"];
$pardotPost ='email='. $_POST["email"];
So my question is two parts.
One - why does the form submit if the email value is used and secondly how would I go about adding several other form fields and send them to Pardot after successful (invisible) Google reCAPTCHA validation?
Thanks in advance!
Okay so this seems to work:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Results</title>
</head>
<body>
<?php
// reCaptcha info
$secret = "key-goes-here";
$remoteip = $_SERVER["REMOTE_ADDR"];
$url = "https://www.google.com/recaptcha/api/siteverify";
// Form info
$email = $_POST["email"];
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$phone = $_POST["phone"];
$querytype = $_POST["querytype"];
$message = $_POST["message"];
$termsconditionsfw = $_POST["termsconditionsfw"];
$response = $_POST["g-recaptcha-response"];
// Curl Request
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
));
$curlData = curl_exec($curl);
curl_close($curl);
// Parse data
$recaptcha = json_decode($curlData, true);
if ($recaptcha["success"]) {
echo "Thank you, we will be in contact with you soon.";
//extract data from the post
//set POST variables
$url = 'http://explore.mixtelematics.com/l/69882/2019-01-15/d3zr3d';
$fields = array(
'email' => urlencode($_POST['email']),
'firstname' => urlencode($_POST['firstname']),
'lastname' => urlencode($_POST['lastname']),
'phone' => urlencode($_POST['phone']),
'querytype' => urlencode($_POST['querytype']),
'message' => urlencode($_POST['message']),
'termsconditionsfw' => urlencode($_POST['termsconditionsfw']),
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
}
else {
echo "Oh no, it seems something went wrong.";
}
?>
</body>
</html>
When I submit this, it sends the information to Pardot :)

JSON_DECODE returning NULL from cURL response even though encode format seems correct?

EDIT: For the solution, view reply from Barmar below. Hope this helps anyone with a similar problem.
I'm trying to take a login from my test.php file and cURL it to a site which uses the data to simulate a login on another page (I know this is tedious, but this isn't the full extent of what I'm doing as a whole, just where I have the problem). So I post an encoded json to the index.php url which has no problem decoding it. The information passed is then used and the decoded json is edited to show successful or unsuccessful login. The json is then encoded once again and echoed onto the page and held in $contents on test.php. When I try to decode it on this file I get NULL everytime. I've tried a ton of things and am just starting to think I made a stupid mistake somewhere so I'm desperately looking for any help here.
-If I echo $contents it shows:
{"user":"user","pass":"password","success":true}
-If I var_dump(trim($contents)) it shows (formatted exactly as shown):
string(364) "
{"user":"user","pass":"password","success":true} "
-last_json_error_msg shows:
SYNTAX ERROR
-I've tried trimming, utfencoding, iconv, setting curl headers and literally everything I've seen recommended on other posts here.
Any help at all would be greatly appreciated. Thanks in advance guys.
test.php:
<html>
<head>
<meta charset="UTF-8">
<title>TITLE</title>
</head>
<body>
<form action="test.php" method=POST>
<input type="text" name="user">
<input type="password" name="pass">
<input type="submit" value="Submit">
</form>
<?php
function logInfo(){
class data{
public $user = "";
public $pass = "";
public $success = false;
}
$data = new data();
$data->user = $_POST['user'];
$data->pass = $_POST['pass'];
$ch = curl_init();
$json = json_encode($data);
curl_setopt($ch, CURLOPT_URL, [URL TO INDEX.PHP]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array("data"=>$json));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$contents = curl_exec($ch);
curl_close($ch);
$array = json_decode($contents, true);
var_dump($array);
//VAR_DUMP SHOWS NULL
}
if(isset($_POST['user']) && isset($_POST['pass'])){
logInfo();
}
?>
</body>
</html>
index.php:
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="test.php" method=POST>
<input type="hidden" name="data">
</form>
<?php
header('Context-type: application/json');
function logInfo(){
$datastring = $_POST['data'];
$data = json_decode($datastring);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, [URL TO SIMULATE LOGIN]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [LOGIN POST]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($code == [SUCCESSFUL LOGIN HTTP CODE]){
$data->success = true;
} else {
$data->success = false;
}
echo json_encode($data);
curl_close ($ch);
}
if(isset($_POST['data'])){
logInfo();
}
?>
</body>
</html>
EDIT: For the solution, view reply from Barmar below. Hope this helps anyone with a similar problem.
index.php is printing HTML before the JSON (weren't you suspicious when var_dump() said that the string is 365 characters long, but you can only see about 50?). When the script is being used to return JSON, it can't produce any other output.
So check for the data parameter before printing any output. And if it's found, exit the script after sending the JSON, so you don't print the HTML.
<?php
if(isset($_POST['data'])){
logInfo();
exit();
}
?>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="test.php" method=POST>
<input type="hidden" name="data">
</form>
<?php
</body>
</html>
<?php
function logInfo(){
header('Context-type: application/json');
$datastring = $_POST['data'];
$data = json_decode($datastring);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, [URL TO SIMULATE LOGIN]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [LOGIN POST]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($code == [SUCCESSFUL LOGIN HTTP CODE]){
$data->success = true;
} else {
$data->success = false;
}
echo json_encode($data);
curl_close ($ch);
}
A simpler solution would probably be to put the code that returns logInfo() into a different script.
You should do
json_encode(get_object_vars($data));
in logInfo function
A couple of things I would recommend. It's not a good practice to define a class inside a function. You should have your class in a separate file. It helps keep your code organised.
Secondly, its good to follow either snake case or camel case for defining classes / methods / functions etc.
Snake case eg: my_function_name_to_execute
Camel case eg: MyFunctionNameToExecute
Try to check resulting JSON syntax using this library https://github.com/Seldaek/jsonlint
UPDATE
It correctly detects extra HTML from index.php and other possible problems.
Following example
use Seld\JsonLint\JsonParser;
$parser = new JsonParser();
$exception = $parser->lint('<html>{"user":"user","pass":"password","success":true}');
echo $exception->getMessage();
will output:
Parse error on line 1:
<html>{"user":"user"
^
Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

get xml of gestis database

i try to get the (not xml aparently) content of this website:
http://gestis.itrust.de/nxt/gateway.dll/gestis_de/010520.xml?f=templates$fn=default-doc.htm$3.0
via curl or file_get_contents in php.
you can open the website in any browser but whenever i try to open it with php to get the content automated it will return a 500 error.
here is the code used:
<?php
/* gets the data from a URL */
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$returned_content = get_data('http://gestis.itrust.de/nxt/gateway.dll/gestis_de/010520.xml?f=templates$fn=default-doc.htm$3.0');
echo $returned_content;
?>
does anybody have an idea how to get the xml via php from this website?
The website you want to open needs the vid=gestisdeu:sdbdeu value in form of a cookie to work:
Cookie: nxt/gateway.dll/vid=gestisdeu%3Asdbdeu;
Please consult the curl documentation how you can set cookies or take a look into the existing material that is already on this webiste, for example Is it possible to set the cookie content with CURL? and the like.
Take care that depending on website and their configuration changes this might become different. So technically your question can't be really answered, because that website doesn't have any documentation of it's HTTP request requirements. So you need to find out on your own and provide those if you ask such a question.
PHP Example:
$url = 'http://gestis.itrust.de/nxt/gateway.dll/gestis_de/010520.xml?f=templates$fn=default-doc.htm$3.0';
$options['http'] = ['header' => 'Cookie: nxt/gateway.dll/vid=gestisdeu%3Asdbdeu;'];
stream_context_set_default($options);
$content = file_get_contents($url);
var_dump($content);
Output:
string(104975) "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>DGUV-IFA GESTIS</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body>
<html>
<head>
<META http-equiv="Content-Type" content="text/html">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="/nxt/gateway.dll/gestis_de/010520.xml?f=stylesheets$fn=gestis-doc.css$up=1$3.0" type="text/css">
<"...

Send xml to webservices using Curl in PHP but returns error

I have a web service to which I send a xml request (application/x-www-form-urlencoded encoded) and get a response back. These are sent to the URL contained within a query parameter called 'xml'
When I use a simple html form such as the one below, I am returned a result. However, when I use my php code, I am returned an error. Perhaps it is because of this: These are sent to the URL contained within a query parameter called 'xml'? If that's the case, how do I send it in that parameter? I'd be very grateful if someone could point out what I've been doing wrong. Many thanks
<form method="post" name="form1" action="http://webservicesapi.com/login.pl">
<textarea cols="80" rows="20" name="xml">
<?xml version="1.0"?><request><auth username="hello" password="world" /><method action="login" /></request>
</textarea>
<input type="submit" value="submit XML document">
</form>
This doesn't work:
<?php
// open a http channel, transmit data and return received buffer
function xml_post($xml, $url, $port)
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off'))
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_PORT, $port); //Set the port number
curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); // add POST fields
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
if($port==443)
{
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
}
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$xml = '<?xml version="1.0"?><request><auth username="hello" password="world" /><method action="login" /></request>';
$url ='http://webservicesapi.com/login.pl';
$port = 80;
$response = xml_post($xml, $url, $port);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
</head>
<body>
<P><?=nl2br(htmlentities($response));?></P>
</body>
</html>
?>
CURLOPT_POSTFIELDS expects either an associative array, or a raw post string. Since you are passing it a string, it treats it as a raw post string. So either of these should work:
$response = xml_post(array('xml' => $xml), $url, $port);
OR
$response = xml_post('xml='.urlencode($xml), $url, $port);

cURL POST data Problem

im bizzare and im new in stackoverflow , i have some problem and that's :
im sending some page directly to a page and page answer to my request correctly , but i when to try send post data using cURL by php , the page do not react anywhere:
<form action="http://remotehost.com/index.aspx" method="post"> -> its work correctly and the index.php show me what i want but when :
<form action ="http://localhost/fetch_data.php" mthod="post"> ->
fetch_data.php:
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<?php
print_r($_POST);
$remotehost_cgi = 'http://remotehost.com/index.aspx';
$ret = post_data($_POST, $remotehost_cgi);
echo $ret;
?>
<?php
function post_data($datatopost,$urltopost){
$crl = curl_init ($urltopost);
curl_setopt ($crl, CURLOPT_POST, true);
curl_setopt ($crl, CURLOPT_POSTFIELDS, $datatopost);
curl_setopt ($crl, CURLOPT_RETURNTRANSFER, true);
$returndata = curl_exec ($crl);
return $returndata;
}
?>
mthod="post" to method="post" ?
curl_exec() returns boolean FALSE if the exec failed for any reasons. Instead of just returning your $returndata, test it first:
...
$returndata = curl_exec($crl);
if ($returndata === FALSE) {
die('Curl failed: ' . curl_error($crl));
}
return($returndata);
Since you only echo out this value, you'd never see it, as boolean false will output as a null/empty string.

Categories