Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > Programming Articles

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
  #82  
Old 05-17-2008, 12:39 AM
Aclikyano Aclikyano is offline
 
Join Date: Apr 2006
Posts: 481
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Wayne Luke View Post
Search for: value="$session[sessionhash]"


In every template this occurs in add this line directly after the line containing the above, if it doesn't exist already:
<input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]" />

Save the template.
I did this to avoid editing some newer templates and noticed SOME templates i did before already have it... and Im afraid they have the sec token value=bla bla TWICE instead of just ONCE...

Quote:
<input type="hidden" name="s" value="$session[sessionhash]"
<input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]"
/>
<input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]" />
How would I only make every template have this ONCE like its supposed to be?
Reply With Quote
  #83  
Old 05-17-2008, 10:36 AM
lms lms is offline
 
Join Date: Jan 2008
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by dancue View Post
I'm trying to add the security token to a mod that is giving me an error message. The mod is very important and I'm not getting any answers from the author.

The mod uses AJAX, which is what is not working. When someone uses quickreply and posts their reply it's supposed to automatically reveal the hidden content. Instead it gives the security token issue.

Here are the templates. Must there be a change to the xml file also?

Code:
				<!--hide-addon-->
		<if condition="$vboptions[disable_ajax] != 2">
			<script type="text/javascript"><!--
			var hpostid = 0;
			var hmax = 0;
			function findposts(obj,call){
				ruf = call;
				var laenge = obj.innerHTML.length;
				if (hmax == '0'){
					hmax = laenge;
				} else if (hmax < laenge){
					hmax = laenge;
					Rufen(ruf);
				}
			}
			var hide_aktiv = null;
			var unhide = null;
			var zahl = 0;
			var old;
			var postid
			function Rufen(posting){
				if (window.XMLHttpRequest) {
					unhide = new XMLHttpRequest();
				} else if (window.ActiveXObject) {
					unhide = new ActiveXObject("Microsoft.XMLHTTP");
				}
				old = posting
				var postids = posting.split(",");
				if ( zahl < postids.length){
					postid = postids[zahl];
					unhide.open("POST", "showthread.php", true);
					unhide.onreadystatechange = ausgeben;
					unhide.setRequestHeader(
						"Content-Type",
						"application/x-www-form-urlencoded");
					unhide.send("do=whatever&p="+postid+"&all="+old);
				} else zahl = 0;
			}

			function ausgeben() {
				if (unhide.readyState == 4) {
					if (unhide.responseText != 'sid_hide_still_active'){
						document.getElementById("post_message_"+postid).innerHTML =
							unhide.responseText;
						zahl++;
						Rufen(old);
					} else {
						zahl++;
						Rufen(old);
					}
				} 
				else setTimeout('ausgeben()', 200);
			}
			//-->
			</script>
		</if>
Code:
		<if condition="$vboptions[disable_ajax] != 2 AND $vboptions[sid_hide_ajax_on] == 1">
		<script type="text/javascript">
			if (hide_aktiv) window.clearInterval(hide_aktiv);
			var hide_aktiv = window.setInterval("findposts(fetch_object('posts'),'$hide_call')", 3000);
		</script>
		</if>
		<div id="hide_fieldset"><fieldset>
			<legend><span class="highlight">$vbphrase[sid_hide_post_hide]</span></legend>
			$hide_img
		</fieldset></div>
I understand it's the author's duty to solve the issue, but the author seems to have abandoned the mod.

