Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > Programming Articles
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools
Implementing CSRF Protection in modifications
Marco van Herwaarden
Join Date: Jul 2004
Posts: 25,415

 

Show Printable Version Email this Page Subscription
Marco van Herwaarden Marco van Herwaarden is offline 04-23-2008, 10:00 PM

With the new version released today for vBulletin 3.6.10 and 3.7.0 RC4, a new protection against Cross Site Request Forgery (CSRF) has been introduced. This new protection might influence the coding in modifications.

Scott MacVicar took the time to compile a short explanation on this new protection for the coders on vBulletin.org:

Changes for CSRF protection with third party modifications

Cross Site Request Forgery (CSRF) involves taking advantage of the stateless nature of HTTP, there are no ways to ensure the exact origin of a request, its also not possible to detect what was actually initiated by a user and what was forced by a third party script. A token was added to the latest version of each of the vBulletin products, with the release of 3.6.10 and 3.7.0 RC4 it is no longer possible to submit a POST request directly without passing in the known token.

The addition of a security token for each POST request removes the ability for a remote page to force a user to submit an action. At the moment this protection will only apply to vBulletin files and third party files will need to opt into this protection and add the appropriate hidden field. This was done to preserve backwards compatibility.

Adding Protection to your own files

To opt your entire file into CSRF protection the following should be added to the top of the file under the define for THIS_SCRIPT.

PHP Code:
define('CSRF_PROTECTION'true); 
With this change all POST requests to this file will check for the presence of the securitytoken field and compare it to the value for the user, if its wrong an error message will be shown and execution with halt.

If this value is set to false then all CSRF protection is removed for the file, this is appropriate for something that intentionally accepts remote POST requests.

You should always add this to your file, even if you don't think the script is ever going to receive POST requests.

An absence of this defined constant within your files will result in the old style referrer checking being performed.

Template Changes

The following should be added to all of the forms which POST back to vBulletin or a vBulletin script. This will automatically be filled out with a 40 character hash that is unique to the user.

Code:
<input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]" />
Again it is worthwhile adding this to your templates even if it is currently not using the CSRF protection.

Exempting Certain Actions

It may be appropriate to exempt a particular action from the CSRF protection, in this case you can add the following to the file.

PHP Code:
define('CSRF_SKIP_LIST''action_one,action_two'); 
The above example would exempt both example.php?do=action_one and example.php?do=action_two from the CSRF protection, if the CSRF_SKIP_LIST constant is defined with no value then it will exempt the default action.

If the skip list needs to be changed at runtime is it available within the registry object, using the init_startup hook the following code would be used to exempt 'example.php?do=action_three'.

