37 Audits
JourneysHow to secure your Liferay site

How to secure your Liferay site

Patch what is vulnerable, close the endpoints Liferay exposes by default, and harden TLS, cookies and headers. Part one of the Liferay series.

A Liferay site that was installed with default settings answers anonymous requests on its API pages, tells every visitor which product it runs, and leaves most browser protections to you. None of this is hard to fix, but it is spread across portal-ext.properties, Tomcat and the web server in front of them, so it rarely gets done in one sitting.

This journey puts it in order. First you tell 37 Audits which Liferay version you run, so the checks know what to look for. Then you patch, close what is exposed, and work outward through HTTPS, cookies and browser headers. The last two steps cover what cannot be seen from outside: sign-in settings and the servers behind Liferay.

Most steps have an auditor that checks the result on your monitored URL. A few complete by hand, either because nothing outside your network can verify them or because a correct Liferay setup still leaves a finding you have to judge yourself. Each of those steps says so.

This is the first of three Liferay journeys. The others are How to make your Liferay site fast and How to keep your Liferay site online.

Steps

Open a step to read it
  1. 1
    Register your Liferay version

    Three auditors in this journey read the software stack of your project, not the site. Without a Liferay entry the CVE and Latest Version auditors have nothing to look up and the Protected URL Auditor probes generic paths like /admin instead of the Liferay ones.

    Do this

    • Open the project that owns this URL and find Software Stack

    • Choose Add Software and set the vendor to Liferay

    • Pick the product (DXP or Portal) and the version from the list the form offers. It is the list of releases Liferay publishes, so an installed release is always in it: 2025.Q1.16 LTS, 7.4 U101, 7.4.3.132 GA132

    • Find the version under Control Panel → Server Administration, or in the startup log

    Done when the project lists Liferay with the version that is running in production. Update it after every upgrade, or the next steps will check the wrong release.

  2. 2
    Patch known vulnerabilities
    Verifies with CVE Auditor

    Liferay publishes every security advisory with the versions it affects. Attackers read the same list, and a public advisory against the version you run is the easiest way into the site.

    The CVE Auditor compares the version you registered against Liferay's known vulnerabilities. It fails on any advisory scored 7.0 or higher and warns on lower ones.

    Do this

    • Run the auditor and open the findings

    • For each advisory, read which update, fix pack or quarterly release fixes it

    • Plan the update. If you cannot update now, apply the workaround the advisory describes

    • After updating, change the version in the Software Stack and run again

    Done when the auditor finds no advisory that affects your version. If the fix for an advisory exists only on a newer line, your line may be out of support. How to keep your Liferay site online checks that with the End of Life auditor.

  3. 3
    Apply the latest fix release of your line
    Verifies with Latest Version Auditor

    Liferay ships fixes for a release line as new releases of that line: updates and fix packs on 7.x, patch releases on the quarterly lines (2025.Q1.16 after 2025.Q1.15). That is where security patches land, and an advisory often says no more than "fixed in the latest release of your line".

    The Latest Version auditor compares the version in your Software Stack with the release list Liferay publishes. It fails when a later fix release of your line exists, and warns when a newer line exists at all.

    Do this

    • Run the auditor. A failure names the fix release you should be on

    • Apply it. A fix release stays inside your line, so the update is small and your customisations usually need no change

    • Decide how often you take fix releases, and put it in the calendar. Liferay publishes them through the year

    • After each update, change the version in the Software Stack and run again

    Done when the auditor reports no later fix release of your line. The warning about a newer line is a different decision, covered in How to keep your Liferay site online. That warning stays while you are on an LTS line, so this step completes by hand.

  4. 4
    Close the endpoints Liferay exposes
    Verifies with Protected URL Auditor

    A default Liferay answers anonymous visitors on pages that list every remote service it offers. /api/jsonws documents the JSON web services, /o/api is the headless API explorer, and /c/portal/json_service is the older JSON servlet. They are meant for developers and they give an attacker a map.

    The Protected URL Auditor requests these paths and the Control Panel without signing in. A path is protected when it answers 401, 403 or 404, or redirects to the sign-in page.

    Do this

    • At the web server or load balancer, deny outside requests to /api/jsonws, /o/api and /c/portal/json_service, or allow only your office and integration addresses

    • In portal-ext.properties, set jsonws.web.service.api.discoverable=false so the JSON web services page stops listing services

    • Restrict the servlets by address with jsonws.servlet.hosts.allowed and json.servlet.hosts.allowed

    • Check that the Control Panel sends anonymous visitors to sign-in

    • Add paths of your own, such as a custom servlet, in the auditor's paths preference on the URL's Configuration tab

    Done when the auditor reports every path as protected. Test your integrations afterwards: anything that calls these APIs from outside needs to be on the allow list.

  5. 5
    Stop advertising server versions
    Verifies with Server Fingerprint Auditor

    Knowing the exact version of Tomcat, Apache or Liferay lets an attacker pick the right exploit without probing. These versions travel in response headers that nobody needs.

    The Server Fingerprint Auditor reads Server, X-Powered-By and X-AspNet-Version and fails when one carries a version number. It does not read Liferay's own Liferay-Portal header, so check that one yourself.

    Do this

    • Apache: ServerTokens Prod and ServerSignature Off. Nginx: server_tokens off

    • Tomcat: keep xpoweredBy off on the connector and set showServerInfo="false" on the ErrorReportValve so error pages stop printing the version

    • Liferay: set http.header.version.verbosity=off in portal-ext.properties to remove the Liferay-Portal header

    Done when the auditor passes and curl -sI https://your-site/ shows no Liferay-Portal header.

  6. 6
    Redirect HTTP to HTTPS
    Verifies with HTTP Redirect Auditor

    Anyone who types your address without https:// starts on plain HTTP. Until the redirect happens, the request can be read or changed on the way, including the session cookie if it is not marked secure.

    The HTTP Redirect Auditor requests the http:// version of your URL and expects a permanent redirect to https://. A 302 is a warning.

    Do this

    • At the web server or load balancer, answer every request on port 80 with a 301 to the same path on HTTPS

    • In portal-ext.properties, set web.server.protocol=https so the links Liferay generates use HTTPS

    • If TLS ends at a proxy, set web.server.https.port to the public port so Liferay does not build URLs with Tomcat's port

    Done when the auditor reports a 301, 307 or 308 to HTTPS.

  7. 7
    Serve a valid certificate on modern TLS
    Verifies with Certificate AuditorVerifies with TLS Version Auditor

    In most Liferay installations TLS ends at the web server or load balancer, not at Tomcat, so that is where these two checks are fixed.

    The Certificate Auditor validates the chain the way a browser does: expired, revoked, self-signed, wrong hostname, untrusted root or missing intermediate all fail. The TLS Version Auditor tries each protocol version and fails when TLS 1.0 or 1.1 is still accepted.

    Do this

    • Install the full chain, intermediates included. A missing intermediate works in some browsers and fails in API clients

    • Check that the certificate names every hostname the site answers on, including virtual hosts of other Liferay sites

    • Turn off TLS 1.0 and 1.1

    • Turn on TLS 1.3. With 1.2 alone the auditor warns and this step will not complete by itself

    Done when both auditors pass.

  8. 8
    Turn on HSTS
    Verifies with HSTS Preload Auditor

    The redirect from step 6 protects a visitor only after the first plain request. HSTS tells the browser to skip that request and use HTTPS from the start, for as long as you say.

    The HSTS Preload Auditor expects the header in the form browsers accept for their preload list: a max-age of at least one year, includeSubDomains and preload.

    Do this

    • First confirm that every subdomain of your domain serves HTTPS. includeSubDomains applies to all of them, including intranet hosts and old staging servers

    • At the web server, on HTTPS responses, send Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

    • If you are unsure, start with a short max-age and without preload, and raise it once nothing breaks

    Done when the auditor passes. Browsers remember this header for the whole max-age, so removing it later does not undo it quickly.

  9. 9
    Remove mixed content
    Verifies with Mixed Content Auditor

    A page served over HTTPS that loads an image or script over http:// is only partly protected. Browsers block the scripts and warn about the rest.

    On Liferay the usual sources are content, not code: web content articles with pasted http:// image links, fragments and widget templates with hardcoded URLs, old theme files, and embedded iframes.

    The Mixed Content Auditor loads the page in a browser and fails for every request or element that uses http://.

    Do this

    • Run the auditor and open the findings to see each URL

    • Fix the URL where it lives: the article, the fragment, the template or the theme

    • Use relative or https:// URLs in new content

    • web.server.protocol=https from step 6 fixes the URLs Liferay generates itself

    Done when the auditor finds no http:// resource. Run it on your busiest pages too, not only the home page.

  10. 10
    Secure the session cookies
    Verifies with Cookie Auditor

    JSESSIONID is the signed-in user. If a script can read it, or it travels over plain HTTP, the session can be stolen.

    The Cookie Auditor checks every cookie set by the monitored URL. A cookie without HttpOnly fails. A missing Secure or SameSite is a warning.

    Do this

    • In Tomcat's web.xml, inside <session-config>, add a <cookie-config> with <http-only>true</http-only> and <secure>true</secure>

    • If TLS ends at a proxy, make Tomcat aware of it (secure="true" and scheme="https" on the connector, or the RemoteIpValve), or it will not mark cookies secure

    • Add SameSite=Lax through Tomcat's cookie processor or at the proxy

    • Review the other cookies in the findings. Liferay sets some of its own, such as GUEST_LANGUAGE_ID and COOKIE_SUPPORT, that carry no session data

    Done when JSESSIONID has Secure, HttpOnly and SameSite, and every remaining finding is a cookie you looked at and decided to accept. This step does not complete by itself, because a correctly configured Liferay can still leave such a finding. Mark it complete when you are satisfied.

  11. 11
    Send the browser security headers
    Verifies with X-Frame-Options AuditorVerifies with X-Content-Type-Options AuditorVerifies with Referrer Policy AuditorVerifies with Permissions Policy Auditor

    Four response headers switch on protections that browsers leave off by default. They are attached together here because you set them in the same place.

    Do this

    • Check what the site already sends with curl -sI https://your-site/. Liferay adds some of these itself, depending on the version, and sending a header twice causes its own problems

    • X-Frame-Options: SAMEORIGIN stops other sites from framing yours. If another of your sites embeds Liferay pages in an iframe, that will stop working

    • X-Content-Type-Options: nosniff stops browsers from guessing file types, which matters for uploaded documents

    • Referrer-Policy: strict-origin-when-cross-origin keeps full page URLs from leaking to other sites

    • Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=() turns off device features the site does not use. Allow only the ones a page needs

    • Add the missing ones at the web server so they also cover error pages and static files

    Done when all four auditors pass.

  12. 12
    Add a Content Security Policy
    Verifies with Content Security Policy Auditor

    A Content Security Policy tells the browser which sources of script, style and frames the page may use. It is the strongest defence against injected script, and the hardest header to get right on a portal, because Liferay pages contain inline scripts.

    The CSP Auditor fails when the header is missing and warns when the policy is report-only or allows unsafe-inline or unsafe-eval.

    Do this

    • Start with Content-Security-Policy-Report-Only and a report endpoint, and watch what real pages would break

    • List the origins you depend on: CDN, analytics, tag manager, maps, video

    • Recent DXP releases have a Content Security Policy setting that adds a nonce to Liferay's own inline scripts. Use it if your version has it. On older versions, set the header at the web server

    • Switch to the enforcing header once the reports are quiet

    Done when the enforcing header is live and the pages you care about still work. Many Liferay sites cannot drop unsafe-inline, and the auditor keeps warning about it, so this step completes by hand. A policy with unsafe-inline still limits where scripts and frames can come from, which is better than no policy.

  13. 13
    Harden sign-in

    No auditor can see these settings from outside. They are the installation defaults that should not survive into production.

    Do this

    • Change the default administrator. A fresh install creates test@liferay.com with the password test (default.admin.* in the portal properties). Rename it and set a strong password, or replace it with named accounts

    • Set setup.wizard.enabled=false

    • If visitors should not create their own accounts, set company.security.strangers=false, or turn it off under Instance Settings → User Authentication

    • Leave passwords.encryption.algorithm on the PBKDF2 default. Do not lower the rounds to save CPU. If sign-in load is a problem, move authentication to SSO

    • Set a session timeout that fits the data behind the login. Liferay's checklist uses 10 minutes in web.xml, which overrides session.timeout

    • Require a second factor for administrators, in Liferay or in your identity provider

    Done when the default account is gone, the setup wizard is off and self-registration matches what the site needs.

  14. 14
    Lock down what sits behind Liferay

    Liferay's reference architecture puts a firewall in front of the load balancer and treats everything behind it as trusted. That only holds if nothing behind it answers the internet.

    Do this

    • Elasticsearch: by default it needs no login to search or browse the index, and the index holds your content and user data. Turn on its security features (authentication and encryption) and configure them in Liferay's Elasticsearch connector

    • Confirm that the Elasticsearch, database and Tomcat ports are not reachable from outside. Test from a machine off your network

    • JMX: the monitoring flags in Liferay's go-live checklist disable authentication and SSL. That is fine on a closed network and dangerous anywhere else. Bind JMX to an internal interface or require authentication

    • If your policy calls for it, add firewalls and encryption between tiers

    Done when a port scan from outside shows only 80 and 443.

    Next in the series: How to make your Liferay site fast.

Create an account, add your site as a monitored URL and work through these steps on it.

© 2026 37 Audits. All rights reserved. Audit your websites with confidence.

Supported by

Made with ❤️ in Floripa

How to secure your Liferay site | 37 Audits