Why p_p_auth token is exposed in the URL? Could it be a security risk?

Issue

  • On Liferay Portal 6.2, p_p_auth token is exposed in the URL. It might be considered as a security risk.

Environment

  • Liferay Portal 6.2

Resolution

No attacker or other user can use p_p_auth token, only a legitimate user is able to apply it. Therefore, leaking the token has no value for anybody other than this 'original' user.

 

The p_p_auth parameter is the so called portlet invocation token. The purpose of the token is blocking unauthorized access to portlets
More specifically, the token means a security check for the portlets which can be dynamically added to pages. (For additional information, please see the description of portlet.add.default.resource.check.enabled property below.) 

If an authorized user is navigating throughout the portal, the corresponding portlet URLs are generated with the portlet invocation token appended. The generated invocation token is unique per portlet and user session. That is, if either an unauthenticated user or another authenticated user attempt to reuse the token to access the portlet, the token validation will fail and access will be denied. 

Below please find the description of the related properties for reference:

#
# Portlets that have configured liferay-portlet.xml with the element
# "add-default-resource" set to true will allow those portlets to be
# dynamically added to any page by any user. This is useful
# (and necessary) for some portlets that need to be dynamically added to a
# page, but it can also pose a security risk because it also allows any user
# to do it.
#
# Set this property to true to add a security check around this behavior.
# If set to true, then portlets can only be dynamically added to a page if
# it contains a proper security token. This security token is automatically
# passed when using a portlet URL from one portlet to another portlet.
#
# Modify the property "portlet.add.default.resource.check.whitelist" to
# whitelist certain portlets from this security check.
#
# The security check utilizes the implementation set in the property
# "auth.token.impl".
#
portlet.add.default.resource.check.enabled=true
#
# Set a list of comma delimited portlet IDs that will bypass the security
# check set in the property "portlet.add.default.resource.check.enabled".
#
portlet.add.default.resource.check.whitelist=com_liferay_login_web_portlet_LoginPortlet,com_liferay_portlet_configuration_web_portlet_PortletConfigurationPortlet,com_liferay_portlet_configuration_css_web_portlet_PortletConfigurationCSSPortlet,145,164,166,com_liferay_product_navigation_simulation_web_portlet_SimulationPortlet,com_liferay_staging_bar_web_portlet_StagingBarPortlet

 

Normally, pages have a layout (rows and/or columns) which defines how the portlets are organized on the page. This association is stored in the Layout table (typeSettingscolumn) within the database. 
Certain scenarios however, require to render portlets even if those are not added to the page. 
For example when a guest user navigates to a restricted page, the Login portlet is required to be displayed in order to to force authentication.

Control Panel is also an example of dynamically added portlets, because the page (layout) is representing it -  the Control Panel doesn't actually store the association to portlets as normal layouts do.

 

Fundamentally, the token prevents unauthorized access to portlets that can be rendered dynamically or on-the-fly. Liferay Portal doesn't have an alternative solution for transferring the token currently. 
However, obtaining the token by an attacker is considered to be harmless, because each token is generated for a specific user and stored only in the specific user's session
If someone else want to use the same token, it is validated against the current user session, meaning the validation will fail and access to the portlet will be denied. 

For further details, you may as well search for implementation examples of the following class: 
com.liferay.portal.security.auth.SessionAuthToken

 

However, if a particular security vulnerability issue is discovered in regards leaking p_p_auth token, kindly issue a ticket to Liferay Support by providing exact reproduction steps in order to investigate it.

 

Additional Information

  • A possible workaround would be creating an URL rewrite rule to remove those tokens.
    Please be aware: hence this is not considered as an official recommendation, no thorough testing has been made by Liferay about this method and it is unclear what impact that would have on the function of the portal. 
    Kindly experiment with these settings at your discretion only, since it involves customization and third party software/hardware configuration.

  • Another workaround could be turning off authentication token checking or add actions and portlets to the "ignore" list through portal-ext.properties

    Please see a description below of each property as well as their default values:
##
## Authentication Token
##

    #
    # Set this to true to enable authentication token security checks. The
    # checks can be disabled for specific actions via the property
    # "auth.token.ignore.actions" or for specific portlets via the init
    # parameter "check-auth-token" in portlet.xml.
    #
    auth.token.check.enabled=true

    #
    # Set the authentication token class. This class must implement
    # com.liferay.portal.security.auth.AuthToken. This class is used to prevent
    # CSRF attacks. See http://issues.liferay.com/browse/LPS-8399 for more
    # information.
    #
    auth.token.impl=com.liferay.portal.security.auth.SessionAuthToken

    #
    # Input a list of comma delimited struts actions that will not be checked
    # for an authentication token.
    #
    auth.token.ignore.actions=\
        /asset/rss,\
        \
        /asset_publisher/edit_article_discussion,\
        /asset_publisher/edit_entry_discussion,\
        /asset_publisher/edit_file_entry_discussion,\
        /asset_publisher/edit_page_discussion,\
        \
        /blogs/edit_entry,\
        /blogs/edit_entry_discussion,\
        /blogs/rss,\
        /blogs/trackback,\
        \
        /blogs_aggregator/edit_entry,\
        /blogs_aggregator/edit_entry_discussion,\
        /blogs_aggregator/rss,\
        \
        /document_library/edit_file_entry,\
        /document_library/edit_file_entry_discussion,\
        \
        /document_library_display/edit_file_entry,\
        /document_library_display/edit_file_entry_discussion,\
        \
        /journal/edit_article_discussion,\
        /journal/rss,\
        \
        /journal_content/edit_article_discussion,\
        \
        /image_gallery_display/edit_file_entry,\
        /image_gallery_display/edit_image,\
        \
        /login/create_account,\
        /login/login,\
        \
        /message_boards/edit_discussion,\
        /message_boards/edit_message,\
        /message_boards/rss,\
        \
        /my_sites/view,\
        \
        /page_comments/edit_page_discussion,\
        \
        /shopping/edit_order_discussion,\
        \
        /software_catalog/edit_product_entry_discussion,\
        \
        /wiki/edit_page,\
        /wiki/edit_page_attachment,\
        /wiki/edit_page_discussion,\
        /wiki/get_page_attachment,\
        /wiki/rss,\
        \
        /wiki_admin/edit_page_attachment,\
        \
        /wiki_display/edit_page_attachment,\
        /wiki_display/edit_page_discussion

    #
    # Set a list of comma delimited origins that will not be checked for an
    # authentication token.
    #
    #auth.token.ignore.origins=\
    #    com.liferay.portal.action.JSONServiceAction:com.liferay.portlet.expando.service.ExpandoValueServiceUtil#getJSONData,\
    #    com.liferay.portal.jsonwebservice.JSONWebServiceServiceAction:/classname/,\
    #    com.liferay.portal.jsonwebservice.JSONWebServiceServiceAction:/user/get-user-by-email-address,\
    #    com.liferay.portlet.asset.action.GetCategoriesAction,\
    #    com.liferay.portlet.portletconfiguration.action.GetLookAndFeelAction

    #
    # Set a list of comma delimited portlet ids that will not be checked for an
    # authentication token.
    #
    auth.token.ignore.portlets=82

    #
    # Set the length of the authentication token. Longer auth tokens will
    # require more CPU cycles to generate and may impact overall performance.
    #
    auth.token.length=8

    #
    # Set the shared secret that is used for requests where it is not possible
    # to generate an authentication token (i.e. WSRP).
    #
    #auth.token.shared.secret=

 

这篇文章有帮助吗?
1 人中有 0 人觉得有帮助