PHP Code:
if (THIS_SCRIPT == 'example')
{
        
$vbulletin->csrf_skip_list[] = 'action_three';

Reply With Quote
  #152  
Old 03-16-2009, 03:49 AM
Lynne's Avatar
Lynne Lynne is offline
 
Join Date: Sep 2004
Location: California/Idaho
Posts: 41,180
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

That query will most likely not catch modification templates or plugins where they don't have the securitytoken nor will it catch if it is a javascript problem. You can try disabling your modifications and seeing if the error goes away.
Reply With Quote
  #153  
Old 03-17-2009, 05:37 PM
Big-K Big-K is offline
 
Join Date: Feb 2005
Posts: 139
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Hello,

I'm trying to implement an add-on (ZP Poll) that shows vb polls in a non-vb page (joomla). Everything works well until users try to vote , then they get the security token issue. This hack is not resident in vbulletin and the only line with a form is
Code:
<form action=\"" . $directory . "/poll.php?do=pollvote&amp;pollid=\"" . $pollid . "\" method=\"post\">"
Any ideas on what I can do please?
Reply With Quote
  #154  
Old 03-17-2009, 05:49 PM
Lynne's Avatar
Lynne Lynne is offline
 
Join Date: Sep 2004
Location: California/Idaho
Posts: 41,180
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

You should ask the author of that modification for help adding the securitytoken.
Reply With Quote
  #155  
Old 03-17-2009, 07:03 PM
Big-K Big-K is offline
 
Join Date: Feb 2005
Posts: 139
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Hi Lynne,

I've been trying to get hold of the developer for days. I was hoping there is a generic way to add tokens to such non-vb pages. I'm attaching the script so you can advise on where I could add the token ?
Attached Files
File Type: php mod_zppollx.php (6.7 KB, 7 views)
Reply With Quote
  #156  
Old 03-17-2009, 07:11 PM
Lynne's Avatar
Lynne Lynne is offline
 
Join Date: Sep 2004
Location: California/Idaho
Posts: 41,180
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I'm no CSRF expert at all. I was able to just add the line to all my custom mods and everything worked perfectly. You can try adding the securitytoken right after the form line you posted above and see if that works.
Reply With Quote
  #157  
Old 05-09-2009, 01:06 PM
ndL ndL is offline
 
Join Date: Oct 2007
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

i have problem with a theme header ( i think so ) quick search (java one) doesnt work with this theme:

where to add special lines to make it work? here is the script

Code:
<!-- designed by hanafi@enthropia.com/napy8gen@yahoo.co.uk for forumtemplates.com -->

<a name="top"></a>
<table width="80%" border="0" align="center" cellpadding="0" cellspacing="0" class="wrapper" style="height:100%;">
  <tr>
    <td class="headerwrap"><table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td valign="top"><table width="100%" border="0" cellpadding="0" cellspacing="0" class="headerwrap2">
          <tr>
            <td><a href="$vboptions[forumhome].php$session[sessionurl_q]">&nbsp;&nbsp;&nbsp;<img src="images/lily/lily_logo.gif" alt="$vboptions[bbtitle]" width="285" height="140" border="0" id="lily_logo" /></a></td>
          </tr>
          <tr>
            <td class="navwrap">
			
<!-- nav buttons bar -->
    <table id="navstyle" cellpadding="$stylevar[cellpadding]" cellspacing="0" border="0" width="100%" align="center" style="border-top-width:0px">
    <tr align="center">
        <if condition="$show['member']">
            <td><a href="usercp.php$session[sessionurl_q]">$vbphrase[user_cp]</a></td>
        </if>
        <if condition="$show['registerbutton']">
            <td><a href="register.php$session[sessionurl_q]" rel="nofollow">$vbphrase[register]</a></td>
        </if>
        $template_hook[navbar_buttons_left]
        <td><a href="faq.php$session[sessionurl_q]" accesskey="5">$vbphrase[faq]</a></td>
        <td><a href="memberlist.php$session[sessionurl_q]">$vbphrase[members_list]</a></td>
        <td><a href="calendar.php$session[sessionurl_q]">$vbphrase[calendar]</a></td>
        <if condition="$show['popups']">       
            <if condition="$show['searchbuttons']">
                <if condition="$show['member']">
                <td><a href="search.php?$session[sessionurl]do=getnew" accesskey="2">$vbphrase[new_posts_nav]</a></td>
                <else />
                <td><a href="search.php?$session[sessionurl]do=getdaily" accesskey="2">$vbphrase[todays_posts]</a></td>
                </if>
                <td id="navbar_search" ><a href="search.php$session[sessionurl_q]" accesskey="4" rel="nofollow">$vbphrase[search]</a>

 <if condition="$show['quicksearch']">

<script type="text/javascript"> vbmenu_register("navbar_search"); </script></if></td>
            </if>
            <if condition="$show['member']">
                <td id="usercptools" ><a href="$show[nojs_link]#usercptools">$vbphrase[quick_links]</a> <script type="text/javascript"> vbmenu_register("usercptools"); </script></td>       
            </if>
        <else />       
            <if condition="$show['searchbuttons']">
                <td><a href="search.php$session[sessionurl_q]" accesskey="4">$vbphrase[search]</a></td>
                <if condition="$show['member']">
                <td><a href="search.php?$session[sessionurl]do=getnew" accesskey="2">$vbphrase[new_posts_nav]</a></td>
                <else />
                <td><a href="search.php?$session[sessionurl]do=getdaily" accesskey="2">$vbphrase[todays_posts]</a></td>
                </if>
            </if>
            <td><a href="forumdisplay.php?$session[sessionurl]do=markread" rel="nofollow">$vbphrase[mark_forums_read]</a></td>
            <if condition="$show['member']">           
                <td><a href="#" onclick="window.open('misc.php?$session[sessionurl]do=buddylist&amp;focus=1','buddylist','statusbar=no,menubar=no,toolbar=no,scrollbars=yes,resizable=yes,width=250,height=300'); return false;">$vbphrase[open_buddy_list]</a></td>           
            </if>           
        </if>
        $template_hook[navbar_buttons_right]
        <if condition="$show['member']">
            <td><a href="login.php?$session[sessionurl]do=logout&amp;logouthash=$bbuserinfo[logouthash]" onclick="return log_out('$vbphrase[sure_you_want_to_log_out]')">$vbphrase[log_out]</a></td>
        </if>
    </tr>
    </table>

<!-- / nav buttons bar -->
			
			
			</td>
          </tr>
        </table></td>
        <td class="headerR">&nbsp;</td>
      </tr>
    </table></td>
  </tr>
  
  <tr>
    <td valign="top" class="cwrap">
<!-- /end long header part -->

<!-- content table -->
$spacer_open
<br/>
<div align="center">@vbbanners@</div>
$_phpinclude_output
Reply With Quote
  #158  
Old 05-09-2009, 02:58 PM
Lynne's Avatar
Lynne Lynne is offline
 
Join Date: Sep 2004
Location: California/Idaho
Posts: 41,180
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by ndL View Post
i have problem with a theme header ( i think so ) quick search (java one) doesnt work with this theme:

where to add special lines to make it work? here is the script
If you think it's a problem with a particular mod, go read the mod thread and see if anyone posted the fix in there. There was also a discussion in this thread about fixing javascript (not java, that is very different) problems. Did you read the thread at all?
Reply With Quote
  #159  
Old 05-09-2009, 08:40 PM
mokujin's Avatar
mokujin mokujin is offline
 
Join Date: Oct 2005
Location: Czech
Posts: 345
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Hi Lynne, do you know how to make the Default var?
Thank you
Reply With Quote
  #160  
Old 05-10-2009, 02:43 AM
Lynne's Avatar
Lynne Lynne is offline
 
Join Date: Sep 2004
Location: California/Idaho
Posts: 41,180
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by mokujin View Post
Hi Lynne, do you know how to make the Default var?
Thank you
I don't understand what you mean, sorry.
Reply With Quote
  #161  
Old 05-10-2009, 04:37 PM
mokujin's Avatar
mokujin mokujin is offline
 
Join Date: Oct 2005
Location: Czech
Posts: 345
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Lynne View Post
I don't understand what you mean, sorry.
Hi Lynne,
I mean how to make the AJAX call a script without click a button (or a link) when a user just loaded the page.
For example: I have Installed AJAX Advanced Forum Statistic.
I browse the index page, that Mod loads the Statistics using AJAX for the default.

I hope you understand what I mean.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 09:19 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.04800 seconds
  • Memory Usage 2,342KB
  • Queries Executed 26 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (3)bbcode_code
  • (3)bbcode_php
  • (3)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (4)pagenav_pagelink
  • (1)pagenav_pagelinkrel
  • (11)post_thanks_box
  • (1)post_thanks_box_bit
  • (11)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (1)post_thanks_postbit
  • (11)post_thanks_postbit_info
  • (10)postbit
  • (1)postbit_attachment
  • (11)postbit_onlinestatus
  • (11)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • fetch_musername
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • post_thanks_function_fetch_thanks_bit_start
  • post_thanks_function_show_thanks_date_start
  • post_thanks_function_show_thanks_date_end
  • post_thanks_function_fetch_thanks_bit_end
  • post_thanks_function_fetch_post_thanks_template_start
  • post_thanks_function_fetch_post_thanks_template_end
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • postbit_attachment
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete