[JSWSERVER-5562] XSS (reflected) in rankVMID parameter of GetRankPage.jspa

          Reviewed again the code and removed this parameter entirely.

          JoanneA (Inactive) added a comment - Reviewed again the code and removed this parameter entirely.

          David Black added a comment - - edited

          To be honest I would fix this issue like the following:
          1. use Ajs.$ (jquery) 'on' event on the various a links with javascript targets in the velocity file and then call the Boards.searchFor - with the values for the Boards.searchFor set as attributes on the <a> element.

          e.g.

          diff -r 9f0ebd04e28f greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm
          --- a/greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm	Thu Nov 22 14:46:43 2012 +1100
          +++ b/greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm	Thu Nov 22 17:41:46 2012 +1100
          @@ -9,11 +9,11 @@
           				<span>
           					#if($action.selectedBoard.pagination.showStartPagine())
           						#if($action.selectedBoard.pagination.start == 0)<span class="active">$action.getText('gh.drop.startpagine')</span>
          -						#else<a href="javascript:Boards.searchFor('0', '$action.selectedBoard.strippedSearchKeyForInput', '${action.escapeJavaScript($action.searchType)}', '${action.escapeJavaScript($action.redirectType)}');">$action.getText('gh.drop.startpagine')</a>#end
          +						#else<a id="first_a_link_example" href="#" start='0' key='$action.selectedBoard.strippedSearchKeyForInput' searchType='${action.escapeJavaScript($action.searchType)}' redirectType='${action.escapeJavaScript($action.redirectType)}';">$action.getText('gh.drop.startpagine')</a>#end
           					#end
           					#foreach($page in $action.selectedBoard.pagination.pages)
           						#if($action.selectedBoard.pagination.isSelected($page))<span class="active">$page.pageNumber</span>
          -						#else<a href="javascript:Boards.searchFor('$page.start', '$action.selectedBoard.strippedSearchKeyForInput', '${action.escapeJavaScript($action.searchType)}', '${action.escapeJavaScript($action.redirectType)}');">$page.pageNumber</a>#end
          +						#else<a id="second_a_link_example" href="javascript:Boards.searchFor('$page.start', '$action.selectedBoard.strippedSearchKeyForInput', '${action.escapeJavaScript($action.searchType)}', '${action.escapeJavaScript($action.redirectType)}');">$page.pageNumber</a>#end
           					#end
           					#if($action.selectedBoard.pagination.showEndPagine())
           						#if($action.selectedBoard.pagination.lastPageSelected)<span class="selected">$action.getText('gh.drop.endpagine')</span>
          @@ -51,4 +51,13 @@
           		#end
           	</div>
           #end
          -<script type="text/javascript">GH.Util.hideAll(['opt_wait', 'Search_wait']);</script>
          +<script type="text/javascript">GH.Util.hideAll(['opt_wait', 'Search_wait']);
          +AJS.$.("first_a_link_example, second_a_link_example").on("click", function (event) {
          +    var _this = AJS.$(this);
          +    Boards.searchFor(this.attr('start'), this.attr('key'), this.attr('searchType'), this.attr('redirectType'));
          +
          +});
          
          +</script>
          

          David Black added a comment - - edited To be honest I would fix this issue like the following: 1. use Ajs.$ (jquery) 'on' event on the various a links with javascript targets in the velocity file and then call the Boards.searchFor - with the values for the Boards.searchFor set as attributes on the <a> element. e.g. diff -r 9f0ebd04e28f greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm --- a/greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm Thu Nov 22 14:46:43 2012 +1100 +++ b/greenhopper/src/main/resources/templates/greenhopper/jira/boards/searchboard/search-results.vm Thu Nov 22 17:41:46 2012 +1100 @@ -9,11 +9,11 @@ <span> # if ($action.selectedBoard.pagination.showStartPagine()) # if ($action.selectedBoard.pagination.start == 0)<span class= "active" >$action.getText( 'gh.drop.startpagine' )</span> - # else <a href= "javascript:Boards.searchFor( '0' , '$action.selectedBoard.strippedSearchKeyForInput' , '${action.escapeJavaScript($action.searchType)}' , '${action.escapeJavaScript($action.redirectType)}' );" >$action.getText( 'gh.drop.startpagine' )</a>#end + # else <a id= "first_a_link_example" href= "#" start= '0' key= '$action.selectedBoard.strippedSearchKeyForInput' searchType= '${action.escapeJavaScript($action.searchType)}' redirectType= '${action.escapeJavaScript($action.redirectType)}' ;">$action.getText( 'gh.drop.startpagine' )</a>#end #end #foreach($page in $action.selectedBoard.pagination.pages) # if ($action.selectedBoard.pagination.isSelected($page))<span class= "active" >$page.pageNumber</span> - # else <a href= "javascript:Boards.searchFor( '$page.start' , '$action.selectedBoard.strippedSearchKeyForInput' , '${action.escapeJavaScript($action.searchType)}' , '${action.escapeJavaScript($action.redirectType)}' );" >$page.pageNumber</a>#end + # else <a id= "second_a_link_example" href= "javascript:Boards.searchFor( '$page.start' , '$action.selectedBoard.strippedSearchKeyForInput' , '${action.escapeJavaScript($action.searchType)}' , '${action.escapeJavaScript($action.redirectType)}' );" >$page.pageNumber</a>#end #end # if ($action.selectedBoard.pagination.showEndPagine()) # if ($action.selectedBoard.pagination.lastPageSelected)<span class= "selected" >$action.getText( 'gh.drop.endpagine' )</span> @@ -51,4 +51,13 @@ #end </div> #end -<script type= "text/javascript" >GH.Util.hideAll([ 'opt_wait' , 'Search_wait' ]);</script> +<script type= "text/javascript" >GH.Util.hideAll([ 'opt_wait' , 'Search_wait' ]); +AJS.$.( "first_a_link_example, second_a_link_example" ).on( "click" , function (event) { + var _this = AJS.$( this ); + Boards.searchFor( this .attr( 'start' ), this .attr( 'key' ), this .attr( 'searchType' ), this .attr( 'redirectType' )); + +}); +</script>

          I believe what you really want is for it to be jsencoded when it is put into js strings and and in some cases additionally html encoded. The current fix will mean the js is passed an incorrect id. Things inside script tags dont need html encoding, only javascript string escaping

          jhinch (Atlassian) added a comment - I believe what you really want is for it to be jsencoded when it is put into js strings and and in some cases additionally html encoded. The current fix will mean the js is passed an incorrect id. Things inside script tags dont need html encoding, only javascript string escaping

          vosipov I am not convinced that the fix is the 'best' way to fix the issue. I'll look at the velocity file some more shortly in regards to this issue.

          David Black added a comment - vosipov I am not convinced that the fix is the 'best' way to fix the issue. I'll look at the velocity file some more shortly in regards to this issue.

          VitalyA added a comment -

          dblack, please have a quick look at the vm template.

          VitalyA added a comment - dblack , please have a quick look at the vm template.

          The fix for this bug was in the velocity template which is not unit-testable - discussed with mtokar and agreed not to create a webdriver test.

          JoanneA (Inactive) added a comment - The fix for this bug was in the velocity template which is not unit-testable - discussed with mtokar and agreed not to create a webdriver test.

          Checked in on branch GHS-5562. Please test with GHS-6705.

          Changed from using escapeJavaScript to htmlEncode - this ensures that all characters are encoded including ", <, > rather than just prefixed with \ which is safer for using inside html attributes.

          JoanneA (Inactive) added a comment - Checked in on branch GHS-5562 . Please test with GHS-6705 . Changed from using escapeJavaScript to htmlEncode - this ensures that all characters are encoded including ", <, > rather than just prefixed with \ which is safer for using inside html attributes.

          How to reproduce this bug:

          This occurs in the rendering of a list of issues on this page. If you try to access a similar URL and see a message reading "Not Authorised" or "No Issues Found" then you will not see the problem.

          It can be reproduced on a local instance.

          To get a URL to work locally, change the host name and then make the fieldId the id of the Rank custom field, and ProjectId a valid project ID with some issues.

          Using the usual GH dataset, fieldId=customfield_10004 and projectId=10703 works to reproduce (anonymous project).

          JoanneA (Inactive) added a comment - How to reproduce this bug: This occurs in the rendering of a list of issues on this page. If you try to access a similar URL and see a message reading "Not Authorised" or "No Issues Found" then you will not see the problem. It can be reproduced on a local instance. To get a URL to work locally, change the host name and then make the fieldId the id of the Rank custom field, and ProjectId a valid project ID with some issues. Using the usual GH dataset, fieldId=customfield_10004 and projectId=10703 works to reproduce (anonymous project).

          This issue was not actually fixed. Simply the specific payload being supplied as reflected html was broken.
          The latest isec report provides the following url to test this issue (with an updated payload):

          https://test01.jira-dev.com/secure/GetRankPage.jspa?fieldId=customfield_10006&start=0&versionId=-1&rankVMID=fielddd491"><img src=u onerror=alert(1)>060025152f2db6800&decorator=none&selectedProjectId=10000&pageType=ChartBoard&subType=ArchiveChartBoard&type=ACB&selectedBoardId=-1&colPage=1

          This attack still works in greenhopper 6.0.6.

          David Black added a comment - This issue was not actually fixed. Simply the specific payload being supplied as reflected html was broken. The latest isec report provides the following url to test this issue (with an updated payload): https://test01.jira-dev.com/secure/GetRankPage.jspa?fieldId=customfield_10006&start=0&versionId=-1&rankVMID=fielddd491 "><img src=u onerror=alert(1)>060025152f2db6800&decorator=none&selectedProjectId=10000&pageType=ChartBoard&subType=ArchiveChartBoard&type=ACB&selectedBoardId=-1&colPage=1 This attack still works in greenhopper 6.0.6.

          In agreement with Jason, I can no longer reproduce this vulnerability on FF. Marking this as done.

          Peter Obara added a comment - In agreement with Jason, I can no longer reproduce this vulnerability on FF. Marking this as done.

            Unassigned Unassigned
            dblack David Black
            Affected customers:
            0 This affects my team
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: