Login gadget escapes HTML tags upon invalid login

Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.

Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Except Fisheye and Crucible

Summary

We can customise the login message via <JIRA_INSTALL>/atlassian-jira/WEB-INF/classes/com/atlassian/jira/web/action/JiraWebActionSupport.properties:

JiraWebActionSupport.properties

# Message for login page (login.jsp)

login

.requestaccount =

Not

a

member

?

To

request an account, {0}.

# Message for login gadget

# Public instance

gadget.login.notmember=Not a member? {0}{1}{2} for an account.

# Private instance

gadget.

login

.notmembernotpublic=

Not

a

member

?

To

request an account, {0}.

Message customised with image (place the image in <JIRA_INSTALL>/images/icons ) can be done with HTML tags. The image is displayed accordingly when dashboard is first loaded but the customised message is escaped after an invalid login resulting the HTML tags being ignored.

Customised message is displayed accordingly when it's first loaded:

(Auto-migrated image: description temporarily unavailable)

Customised message is escaped after failed login attempt:

(Auto-migrated image: description temporarily unavailable)

This is only happening with login gadget, not the login page.

Environment

8.5.8

Cause

Tracing where the gadget.login.notmembernotpublic message is used led us tologin.soy:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 {if $isPublicMode} <div class="field-group" id="publicmodeon"> <div id="publicmodeonmsg"> {getText('gadget.login.notmember', '<a id="signup" href="' + contextPath() + '/secure/Signup!default.jspa" tabindex="-1" target="_parent">', getText('gadget.login.notmember.signup'), '</a>')|noAutoescape} </div> </div> {elseif $adminFormOn} <div class="field-group" id="publicmodeooff"> <div id="publicmodeoffmsg"> {getText('gadget.login.notmembernotpublic', getText('common.concepts.contact.administrator', '<a id="contact-admin" href="' + contextPath() + '/secure/ContactAdministrators!default.jspa">', '</a>'))|noAutoescape} </div> </div> {else} <div class="field-group" id="publicmodeooff"> <div id="publicmodeoffmsg"> {getText('gadget.login.notmembernotpublic', getText('common.concepts.contact.administrator', '', ''))} </div> </div> {/if}

As we can see, the last message in the else block is missing noAutoescape.

The login.soy is embedded within <Jira-Install>/atlassian-jira/WEB-INF/atlassian-bundled-plugins/jira-gadgets-plugin-<version>.jar .

Solution

Bug ticket is raised to address this behaviour inconsistency – JRASERVER-72790 - Login gadget escapes HTML tags upon invalid login

As a workaround, follow the below steps to rectify the issue:

  1. Extract the jira-gadgets-plugin-<version>.jar file:

    1 jar xf jira-gadgets-plugin-8.5.8.jar
  2. Edit <Extracted_JAR>/static/dashboarditem/login/login.soy file to include noAutoescape with the last getText method:

    1 {getText('gadget.login.notmembernotpublic', getText('common.concepts.contact.administrator', '', ''))|noAutoescape}
  3. Create a new JAR container after modifying the files and name it the same as the original JAR file (e.g. jira-gadgets-plugin-<version>.jar).

    1 jar cvfm jira-gadgets-plugin-8.5.8.jar META-INF/MANIFEST.MF ./*
  4. Replace the JAR file in <Jira-Install>/atlassian-jira/WEB-INF/atlassian-bundled-plugins

  5. Restart Jira

Updated on April 8, 2025

Still need help?

The Atlassian Community is here for you.