From 8ba739ad1ecde1036bfe2e364aee378e137f6dff Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sat, 19 Apr 2014 16:06:49 +0200 Subject: [PATCH] Added stricter URL filtering to prevent DOM Based XSS when the tree view is enabled --- src/navtree.js | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/navtree.js b/src/navtree.js index 9026962dcc4..3914be85c9c 100644 --- a/src/navtree.js +++ b/src/navtree.js @@ -1,5 +1,3 @@ -var SYNCONMSG = 'click to disable panel synchronisation'; -var SYNCOFFMSG = 'click to enable panel synchronisation'; var navTreeSubIndices = new Array(); function getData(varName) @@ -22,6 +20,21 @@ function stripPath2(uri) return m ? uri.substring(i-6) : s; } +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + function localStorageSupported() { try { @@ -44,7 +57,7 @@ function deleteLink() { if (localStorageSupported()) { window.localStorage.setItem('navpath',''); - } + } } function cachedLink() @@ -180,7 +193,7 @@ function newNode(o, po, text, link, childrenData, lastNode) a.className = stripPath(link.replace('#',':')); if (link.indexOf('#')!=-1) { var aname = '#'+link.split('#')[1]; - var srcPage = stripPath($(location).attr('pathname')); + var srcPage = stripPath(pathName()); var targetPage = stripPath(link.split('#')[0]); a.href = srcPage!=targetPage ? url : "javascript:void(0)"; a.onclick = function(){ @@ -274,11 +287,10 @@ function glowEffect(n,duration) function highlightAnchor() { - var aname = $(location).attr('hash'); + var aname = hashUrl(); var anchor = $(aname); if (anchor.parent().attr('class')=='memItemLeft'){ - var rows = $('.memberdecls tr[class$="'+ - window.location.hash.substring(1).replace(/1) hash = '#'+parts[1]; + if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,''); else hash=''; } if (hash.match(/^#l\d+$/)) { var anchor=$('a[name='+hash.substring(1)+']'); glowEffect(anchor.parent(),1000); // line number hash=''; // strip line number anchors - //root=root.replace(/_source\./,'.'); // source link to doc link } var url=root+hash; var i=-1; @@ -448,7 +459,7 @@ function toggleSyncButton(relpath) if (navSync.hasClass('sync')) { navSync.removeClass('sync'); showSyncOff(navSync,relpath); - storeLink(stripPath2($(location).attr('pathname'))+$(location).attr('hash')); + storeLink(stripPath2(pathName())+hashUrl()); } else { navSync.addClass('sync'); showSyncOn(navSync,relpath); @@ -488,7 +499,7 @@ function initNavTree(toroot,relpath) } $(window).load(function(){ - navTo(o,toroot,window.location.hash,relpath); + navTo(o,toroot,hashUrl(),relpath); showRoot(); }); @@ -496,21 +507,20 @@ function initNavTree(toroot,relpath) if (window.location.hash && window.location.hash.length>1){ var a; if ($(location).attr('hash')){ - var clslink=stripPath($(location).attr('pathname'))+':'+ - $(location).attr('hash').substring(1); + var clslink=stripPath(pathName())+':'+hashValue(); a=$('.item a[class$="'+clslink.replace(/