The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. November 21, 2008, 03:35:05 PM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: Vsloathe's Asynchronous Remote Post Class  (Read 644 times)
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Online Online

Posts: 596



View Profile
« on: July 18, 2008, 05:29:21 AM »

Thanks to The Darkness for his javascript autoclicker and to Perkiset for both inspiration and his ajaxRequestor javascript. Perk's ajaxRequestor javascript is required for this to work, and it's available here: http://www.perkiset.org/forum/javascript_ajax/ajax_requestor_class-t38.0.html Download the latest version, and put it in a file called "class.ajaxRequestor.js" located in a directory called "js". Or you can modify where the script is linked to in the below code if you'd prefer to put it somewhere else or call it something else.

What does this code do?
For how complicated the process is, what it does is actually pretty simple. I wanted a way to asynchronously POST to a remote domain, and that's what it does.

What good is that to me?
You might want to communicate something to a server on a remote domain, but don't need a response. So, rather than the hacky workarounds out there for getting XMLHTTPRequest to work cross-domain, you might choose to just fire off an invisible post.

What are the limitations
Because of the "same origin policy" and other such silliness, you can't receive the server's response to your post, but in a lot of cases this is ok. There are hacks and workarounds to circumvent this restriction, but they're way outside the scope of a compact, easy-to-use code snippet. Also, since the post is firing from a page you own, the remote server will see whatever script you are instantiating this class from as the referer. That's not a terribly big deal, and the vast majority of services out there will accept the post regardless, provided it contains the right params.

So there you have it. If you'd like to "borrow" your surfer's IP in order to post to a remote domain, have at it!

Usage:
Code:
<?php
/*
Optionally, you can specify that RPX should send a GET request to the page (or another page) before the POST, or that it should be rendered inside a hidden div (not terribly important as the iframe that it creates is 1x1 anyway, but you never can be too paranoid).
*/
$RPX = new RPX('http://someremotedomain.com/postpage.html');
$RPX->addPostVar('foo','bar');
$RPX->dispatchPost();
?>

Class:
Code:
<?php
class RPX{

var $postURL;
var $getURL;
var $isHidden 0;
var $doGetFirst 0;
var $arrPostVars = array();

function RPX($postURL$getURL ''){
if(isset($_POST['RPXObj'])){
$RPXObj stripslashes($_POST['RPXObj']);
$RPX unserialize($RPXObj);
$RPX->printHTML();
exit;
}else{
$this->postURL $postURL;
$this->getURL $getURL;
}
}
function setHidden($hide 1){
$this->isHidden $hide;
}
function setDoGet($doGet 1){
$this->doGetFirst $doGet;
}
function addPostVar($name$value){
$this->arrPostVars[$name] = $value;
}
function printHTML(){
$HTML $this->buildHTML();
echo($HTML);
}
function buildHTML(){
$HTML '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'."\n".
'<html lang="en-US">'."\n".
'<body>'."\n";
if($this->isHidden)$HTML .= '<div style="display:none;" >';
if($this->doGetFirst)$HTML .= '<iframe src="'.$this->getURL.'" style="height:0px;width:0px;" ></iframe>'."\n";
$HTML .= '<form action="'.$this->postURL.'" method="POST" name="theForm" id="theForm" >'."\n";
$submitButton 0;
foreach($this->arrPostVars as $name => $value){
if($name == "submit"){
$submitButton 1;
$HTML .= '<input type="submit" name="_'.$name.'" id="_'.$name.'" value="'.$value.'" onclick="document.getElementById(\'theForm\').submit();" />'."\n";
}else{
$HTML .= '<input type="hidden" name="'.$name.'" id="'.$name.'" value="'.$value.'" />'."\n";
}
}
if(!$submitButton){
$HTML .= '<input type="submit" name="_submit" id="_submit" value="" onclick="document.getElementById(\'theForm\').submit();" />'."\n";
}
$HTML .= "</form>\n";
if($this->isHidden)$HTML .= '</div>';
$HTML .= "</body>\n</html>\n";
$HTML .= '<script type="text/javascript">
isIE = ( ( document.all ) && ( document.getElementById ) );
if( isIE )
   document.getElementById("_submit").click();
else
   document.getElementById("_submit").onclick();
</script>'
;
return $HTML;
}
function dispatchPost(){
$RPXObj serialize($this);
echo('<script src="/js/class.ajaxRequestor.js" type="text/javascript"></script>'.
'<script type="text/javascript">'.
'ajax1 = new ajaxRequestor();'.
"ajax1.url = '".$_SERVER['PHP_SELF']."';".
"ajax1.postParam('RPXObj', '$RPXObj');".
'ajax1.onSuccess = handleAjax;'.
'ajax1.execute();'.
'function handleAjax(sender){
var ifrm = \'<iframe src="" name="postIframe" id="postIframe" style="height:1px;width:1px;"></iframe>\';
document.body.innerHTML += ifrm;
var ifram = document.getElementById(\'postIframe\');
            ifram = (ifram.contentWindow) ? ifram.contentWindow : (ifram.contentDocument.document) ? ifram.contentDocument.document : ifram.contentDocument;
            ifram.document.open();
            ifram.document.write(sender.lastResponse);
            ifram.document.close();
}'
.
'</script>');
}

}
?>


