PDA

View Full Version : YUI and vB SESSIONURL question


JamesAB
03-28-2009, 04:02 AM
I'm trying to use the YUI uploader with a vBulletin script, but I'm having trouble with SESSIONURL.

This works for me without SESSIONURL:
function upload() {
if (fileID != null) {
uploader.upload(fileID, "http://tforum.mydomain.com/uploadzip.php",
"POST",
{"do":"doupload",
"albumid":jababumid,
"jabuniquezip":jabuniquezip,
"securitytoken":SECURITYTOKEN},
"upload");
}
}

However, I think I should be using SESSIONURL with securitytoken. :confused:

When I change the line to:
SESSIONURL + "securitytoken":SECURITYTOKEN},

Now I get a javascript error.

Is SESSIONURL supposed to be empty or NULL sometimes?

Any ideas or advice?

Thanks,
James

TigerC10
03-28-2009, 05:15 AM
SESSIONURL is supposed to be empty all the time. The only time it gets used is when vBulletin has a problem with storing the Session Hash in the cookies. Instead of using SESSIONURL, try pulling the SessionHash from the cookies.


$vbulletin->input->clean_array_gpc('c', array(
//COOKIE_PREFIX.'userid' => TYPE_UINT,
//COOKIE_PREFIX.'password' => TYPE_STR,
//COOKIE_PREFIX.'styleid' => TYPE_UINT,
//COOKIE_PREFIX.'lastactivity' => TYPE_UINT,
//COOKIE_PREFIX.'lastvisit' => TYPE_UINT,
//COOKIE_PREFIX.'cpsession' => TYPE_STR,
COOKIE_PREFIX.'sessionhash' => TYPE_STR
));

$sessionhash = $vbulletin->GPC[COOKIE_PREFIX.'sessionhash'];


Then you can use the $sessionhash variable in place of SESSIONURL, or define SESSIONURL to be $sessionhash, you know - whatever.

JamesAB
03-29-2009, 01:41 AM
Okay. So from a security point of view, do I need SESSIONURL when passing an upload post from YUI to my PHP script?

There doesn't seem to be any official vBulletin/YUI guides yet. I've only found the stock reply indicating that connections should be called with this format.

YAHOO.util.Connect.asyncRequest('POST', scriptpath + '?do=ajax', {
success: this.handle_ajax_response,
failure: this.handle_ajax_error,
timeout: vB_Default_Timeout,
scope: this
}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&foo=' + foo);

This works for me using SESSIONURL as part of the request, but as I mentioned above it isn't working with the YUI uploader example I posted.

Bottom line, do I need to find a way to incorporate SESSIONURL (or $sessionid as TigerC10 suggested) with YUI's uploader in order to fully take advantage of vBulletin's CSRF protection scheme?

Or will using SECURITYTOKEN alone suffice?

Thanks,
James

TigerC10
03-29-2009, 01:49 AM
I typoed that, $sessionid was supposed to be $sessionhash, I fixed my previous post. See my code sample for how to get at it.

I believe that the security token is matched up to the value in the database based on the session, so you do need it.

JamesAB
03-29-2009, 03:47 AM
Thanks for your help TigerC10.

I'm still trying to understand why they are recommending

SESSIONURL + 'securitytoken=' + SECURITYTOKEN

versus simply

'securitytoken=' + SECURITYTOKEN

if SESSIONURL is normally empty. :confused:

As I found out above with the YUI uploader

"securitytoken":SECURITYTOKEN

works (for me) with CSRF enabled , but

SESSIONURL + "securitytoken":SECURITYTOKEN
gives me a javascript error.

Maybe I'll have to ask this same question in the CSRF thread in the articles section...

Thanks,
James

Dismounted
03-29-2009, 03:52 AM
The security token is not stored anywhere - it is dynamically generated from other variables (e.g. time, user ID, etc.). (It is only needed on POST forms/requests.)

The session hash (SESSIONURL) is needed when the user does not have cookies enabled - it is empty otherwise.

JamesAB
03-29-2009, 05:20 AM
I'm far from a javascript expert (I'm a PHP guy) and I've been trying to give myself a crash couse in Yahoo/YUI this week. That's why I've been asking for help and assuming it was my mistake, but I'm finally coming to the conclusion that this is probably a YUI quirk.

I haven't found any documentaion on this yet, but it appears that the first half of the POST vars on this uploader have to be string literals. You CANNOT use any varibles here...or at least I can't get the simpliest example to work.

If it's true, this would explain why I can't get any version to work with the SESSIONURL variable added either.

// THIS WORKS
uploader.upload(fileID, "http://tforum.mydomain.com/uploadzip.php",
"POST",
{"do":"doupload",
"albumid":jababumid,
"jabuniquezip":jabuniquezip,
"securitytoken":SECURITYTOKEN},
"upload");

as opposed to

// THIS DOES NOT WORK
var vbsessionurlsecuritytoken = "securitytoken";
uploader.upload(fileID, "http://tforum.mydomain.com/uploadzip.php",
"POST",
{"do":"doupload",
"albumid":jababumid,
"jabuniquezip":jabuniquezip,
vbsessionurlsecuritytoken:SECURITYTOKEN},
"upload");

