Liferay Community Edition Misconfiguration Exposes Plaintext Passwords in Government Systems via CWE-319

A Russian government information system built on Liferay Community Edition sent user passwords in plaintext emails due to default notification templates and unhardened configuration settings. The portal used Liferay's built-in MailEngine, which retained the hardcoded liferay.com domain in Message-ID headers and left the [$PORTAL_URL$] variable pointing to localhost:8080. Instead of hashing the new password, the custom password-change portlet triggered the default account-creation notification that embedded the actual password via the [$PASSWORD$] macro. This exposed credentials to anyone with access to the recipient mailbox, directly violating CWE-319 requirements for protecting sensitive data in transit. The root cause was the failure to remove the macro from password-change templates and override portal-ext.properties values before deployment. Administrators can remediate the issue in minutes by editing Control Panel notification settings and setting web.server.host, web.server.https.port, and mail.string.id to production values.

HabrTranslated from Russian

Read at source

A Russian government portal running Liferay Community Edition exposed user passwords in plaintext transactional emails, illustrating how default Open Source configurations can undermine even heavily protected state systems and produce a classic CWE-319 vulnerability.

The system was deployed inside a closed government information system (GIS) where every component is expected to undergo strict review. Because commercial Liferay DXP licenses were unavailable under sanctions, engineers selected the free Community Edition hosted on GitHub. Authorization was delegated to external government OAuth 2.0 gateways and CSRF tokens protected the frontend, yet the password-reset workflow remained untouched.

When a user changed their password through a custom portlet, the application invoked Liferay’s default “New Password Notification” template. The template inserted the literal password via the [$PASSWORD$] macro and sent it to the user’s mailbox. The resulting email also carried the developer’s localhost:8080 address in the subject line and retained the American MailEngine domain in the Message-ID header.

Technical evidence found in message source

  • Message-ID contained @://liferay.com, the hardcoded default never overridden in portal-ext.properties.
  • Subject line revealed “http://localhost:8080: Your New Password”, showing that the [$PORTAL_URL$] variable had not been updated for production.
  • Message body contained the actual password in clear text: “Your new password for http://localhost:8080 is HabraHabr1”.

The developers had reused the built-in account-creation trigger instead of creating a dedicated notification that omits the password value. Liferay’s macro is intended only for administrator-initiated temporary passwords; applying it to permanent user-chosen passwords created the dangerous hybrid behavior.

Remediation steps

Security teams can close the exposure without code changes:

  • In Control Panel → System Settings → Users, delete the [$PASSWORD$] macro from both Password Changed Notification and New Password Notification templates.
  • Edit portal-ext.properties and set web.server.host, web.server.https.port, web.server.protocol, and mail.string.id to production values.
  • Restart the application server (Tomcat or WildFly).

The incident demonstrates that even heavily audited Open Source platforms require explicit hardening of notification templates and environment variables before they are placed in high-security government environments.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Vulnerabilities & Exploits

Google Patches 21 Vulnerabilities in Chrome Including Critical MediaStream Flaw
CISA Adds Cisco Secure Firewall and GitLab Flaws to Known Exploited Vulnerabilities Catalog
Telegram for Android Patches Voice Call Vulnerability Enabling Code Execution