TODO:
Patch some holes and do better input validation - as it stands a user could potentially send a malicious packet to the script (if he knew what was going on and how the object looked) in order to inject a malformed RPXObject.
« Last Edit: July 18, 2008, 05:32:20 AM by vsloathe » Logged

jammaster82
Expert
****
Offline Offline

Posts: 293

bloody hacker


View Profile WWW
« Reply #1 on: July 18, 2008, 06:48:06 AM »

NICE!!!!
Logged

Of course Big Brother exists, he is the embodiment of the party..... Does he exist in the same way I exist?....... You, do not exist.
KaptainKrayola
Keeper of Pie
Global Moderator
Lifer
*****
Offline Offline

Posts: 772



View Profile WWW
« Reply #2 on: July 18, 2008, 07:38:29 AM »

Tasty treat there Vsloathe.   Applause 
Oh, the possibilities.  Grin
Logged

We can't stop here, this is bat country.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5142


:sniffle: Humor was so much easier before.


View Profile
« Reply #3 on: July 18, 2008, 03:34:43 PM »

ROFLMAO That may well be the most innocently described chunk of potential evil I've seen in a decade. Well done mate!

I like how you wrap the requestor in an iframe to defeat the cross-domain restrictions ... very nicely done. As you mention, if your intention is to fire-and-forget this is the perfect way to do it.

Thanks VS!
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3384


View Profile
« Reply #4 on: July 18, 2008, 04:01:22 PM »

now the holy grail of course would be POST and able to read the return...
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5142


:sniffle: Humor was so much easier before.


View Profile
« Reply #5 on: July 18, 2008, 04:08:53 PM »

http://www.perkiset.org/forum/ajax/great_article_on_using_iframes_for_ajaxlike_client_server_action-t190.0.html

There's a way, and I think it lies somewhere in there.
Logged

If I can't be Mr. Root then I don't want to play.
taky
n00b
*
Offline Offline

Posts: 8


View Profile
« Reply #6 on: July 18, 2008, 04:27:03 PM »

i have not tried this but maybe you can bundle it as software, vsloathe: saving you money on ips one block at a time.

thanks.

oh and i agree if we can get post responses you just about nulled my hosting bill. 
« Last Edit: July 18, 2008, 04:28:57 PM by taky » Logged
taky
n00b
*
Offline Offline

Posts: 8


View Profile
« Reply #7 on: July 18, 2008, 04:29:41 PM »

this page is saved instantly to my desktop, wshh!
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5142


:sniffle: Humor was so much easier before.


View Profile
« Reply #8 on: July 18, 2008, 04:30:12 PM »

VS watch out - you've intrigued Taky and I'm not sure that's a good thing Wink
Logged

If I can't be Mr. Root then I don't want to play.
dimitry12
Rookie
**
Offline Offline

Posts: 26



View Profile
« Reply #9 on: July 19, 2008, 01:50:35 PM »

just curious, why don't just

Code:

new RPX;
RPX->addVars;
PRX->showPost;


with RPX::showPost being like

Code:

{
 printOuterIframe(printForm().printAutoClick());
}


why that ajax, self-call?
Logged
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Online Online

Posts: 596



View Profile
« Reply #10 on: July 19, 2008, 02:07:43 PM »

you're correct, it could just be done like that. I was looking for the level of flexibility that is hard to get without using async. calls though. Ultimately, I want to incorporate a hack I developed in order to make the response readable. It will be easier for me to do that now.
Logged

dimitry12
Rookie
**
Offline Offline

Posts: 26



View Profile
« Reply #11 on: July 19, 2008, 02:14:48 PM »

what do you mean by "response readable"?

btw, with "ajax" it's not in the source - so more secure, though the call is visible and can be manipulated

moreover. with PHP_SELF you can't include any other content in that script or you should check for POST[RPX] before outputting it before calling 'new RPX' (or it will output into iframe too)

still can't see the reason for complexity  Smiley

that all looks like closure and closures hurt my brain and look like "fuck yourself" - literally

why don't use just two separate objects: one for showing the ajax with form. other - for generating the form and use serialized array to transmit data
« Last Edit: July 19, 2008, 02:27:50 PM by dimitry12 » Logged
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Online Online

Posts: 596



View Profile
« Reply #12 on: July 23, 2008, 05:09:39 PM »


Indeed, that is one possibility.

The hindrance present with the particular method outlined in that article is that you must rely on weak input validation on the part of the remote server if it's owned by someone else. E.g. you need to inject some javascript that calls home with the response. Along a similar line, you can use HTML fragments, as iframes, even ones not from the same origin, have the ability to read and write to one another's location attribute.
Logged

Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!