Uploaded image for project: 'Jira Software Data Center'
  1. Jira Software Data Center
  2. JSWSERVER-8868

JIRAIFrameAction Reflected XSS

    XMLWordPrintable

Details

    Description

      The JIRAIFrameAction action is vulnerable to reflected XSS when passing an unsanitized url parameter to the Jira-iframe.vm velocity template. Exploitation of the issue first requires a JIRA issue id with read-access.

      File: src\main\Resources\Atlassian-plugin.xml

      <action name="com.pyxis.greenhopper.jira.actions.JIRAIFrameAction" alias="JIRAIFrameAction">
      ...
        <command name="genericIssueIFrame" alias="GenericIssueIFrame">
          <view name="success">/templates/greenhopper/jira/jira-iframe/jira-iframe.vm</view>
          <view name="error">/templates/greenhopper/jira/boards/error.vm</view>
        </command>
      ...
      </action>
      

      File: greenhopper\src\main\java\com\pyxis\greenhopper\jira\Actions\JIRAIFrameAction.java

      JIRAIframeAction.java
      package com.pyxis.greenhopper.jira.actions;
      import com.atlassian.jira.config.SubTaskManager;
      import com.atlassian.jira.issue.link.IssueLinkManager;
      import com.pyxis.greenhopper.GreenHopper;
      import com.pyxis.greenhopper.GreenHopperException;
      import com.pyxis.greenhopper.jira.license.GreenHopperLicenseManager;
      import com.pyxis.greenhopper.jira.util.JiraUtil;
      
      @SuppressWarnings("serial")
      public class JIRAIFrameAction extends BoardAction
      {
        private String url;
        private Long issueType;
        private long displayedTime;
        private boolean absoluteUrl;
      ...  
        /** In this action the url is provided by the caller already. */
        public String doGenericIssueIFrame()
        {
          try 
          {
            if(JiraUtil.getIssue(getId()) == null)
            {
              throw new GreenHopperException("Issue not found", "gh.issue.notfound");
            }
          } 
          catch (Exception e) 
          {
            addError("Issue not found", "Issue not found");
          }     
          try
          {
            if (url == null) {
              throw new GreenHopperException("URL not defined", "gh.issue.notfound");
            }
          }
          catch (Exception e) 
          {
            addError("URL not defined", "URL not defined");
          }
          return hasAnyErrors() ? ERROR : SUCCESS;        
        }
      ...
        public String getUrl()
        {
          return url;
        }
        public void setUrl(String url)
        {
          this.url = url;
        }
        public boolean isAbsoluteUrl()
        {
          return absoluteUrl;
        }
        public void setAbsoluteUrl(boolean absoluteUrl)
        {
          this.absoluteUrl = absoluteUrl;
        }  
      }
      

      File: greenhopper\src\main\resources\templates\greenhopper\jira\Jira-iframe\Jira-iframe.vm

      Jira-iframe.vm
      #disable_html_escaping()
      ##POSSIBLEXSS
      <script type="text/javascript">
        Boards.dynAJSPopup(1050, 620);
        Boards.AJSpopup.addHeader("$action.getText('gh.boards.iframe')");
        AJS.$('.aui-dialog').addClass('gh-dialog gh-dialog-iframe');
        Boards.AJSpopup.addPanel("", "panel1");
        Boards.AJSpopup.getCurrentPanel().html(AJS.$("#jira-iframe"));
        Boards.AJSpopup.addCloseAction('$action.getText('gh.boards.close')', '${action.modifierKey}');
        Boards.AJSpopup.cancelCallback = function() {
          Boards.closeIFrame('$action.issueObject.id', '$action.displayedTime');
          ## don't close the popup yet
          return true;  
        }	
        ## set the src here, as otherwise a stale request is issued for the non-visible html added to the dom
        AJS.$("iframe", Boards.AJSpopup.popup.element).attr('src', '#if(!$action.absoluteUrl)${requestContext.baseUrl}/#end$action.url');	
        Boards.showAJSPopup(0, 0);
      </script>
      <div style="display:none;">
        <div id="jira-iframe"  style="height:100%;">
          <div class="body" style="height:100%;">
            <div class="iframecontainer" style="height:100%;">
            <iframe id="iframe" name="iframe" style="height:100%;width:100%;"></iframe>
          </div>
        </div>
        </div><!-- // \#jira-iframe-->
      </div>
      

      An example URL that will exploit the issue:
      http://10.211.55.9:8082/secure/GenericIssueIFrame.jspa?url=');</script><script>alert(document.cookie);</script>&absoluteUrl=true&id=10028

      Screenshot of the XSS attack:

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              cee3f48a9671 Daniel
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: