Author |
Message |
killing-hours
RavenNuke(tm) Development Team

Joined: Oct 01, 2010
Posts: 438
Location: Houston, Tx
|
Posted:
Mon Dec 13, 2010 3:46 pm |
|
Hey all-
New issue. I'm not very familiar with CSRF so I'm a bit lost here with this problem.
I am trying to load a particular form within my tracking module using colorbox. When i go to submit that form however, I get this...
Since I'm not including the header.php within the colorbox popup... i'm not carrying the csrf check along. Not real sure how to bridge this gap... help needed. Thanks. |
_________________ Money is the measurement of time - Me
"You can all go to hell…I’m going to Texas" -Davy Crockett |
|
|
 |
Palbin
Site Admin

Joined: Mar 30, 2006
Posts: 2583
Location: Pittsburgh, Pennsylvania
|
Posted:
Mon Dec 13, 2010 4:46 pm |
|
You need to include mainfile,php in your form. Then use the following function to create a hidden input with the token.
Code:
csrf_rn_token('input');
|
|
_________________ "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan. |
|
|
 |
Palbin

|
Posted:
Mon Dec 13, 2010 4:47 pm |
|
|
|
 |
killing-hours

|
Posted:
Mon Dec 13, 2010 4:49 pm |
|
Thank your for the code. I tried to add the mainfile to the form (require_once('mainfile.php')) but I didn't know about the code needed to cook it all.
Really appreciate you Palbin!
 |
|
|
|
 |
killing-hours

|
Posted:
Wed Dec 15, 2010 11:36 am |
|
Palbin-
I tried your solution... however, it didn't work. It was never producing a token.
After debugging this thing back a bit... I found that adding
Code:require_once('mainfile.php');
online();
|
is what finally got it to work. Do you happen to know right off hand what the "online();" function is? Just curious because I didn't find any results for it in the wiki and I'm not sure if it's going to be a security risk of some sort. Thanks!
edit**
I should also note that these forms are within the admin area of the module. The public "should" never see them. |
|
|
|
 |
Palbin

|
Posted:
Wed Dec 15, 2010 12:48 pm |
|
You should not need the online function to make it work. I will have to look at it. i will try and get back to you. |
|
|
|
 |
PHrEEkie
Subject Matter Expert

Joined: Feb 23, 2004
Posts: 358
|
Posted:
Wed Dec 15, 2010 2:02 pm |
|
The function online() only manages the nuke_session table, and nothing else. If you comment out online();, the token fails? Looking at this topic so far, it would seem there's actually something in mainfile that is getting the token delivered, or was the mainfile require always there? I haven't had to deal with the CSRF at all yet, but it was on my list. When playing with NST Groups once, I made one public group, logged in an alt, and attempted to self-join the group, at which point it started throwing the CRSF fails (well, actually I was getting a 500 error, and found the CSRF problem in my Cpanel error log). I just commented out the CSRF call, and it then worked. I needed to move on with what I was doing, so I never traced it back.
- Keith |
_________________ PHP - Breaking your legacy scripts one build at a time. |
|
|
 |
Palbin

|
Posted:
Wed Dec 15, 2010 2:34 pm |
|
On a typical form in the CMS the token is automatically added via output buffering. We have added ways to create your own token for javascript and other applications. This by itself unless the CSRF check function is manually added. Which it should be in the base code.
Since he is not loading an entire page he will need to manually add a token. Within mainfile the CSRF Magic script is included.
....
As I typed the above I just thought of something. For your forms just run them through admin.php via an $op. Meaning you would call them like this: www.yoursite.com/admin.php?op=xxxxx. This would be done by adding an op definition to case.php within the module admin directory and also maybe adding it to the switch statement in the admin index.php. |
|
|
|
 |
killing-hours

|
Posted:
Wed Dec 15, 2010 2:55 pm |
|
Phreekie-
Here's the best explanation I can give at this point. The way I'm using it is with modified pages within the Project Tracking module but with original code.
So lets pretend we are in the Project tracking module and within the admin area control panel... let's click on "Edit Task". That switches the op to "PJTaskEdit" (PJTaskEdit.php). and loads the page after a page refresh.
Now... the taskedit.php includes the header/footer, opens tables etc to view correctly. Since the header is being loaded... the online function fires and as you say... controls the sessions.
Now we want just the form itself showing in the colorbox iframe popup (no need for a header/footer) so we comment out the header/footer includes and should add the mainfile.php & csrf_rn_token('input'); function to produce a token, however, because we commented out the header... we don't fire off the online() function thus breaking the session. (i'm assuming this is why I couldn't get it to produce a token but not really sure)
If you want to try this... here are the closest steps I can give that will hopefully re-produce the error.
1. Activate the Project Tracking module.
2. Located the file "PJTaskList.php" within /modules/Project_Tracking/admin folder and around line 58 find
Code:echo "<td align='center' nowrap='nowrap'>[ <a href='".$admin_file.".php?op=PJTaskEdit&task_id=$task_id'>"._PJ_EDIT."</a>";
|
and add this just after the <a
3. locate the file "PJTaskEdit.php" in the same directory and comment out the include header/footer.
From this point... I would navigate via the admin panel on your site to the Project Tracking admin backend and in the admin panel pick "Task List". (you will need to create a project & associated task prior to this for it to work) When you get to the task list... your associated task should be in the list. When you click on "Edit" to the right... it should open the task edit form within the colorbox pop. Make some change to the task and then hit "Update Task".
The first run SHOULD produce the a csrf failure. (since we didn't include the mainfile, csrf_rn_token nor header)
Now go back to the PJTaskEdit.php and add the formentioned fix to the page and save it. Try to edit the task again and it "SHOULD" still produce the csrf failure.
Sorry for the long explanation.... but I know it's hard enough to try and debug a problem while you're staring at it... much less just getting a description from someone else and trying to figure out what they are doing.
--------------------------
Edit*** Sorry again Palbin... .was coming up with mine as you were with yours.
I agree with you that I should be running it through the admin file... but I thought I already was. (see previous code about add the colorbox class). Since the link that has the class with colorbox is going through the admin file... I figured that should have taken care of it... .but since i'm not loading the header... i'm never actually firing off the online() function thus breaking my session?? |
|
|
|
 |
Palbin

|
Posted:
Sat Dec 18, 2010 8:07 pm |
|
As I was developing a test case it came to me what your problem probably is. You need to echo the function call not just call it. Check my example below.
Code:
require 'mainfile.php';
$op = (!empty($_POST['op'])) ? $_POST['op'] : '';
switch($op) {
default:
display_form();
break;
case 'submit':
validate_data();
break;
}
function display_form() {
echo '<div>'
, '<form method="post" action="test_form.php">'
, '<fieldset style="padding: 5px;">'
, '<legend><span style="text-align: center; font-weight: bold;" class="option">CSRF Testing</span></legend>'
, '<dl><dt><label for="data">Enter a number:</label></dt>'
, '<dd><input type="text" id="data" name="some_number" title="Enter a number" size="30" maxlength="60" value="" /></dd></dl>'
, csrf_rn_token('input')
, '<input type="submit" name="op" value="submit">'
, '</fieldset>'
, '</form>'
, '</div>';
}
function validate_data() {
csrf_check();
if (!empty($_POST['some_number']) && is_numeric($_POST['some_number'])) {
echo '<span style="color: green;">The value you entered is numberic.</span>';
} else {
echo '<span style="color: red;">The value you entered is not numeric.</span>';
}
}
|
|
|
|
|
 |
killing-hours

|
Posted:
Thu Dec 23, 2010 11:11 pm |
|
Hmm... have another csrf issue but didn't want to start a new topic for it.
In this instance... I'm re-working the modules admin code and I've made a bit of progress... but I've hit another road block that I don't quite understand how to play nice with it yet.
In the original code...
Code:$puthome = '<a class="rn_csrf" href="'.$admin_file.'.php?op=home_module&mid='.$mid.'">' . _PUTINHOME . '</a>';
$change_status = '<a class="rn_csrf" href="'.$admin_file.'.php?op=module_status&mid='.$mid.'&active='.$act.'">'.$change.'</a>';
|
we notice that the link generated also generates the csrf token. The roadblock I'm hitting is that adding other classes to the links do not work. (i.e. if I add the class "colorbox"... it does not work)
The way this check seems to work is by creating the token on load and some how rewriting the link. I understand that this check needs to be in place so that we are sure the admin changes aren't made by unauthorized people... however, not sure how to get around this one nicely. Help needed. Thanks. |
|
|
|
 |
Palbin

|
Posted:
Thu Dec 23, 2010 11:30 pm |
|
The colorbox does not work or the token is not generated? |
|
|
|
 |
killing-hours

|
Posted:
Fri Dec 24, 2010 12:52 am |
|
Still debugging, but from what I can tell... if you were to add more than the "rn_csrf" class to a given link that is using it... it will break the csrf class code. (not producing a token)
to test... navigate to your 'admin/modules/modules.php' and around line 187 find the two aforementioned links and add into the class "colorbox"
I.e. (only really needs to work on $puthome)
Code: $puthome = '<a class="rn_csrf colorbox" href="'.$admin_file.'.php?op=home_module&mid='.$mid.'">' . _PUTINHOME . '</a>';
$change_status = '<a class="rn_csrf" href="'.$admin_file.'.php?op=module_status&mid='.$mid.'&active='.$act.'">'.$change.'</a>';
|
|
|
|
|
 |
nuken
RavenNuke(tm) Development Team

Joined: Mar 11, 2007
Posts: 2024
Location: North Carolina
|
Posted:
Fri Dec 24, 2010 7:16 am |
|
colorbox can also be used with the rel attribute by adding a few lines of js.
something like this may work
Code:
<script type="text/javascript">
$(document).ready(function(){
$("a[rel="colorbox"]").colorbox();
});
</script>
|
Edit: I tested it and it does not work. There is a way to use the rel though. |
_________________ Only registered users can see links on this board! Get registered or login! |
|
|
 |
killing-hours

|
Posted:
Fri Dec 24, 2010 9:33 am |
|
Even though that didn't work nuken, it gave me an idea to test and it seems this does work. (so far at least)
Solution:
Code:$("a.rn_csrf").hover(function() {
$(this).colorbox({opacity:0.80, width:"750", heigth:"400"});
},
function() {
$(this).removeClass("cboxelement");
});
|
Thanks for the nudge!
P.s. I hope to have something for y'all to play with here in the next week or so. (maybe after the new year) I think y'all will like this.
P.s.s. I was using JS (jquery) before to add the class on the fly... however, that was still not working. |
|
|
|
 |
Palbin

|
Posted:
Fri Dec 24, 2010 3:24 pm |
|
Ok I looked into the problem with not getting a token when adding classes. I seem to have fixed it except where jQuery is concerned. My updated code seems to work expect when jQuery starts adding its own classes automatically.
To fix the problem multiple classes open includes/csrf-magix.php and change lines 188-197 to the following:
Code:
$input = array(
'#(<form[^>]*method\s*=\s*["\']?post["\']?[^>]*>)#iu', // for forms re-write
// '#<a[^>]*\s*class=\s*\"rn_csrf\"\s*href\s*=\s*["\']([a-zA-Z0-9/;:=_-]*).html["\'][^>]*>#iu', // for ShortLinks re-written links to .html
'#(<a[^>]*\s*class=\s*["\'][^"\']*rn_csrf[^"\']*["\']\s*)href\s*=\s*["\']([a-zA-Z0-9/&;:=\?\._-]*)["\']([^>]*>)#iu' // for links that are not ShortLinks re-written
);
$output = array(
'$1<input type="hidden" name="' . $name . '" value="' . $tokens . '"' . $endslash . '>', // for forms re-write
// "<a class=\"rn_csrf\" href=\"$1.html?$name=$tokens\">", // for ShortLinks re-written links to .html
'$1href="$2&' . $name . '='. $tokens . '"$3' // for links that are not ShortLinks re-written
);
|
Note: that the class attribute MUST appear before the href attribute for the token to be added.
I would advise against Code:
$("a.rn_csrf").hover(function() {
$(this).colorbox({opacity:0.80, width:"750", heigth:"400"});
},
function() {
$(this).removeClass("cboxelement");
});
| because you are going to catch other links. If you are going to use jQuery on a link that needs CSRF protection I would just build the token onto the end of the link without using the output buffering. What I mean by this is that I would remove the rn_csrf class and then do something like the following.
Code:
$puthome = '<a href="' . $admin_file . '.php?op=home_module&mid=' . $mid . csrf_rn_token() . '">' . _PUTINHOME . '</a>';
|
|
|
|
|
 |
killing-hours

|
Posted:
Sat Dec 25, 2010 11:17 am |
|
Palbin-
If the jquery is added 'inline'... would that still catch other links? What I mean is this... the way i've structured this is to add the jquery to a variable then add it inline on in the modules.php while at the same time grabbing my style sheet.
The only links that "should" be on the screen when this jquery is used should be only those links.
Is this a poor choice of structure?
BTW... Merry Christmas! |
|
|
|
 |
Palbin

|
Posted:
Sat Dec 25, 2010 3:33 pm |
|
|
|
 |
killing-hours

|
Posted:
Mon Dec 27, 2010 6:57 pm |
|
What I mean is adding the jquery/ajax inline in the modules.php. Since that page will be hosting it's own "inline" jquery... it seems logical that it will only be in the browser when that particular page is loaded (i.e. the modules administration) Since the only links showing on the page at that time will be those particular links... I don't understand how it should be grabbing other links from around the site.
In any case... I've used your fix as it "should" really be incorporated into the next release of RN as well as it makes the code much easier and cleaner to understand in the jquery.
I've got two more issues to sort out (ajaxifying the put in home/ edit module) along with some code clean up and commenting.
Edit Module:
Put in home:
The modules table:
Note** In firefox... I've used the "blink" attribute to blink the line. (only supported by some browsers) I've also used jquery to change the text / background color so that it's more visible and gives the end user a more interactive feel to the process.
The data will be updated by interval which can be set by the end user in the jquery.
Comments, suggestions & advice always welcome.
P.s. I've also taken into account the user has JS disabled/ not supported. Have no fear.  |
|
|
|
 |
spasticdonkey
RavenNuke(tm) Development Team

Joined: Dec 02, 2006
Posts: 1693
Location: Texas, USA
|
Posted:
Tue Dec 28, 2010 9:45 am |
|
very nice look forward to this. |
|
|
|
 |
killing-hours

|
Posted:
Tue Dec 28, 2010 9:53 am |
|
So am I. The whole point behind this modified code is to keep the admin from waiting on page loads. I can't tell you how much it burned my buns to have to reload the page then scroll back down and find the modules I was wanting to change next. Also, for very active sites with multiple admins... their lists are updated in more or less "real time" so they can see when changes are made to the modules by other admins without having to reload to see.
I use this same sort of setup on my Project tracking module so that our clients can see in real time when their stuff is being worked on etc. So far it has worked really well.
All in all... I think it will give a more modern feel to the RN backend as well as speed up the admins time in managing modules.
P.s. Sorry if I'm not following dev protocol... I'm just seeing an improvement and jumping on the chance to make it happen. |
|
|
|
 |
nuken

|
Posted:
Tue Dec 28, 2010 10:39 am |
|
|
|
 |
killing-hours

|
Posted:
Tue Dec 28, 2010 2:54 pm |
|
Ok... trying my hardest not to deviate from my original topic... but just a quick update and question.
In order to solve my last two problems... I've had to update the colorbox script to the latest version (1.3.15) from the original that comes with RN (2.4.01) which was 1.2b. (the new version adds callbacks)
Will this turn out to be an issue as far as the development of RN as a whole?
I am building this on a fresh install of RN (2.4.01) and so far I haven't had any issues as far as it playing nice... however, I'm concerned that updating the script will break the end users colorbox that they may already have in place etc. on existing sites or that there are things in development I may not know about that uses the version of colorbox supplied with RN. (although... I think the updated colorbox only extends what's previously been put in place)
Not really sure what I should be asking in this instance or what I should be concerned with in general. Palbin/Raven or any of the devs... should I be worried about updating this script and it's relation to RN? Thanks guys! |
|
|
|
 |
Palbin

|
Posted:
Tue Dec 28, 2010 3:48 pm |
|
Typically we would like to include the latest versions of scripts when we do a release. Of course if that would require major changes we would not do so on a maintenance release. So basically do not worry about using the latest version. |
|
|
|
 |
killing-hours

|
Posted:
Tue Dec 28, 2010 3:54 pm |
|
Thank you Palbin!! Exactly what I was hoping for.
I should be done with this here in the next couple of days... I'll privately release this to site owners & the devs so that y'all can look my work over and fix the code that you believe should be better. I will let y'all decide the direction it should go from there. Thanks for all your help guys!!! |
|
|
|
 |
|