3

Scenario:

  1. User is posting an ajax request to Joomla site (via com_ajax).

  2. Inside the called method, I want to retrieve the entire html output of a known Joomla submenu (let's say /contact). The joomla submenu is only accessible to a different user than the one currently logged in.

  3. The method then returns the html back to the user.

OK, I can do #1 and #3, no problem. How can I do #2 ?

Things I've explored:

  • Posting via cURL - I could not find a way to maintain session variables and surpass Joomla's CSRF protection mechanism.
  • Using ob_start, then using the redirect method of JApplication. This sends only the redirect headers.
  • Using JApplication->login to impersonate a user. This solves just a part of the problem. I am only mentioning it because if someone posts an answer via cURL, it'd have to tackle the authentication problem too.

"Solutions" that will not work (to save you some time):

  • require / include X file: No, because I want an entire url (which may contain multiple components/modules)
  • Have the user directly call the url (in this case /contact): No, for various business logic rules. Let's say for simplicity that the returned html output is "enriched" before being sent back.
  • 1
    +1 for using com_ajax, doesn't often happen :) – Lodder Jul 27 '16 at 14:10
1

I had partial success with the following, thanks to this answer mainly:

<?php
function retrieveURL($relativeURL){
    $uname = "user";    //this is the privileged user to the relative url we want
    $upswd = "pass";
    $domain = $_SERVER['HTTP_HOST'];
    $prefix = $_SERVER['HTTPS'] ? 'https://' : 'http://';

    $url_get_key = $prefix.$domain."index.php?option=com_users"; 

    //GET return & key
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_get_key );
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE );

    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt');   //as far as i understand, this stores a *new* session to a cookie file
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
    curl_setopt($ch, CURLOPT_HEADER, 0 );

    $results = curl_exec($ch);

    preg_match_all("(<input type=\"hidden\" name=\"return\" value=\"(.*)\" />)siU", $results, $matches1);   //Should not be needed if username and password are correct
    preg_match_all("(<input type=\"hidden\" name=\"(.*)\" value=\"1\" />(.*)</fieldset>)iU", $results, $matches2); //Same as above

    // POST
    $url_post = $prefix.$domain."index.php?option=com_users&task=user.login";
    $postdata = "username=".urlencode($uname)."&password=".urlencode($upswd)."&return=".urlencode($matches1[1][0])."&".urlencode($matches2[1][0])."=1";
    curl_setopt($ch, CURLOPT_URL, $url_post);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
    $results1 = curl_exec($ch);

    $url_data = $prefix.$domain.$relativeURL;   
    curl_setopt($ch, CURLOPT_URL, $url_data);   //Now we can retrieve the proper url

    $results2 = curl_exec($ch);
    $error = curl_error($ch);
    $errno = curl_errno($ch);

    curl_close($ch);
    return $results2;   //could probably use a bit more error checking
}
?>

This retrieves the html of the output page with the credentials of the privileged user. Now, if I could somehow keep the session variables of the previous user, or inject them to the new session, all would be perfect. From what I understand though, what I am trying to do may be called "Session poisoining" :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.