0

I have a POST function contained in my page. I am trying to call it directly for my CURL Function, notice in the following code the url variable is set to http://dirtrif.loc/installs.php

//extract data from the post
//set POST variables

$cookie_name = "drcuserid";

if(isset($_COOKIE[$cookie_name]))
{
  $cookie = $_COOKIE[$cookie_name];
}
$url = 'http://dirtrif.loc/installs.php';
$fields['username'] = $vbulletin->userinfo[username];
$fields['webmasteremail'] = $vbulletin->options[webmasteremail];
$fields['cookie'] = $_COOKIE[$cookie_name];

//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);


echo $fields_string;

This is causing an issue when the CURL script is executed, by navigating to the actual page and not running the portion that it's supposed to.

I currently have the post portion set up as follows in my installs.php:

if (isset($_POST['username'])) {
  $vbulletin->db->query_write("
  INSERT INTO " . TABLE_PREFIX . "installs (
    username,
    webmasteremail,
    cookie
  ) VALUES (" .
    $_POST['username'] .", '" .
    $_POST['webmasteremail'] . ", '" .
    $_POST['cookie'] . "'
  )");
}

Is there a way I can change the URL in my CURL code to point directly to that part of the installs.php page?

the full contents of installs.php (note* I have made a few changes since posting this question)

<?php
// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);

// #################### DEFINE IMPORTANT CONSTANTS #######################
define('THIS_SCRIPT', 'installs');
define('CSRF_PROTECTION', true);
define('CSRF_SKIP_LIST', '');

// ################### PRE-CACHE TEMPLATES AND DATA ######################

// pre-cache templates used by all actions
$globaltemplates = array(
  'installs'
);

// pre-cache templates used by specific actions
$actiontemplates = array();

// ######################### REQUIRE BACK-END ############################
require_once('./global.php');

// ######################### VARIABLES ############################

$username       = $_POST['username'];
$userid         = $_POST['userid'];
$email          = $_POST['email'];
$addontitle     = $_POST['addontitle'];
$addonversion   = $_POST['addonversion'];
$bburl          = $_POST['bburl'];
$bbtitle        = $_POST['bbtitle'];
$webmasteremail = $_POST['webmasteremail'];
$cookie         = $_POST['cookie'];

    if (isset($_POST['username'])) {
      $db->query_write("
      INSERT INTO " . TABLE_PREFIX . "installs (
        username,userid,email,addontitle,addonversion,bburl,bbtitle,webmasteremail,cookie,dateline
      ) VALUES (
        '$username',
        '$userid',
        '$email',
        '$addontitle',
        '$addonversion',
        '$bburl',
        '$bbtitle',
        '$webmasteremail',
        '$cookie',
        NOW()
      )");
    }

// #######################################################################
// ######################## START MAIN SCRIPT ############################
// #######################################################################

$navbits = array();
$navbits[$parent] = 'Installs Page';
$navbits = construct_navbits($navbits);

eval('$navbar = "' . fetch_template('navbar') . '";');
eval('print_output("' . fetch_template('installs') . '");');
?>
DrCustUmz
  • 370
  • 3
  • 15
  • the last portion of code above - is that a snippet from `installs.php`? The upper piece of code is that also just an extract? And can you clarify: You want to send a POST request, using cURL, to `installs.php` but only execute SOME of the code on that page? If you were to add ALL of `installs.php` it would help identify what can be done – Professor Abronsius Jun 07 '20 at 07:59
  • @RamRaider yes, the bottom code is from installs.php and the top code is called via an install script that can be executed anywhere. inside of installs.php is just more php/html – DrCustUmz Jun 07 '20 at 08:12
  • your question is a little vague - but you can have sections in the installs script that can be targeted - for instance include a field `action` in the POST fields and use a `switch` statement in installs - such as `switch($_POST['action']){ case 'install':/* code*/break; case 'uninstall':break; }` – Professor Abronsius Jun 07 '20 at 08:16
  • how is it vague? I want to call the part I stated via the url, I just dont know how to do it, EXAMPLE: dirtrif.loc/installs.php?post i just know thats far from correct that way in the curl URL i can use that as my URL @RamRaider – DrCustUmz Jun 07 '20 at 08:19
  • Your code is susceptible to SQL Injections! – Lars Stegelitz Jun 07 '20 at 09:31
  • @LarsStegelitz could you be more descriptive please – DrCustUmz Jun 07 '20 at 09:41
  • You put raw POST values into your SQL queries. Please consider a search machine of your choice to learn about SQL Injections... – Lars Stegelitz Jun 07 '20 at 09:44
  • @DrCustUmz You can read more about SQL injections [here](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) for example. SQL injection is a very widely known way of attacking websites and their database. It's definitely something worth reading about. – askuri Jun 07 '20 at 09:45
  • There is another thing that might prevent your code from working. The foreach and rtrim statements are not necessary. You can just pass your array straight to CURLOPT_POSTFIELDS, see [https://stackoverflow.com/a/32112981/11836707](https://stackoverflow.com/a/32112981/11836707). – askuri Jun 07 '20 at 09:51
  • @LarsStegelitz you got me a little worried now, https://pastebin.com/WiS5mBq1 would that secure it? – DrCustUmz Jun 07 '20 at 09:58
  • @askuri - passing an array rather than a querystring does change the `Content-Type` header which is not always desirable. As an array this header will be set as `multipart/form-data` but as a querystring it will be `x-www-form-urlencoded` – Professor Abronsius Jun 07 '20 at 09:59
  • @DrCustUmz - the code you posted via Pastebin shares the same problem - you have potentially unsanitised user input from the POST array being directly embedded in the SQL statement. You really should use a `prepared statement` with bound variables – Professor Abronsius Jun 07 '20 at 10:01
  • @askuri removing the foreach and rtrim or even one or the other, does not allow my data to be posted to the database. – DrCustUmz Jun 07 '20 at 10:05
  • @RamRaider I dont see how I could do that, whats going on is that top box of code with the curl, is in a product you downloaded for a CMS (vBulletin) the installs.php is what is on my server, what it's doing is grabbing the installers userinfo and storing it to my DB so I know who has installed a product. – DrCustUmz Jun 07 '20 at 10:08

1 Answers1

2

Is there a way I can change the URL in my CURL code to point directly to that part of the installs.php page?

As for standard HTTP features: no, there is no explicit way of calling parts of a script.

Let's start from the beginning. What we would usually do in this situation is that we set the path in the URL to the file, that contains parts we want to execute. Then, it is up us to decide, how we design our program to know, which part should be executed. We can use POST parameters for that like you were trying. So far, so good.

Now, how do we divide our script, installs.php in your case, into pieces?

One good way is the one RamRaider already mentioned: use a POST parameter action and in installs.php, put code into a big switch. Example:

// installs.php
<?php
switch ($_POST['action']) {
  case 'myfirstaction':
    if (isset($_POST['username'])) {
      $vbulletin->db->query_write("...");
    }
    break;
  case 'myotheraction':
    // code here
    break;
}
?>
To call specific actions, just extend you $fields array:
<?php
// script that "can be executed from anywhere":
$fields['action'] = 'myfirstaction';
?>

I would say this is the cleanest way to do it in your situation. However, if installs.php is a larger script you are adjusting, this might be way too much work. In that case you may want to exit the script after running your code (thus, running only the code you want). You can simply write exit; and no further code will be executed. See: https://www.php.net/exit.

askuri
  • 185
  • 2
  • 7
  • the page as of yet is fairly simple, I will update the OP to include everything. Thank you for breaking it down for me though GREAT explanation. My only question to this would be if I were to use the switch, how would I navigate call that portion IE. mysite.com/installs.php?SomethingLikeThis – DrCustUmz Jun 07 '20 at 09:47
  • 1
    the url you use in the curl request can include a querystring, so if you had a url of `http://dirtrif.com/installs.php?action=install&name=bob` for instance you could use `switch( $_GET['action'] ){/* cases */}` instead of `switch( $_POST['action'] ){/* cases */}` – Professor Abronsius Jun 07 '20 at 09:50
  • I have added the full installs.php content to the OP, I"m not sure if this is the method that will solve this since the url i put there will never be designated as one thing. To break it down more, installs.php is on my server, the CURL code is something I give to you to install, when you install it, it gives me the information I requested. – DrCustUmz Jun 07 '20 at 09:54
  • please explain what `url i put there will never be designated as one thing` actually means. Also - are you saying that you send the `curl` code to customers and they put that on their server and run it? – Professor Abronsius Jun 07 '20 at 10:04
  • @RamRaider yes! exactly, then it stores the data to my database, A install tracker sort of thing – DrCustUmz Jun 07 '20 at 10:10