With the second version, when a variable is used instead of the actual string, I get a CSRF error.

Am I missing something?
Or should I give up on this?

Thanks,
James

TigerC10
03-29-2009, 05:44 AM
Just for giggles, try:


var vbsessionurlsecuritytoken = "securitytoken";
uploader.upload(fileID, "http://tforum.mydomain.com/uploadzip.php",
"POST",
{"do":"doupload",
"albumid":jababumid,
"jabuniquezip":jabuniquezip,
vbsessionurlsecuritytoken.valueOf():SECURITYTOKEN} ,
"upload");

The .valueOf() method will return the primitive value of the string, which might be substitutable for the literal value.




The security token is not stored anywhere - it is dynamically generated from other variables (e.g. time, user ID, etc.). (It is only needed on POST forms/requests.)

The session hash (SESSIONURL) is needed when the user does not have cookies enabled - it is empty otherwise.

Really? That's good to know, but then why does every submission form append the session to the post in a hidden type?

JamesAB
03-29-2009, 04:41 PM
Thanks for the suggestion TigerC10.

I just tried using vbsessionurlsecuritytoken.valueOf() instead and the javascript would not even run properly.

I'm going to ask about this over at the Yahoo's YUI group too. It just seems odd or at least inconsistent that the POST vars format evaluates one way (as expected) with YAHOO.util.Connect.asyncRequest, but they seem to be treated differently with the YUI uploader.

In the meantime I'd like to evaluate the situation of not using SESSIONURL as part of the uploader's POST vars and just using "securitytoken":SECURITYTOKEN which works for me.

How often would this not work? Or exactly which users would be effected?
Is it only users that don't have cookies enabled?

Thanks,
James

Dismounted
03-30-2009, 04:22 AM
Really? That's good to know, but then why does every submission form append the session to the post in a hidden type?
I don't understand what you're trying to say?

JamesAB
04-02-2009, 09:52 PM
I've been doing a bit more digging and it seems that the POST vars have to be in the form of an object. They can be inline as I had them, or declared earlier. Unfortunately, you can't use a standard string with all the POST information combined here.

My problem is still that I can't use SESSIONURL + 'securitytoken' as the name of variable, since I'm ultimately trying to POST:

SESSIONURL + 'securitytoken=' + SECURITYTOKEN

The following code is sending vbsessionurlsecuritytoken as the name of the POST variable, not the value of vbsessionurlsecuritytoken.

// THIS DOES NOT WORK
var vbsessionurlsecuritytoken = "securitytoken";
uploader.upload(fileID, "http://tforum.mydomain.com/uploadzip.php",
"POST",
{"do":"doupload",
"albumid":jababumid,
"jabuniquezip":jabuniquezip,
vbsessionurlsecuritytoken:SECURITYTOKEN},
"upload");

Is it even possible in javascript to create an object where the name of the variable is dynamic?

Thanks,
James

Dismounted
04-03-2009, 05:05 AM
Try:
uploader.upload(fileID, 'http://tforum.mydomain.com/uploadzip.php', 'POST', {
sessionurl: SESSIONURL
do: 'doupload',
albumid: jababumid,
jabuniquezip: jabuniquezip,
securitytoken: SECURITYTOKEN
}, 'upload'
);

JamesAB
04-06-2009, 06:48 PM
Thanks Dismounted. That appears to be working so far.

Now I'm also looking at using the YUI uploader to allow selecting multiple files (with upload progress bars) for album uploads. In some ways this will be simpler than the original project I had for uploading & adding photos from a .ZIP file.

Looking at the hidden form fields in the album_picture_upload template:

<input type="hidden" name="s" value="$session[sessionhash]" />
<input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]" />
<input type="hidden" name="do" value="uploadpictures" />
<input type="hidden" name="albumid" value="$albuminfo[albumid]" />
<input type="hidden" name="MAX_FILE_SIZE" value="$inimaxattach" />

It looks like I'll just need to add these to the YUI uploader's POST variables object and set the YUI uploader's URL to use the equivalent of album.php?do=uploadpictures&amp;albumid=$albuminfo[albumid]

Am I correct that these two do the same thing?
//In the template
<input type="hidden" name="s" value="$session[sessionhash]" />
//In the javascript uploader POST object
sessionurl: SESSIONURL


This just leaves the javascript not knowing the albumid or MAX_FILE_SIZE, I believe.

Is the best way to pass these variables from PHP to javascript, the way I have been doing it so far?

<script type="text/javascript">var jababumid = <?php echo $albuminfo['albumid']; ?>;</script>

<script type="text/javascript">var jabinimaxattach = <?php echo $inimaxattach; ?>;</script>

Thanks for everyone's help,
James

Dismounted
04-07-2009, 08:03 AM
Is the best way to pass these variables from PHP to javascript, the way I have been doing it so far?
It's pretty much the only way to do it. :p You also know to not depend on MAX_FILE_SIZE, right?