I am not asking for the solution, but guidance.
C?mbialo por este otro c?digo: (you must change by this other code
Code:
				<!--hide-addon-->
		<if condition="$vboptions[disable_ajax] != 2">
			<script type="text/javascript"><!--
			var hpostid = 0;
			var hmax = 0;
			function findposts(obj,call){
				ruf = call;
				var laenge = obj.innerHTML.length;
				if (hmax == '0'){
					hmax = laenge;
                                        SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
				} else if (hmax < laenge){
					hmax = laenge;
                                        SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
					Rufen(ruf);
				}
			}
			var hide_aktiv = null;
			var unhide = null;
			var zahl = 0;
			var old;
			var postid
			function Rufen(posting){
				if (window.XMLHttpRequest) {
					unhide = new XMLHttpRequest() + SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
				} else if (window.ActiveXObject) {
					unhide = new ActiveXObject("Microsoft.XMLHTTP") + SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
				}
				old = posting
				var postids = posting.split(",");
				if ( zahl < postids.length){
					postid = postids[zahl];
					unhide.open("POST", "showthread.php", true);
					unhide.onreadystatechange = ausgeben;
					unhide.setRequestHeader(
						"Content-Type",
						"application/x-www-form-urlencoded");
					unhide.send("do=whatever&p="+postid+"&all="+old) + SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
				} else zahl = 0;
			}

			function ausgeben() {
				if (unhide.readyState == 4) {
					if (unhide.responseText != 'sid_hide_still_active'){
						document.getElementById("post_message_"+postid).innerHTML =
							unhide.responseText;
						zahl++;
						Rufen(old);
					} else {
						zahl++;
						Rufen(old);
					}
				} 
				else setTimeout('ausgeben()', 200);
			}
			//-->
			</script>
		</if>
Code:
		<if condition="$vboptions[disable_ajax] != 2 AND $vboptions[sid_hide_ajax_on] == 1">
		<script type="text/javascript">
			if (hide_aktiv) window.clearInterval(hide_aktiv);
			var hide_aktiv = window.setInterval("findposts(fetch_object('posts'),'$hide_call')", 3000) + SESSIONURL + 'securitytoken=' + SECURITYTOKEN;
		</script>
		</if>
		<div id="hide_fieldset"><fieldset>
			<legend><span class="highlight">$vbphrase[sid_hide_post_hide]</span></legend>
			$hide_img
		</fieldset></div>
A m? me funciona bien (Me, it works right).

Salud2
Reply With Quote
  #84  
Old 05-21-2008, 06:55 AM
HearthrobZ HearthrobZ is offline
 
Join Date: May 2008
Posts: 3
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

This is really a mess! I'm not a professional coder.Plz Some One make a step by step instruction to do this to avoid security token missing error,as it'd help lot of people.

Thanks
Reply With Quote
  #85  
Old 05-21-2008, 07:40 AM
mikesz mikesz is offline
 
Join Date: Jan 2006
Posts: 45
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I have seen this one before but don't know exactly what triggers it BUT for what its worth,

Find in your footer template the following,


Code:
<if condition="$show['dst_correction']">
<!-- auto DST correction code -->
<form action="profile.php?do=dst" method="post" name="dstform">
	<input type="hidden" name="s" value="$session[sessionhash]" />
	<input type="hidden" name="do" value="dst" />
</form>
It should be:

Code:
<if condition="$show['dst_correction']">
<!-- auto DST correction code -->
<form action="profile.php?do=dst" method="post" name="dstform">
	<input type="hidden" name="s" value="$session[sessionhash]" />
        <input type="hidden" name="securitytoken" value="$bbuserinfo[securitytoken]" />

	<input type="hidden" name="do" value="dst" />
</form>
HTH, mikesz
Reply With Quote
  #86  
Old 05-21-2008, 03:34 PM
blindmedia ltd blindmedia ltd is offline
 
Join Date: May 2008
Location: uk
Posts: 9
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

its ok for you all to say do this if people know the code and i dont know

surely as jelsoft screwed up with this they should issue a fix,i installed my 3.7 as a clean 1st time full install and i still get this error
Reply With Quote
  #87  
Old 05-21-2008, 05:06 PM
scan-pa scan-pa is offline
 
Join Date: May 2006
Location: Lebanon Co. Pa. USA
Posts: 189
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by blindmedia ltd View Post
its ok for you all to say do this if people know the code and i dont know

surely as jelsoft screwed up with this they should issue a fix,i installed my 3.7 as a clean 1st time full install and i still get this error
it's not Jelsofts problem. they fixed all of the templates that come with the basic software. But the current errors are from all of the various Non Jelsoft add-ons and Modification programs. Since jelsoft does not Officialy support these add-ons, you use them at your own risk.

But posted in the early posts is the exact steps you should take to search your templates and find the ones that need the line of code added to it.
Reply With Quote
  #88  
Old 05-21-2008, 09:16 PM
dssart dssart is offline
 
Join Date: May 2002
Posts: 70
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by blindmedia ltd View Post
its ok for you all to say do this if people know the code and i dont know

surely as jelsoft screwed up with this they should issue a fix,i installed my 3.7 as a clean 1st time full install and i still get this error
Do yourself a favor..if your having problems and the hacks you have installed are something you can live without then uninstall them., revert your templates, upgrade, and you will be stress-free. Have you tried contacting the author of the hack? he probably has moved onto other things which is why you are here. If that's the case, the hack is obviously unsupported now and it's just a matter of time anyways before it breaks under another update and you will have to go through this all over again.
Reply With Quote
  #89  
Old 05-22-2008, 09:57 PM
blindmedia ltd blindmedia ltd is offline
 
Join Date: May 2008
Location: uk
Posts: 9
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by dssart View Post
Do yourself a favor..if your having problems and the hacks you have installed are something you can live without then uninstall them., revert your templates, upgrade, and you will be stress-free. Have you tried contacting the author of the hack? he probably has moved onto other things which is why you are here. If that's the case, the hack is obviously unsupported now and it's just a matter of time anyways before it breaks under another update and you will have to go through this all over again.
thats what i said it was a 100% clean install brand new with no hacks installed and it was giving this error

therefore it would be impossible for it to be anything other than vbulletin itself causing the problem

it is 100% vbulletin 3.7.0 at fault there was at the time it started NO other software hack or mods installed
Reply With Quote
  #90  
Old 05-23-2008, 12:55 AM
dssart dssart is offline
 
Join Date: May 2002
Posts: 70
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I can't comment accurately on your situation, but I had serious reservations myself in upgrading from 3.6.9 to 3.7.0. I have a custom hack coded for my forum that I was almost positive was going to fail with this CSRF thing. I did the following and it was the smoothest upgrade I've ever had. Not even my custom hack cracked:

Backup database, backup my /images folder, shut down forum, do upgrade. Upload my custom /images and overwrite the new, then perform upgrade. After, go back and revert everything the upgrade reported as needing to be reverted. Sounds to me like some of the upgrade files were munged during the transfer. I'd re-upload the upgrade files and make sure all appropriate ascii files are transferred as ascii and all binary as binary. Something that simple can easily be overlooked. Also, make sure your config.php is correctly configured. Something is missing..you just have to.

Seeing as it was a brand new install, I'd say the problem is either with a corrupt file upload or misconfigured config.php. Something isn't seeing something the way it's supposed to. Many people have installed the 3.7.0 software as an upgrade (which is a helluva lot trickier than a virgin install) and are running with no problem.
Reply With Quote
  #91  
Old 05-23-2008, 07:19 PM
tafreeh tafreeh is offline
 
Join Date: May 2008
Location: Canada
Posts: 536
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

ok here is the thing .... i almost check all my templates for security tokken code.... and fix all of them ....
but still only super mod getting security tokken error when ever they try to reply to the post... whether in new reply or quick reply ....

can some1 tell me which templates i have fix....
Reply With Quote
Reply

Thread Tools

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 08:34 PM.


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.04937 seconds
  • Memory Usage 2,347KB
  • 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
  • (7)bbcode_code
  • (3)bbcode_php
  • (6)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
  • (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
  • (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
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete