Can you keep a secret?
What two people know is a secret. What ten people know is information.
I’ll go straight to the point: The Symfony app secret is critical for security. If it leaks, is cracked, or guessed, your application is compromised. If you have any suspicion it may have already leaked or be in danger of leaking, replace it with a new secret, and check your installation for possible intrusion. Now.
Here’s a quick summary of our advice, before we dive into the details:
- Replace any default secrets (see below)
- Replace any short (less than 32 characters) secrets
- Replace any old (several years) secrets
- Replace any secrets that may have been exposed (config file on GitHub, site in dev-mode without access controls, etc)
FragmentListener is made for handling edge-side includes (ESI), and is designed to execute PHP code in response to certain requests. This of course makes it a target of interest for attackers, which is why we only accept requests that are cryptographically signed with a valid keyed-hash message authentication code (HMAC). To make a valid HMAC you need a key: The Symfony app secret.
This makes it crucial that this secret is indeed kept secret, to avoid any possibility of such code execution attacks. To illustrate how we can keep it secret, let’s look at how attackers can get hold of the secret.
The first, and easiest way is if the web site uses a default value. Ideally, software should not include any default secrets or passwords. Please note that while the current release of Ibexa DXP (v3.2) comes with a default secret, this is expected to end with v3.3 in December 2020. Until then, the solution is obviously to replace the default with your own secret. Here’s a list of current and older defaults you should never use:
The second way is brute forcing the secret. To do that, the attacker must have access to a valid hash, knowledge of how the hash is generated, and enough computing power. For the hash, any valid fragment request URL will do, and those are by necessity included in ordinary responses from the web server. CSRF tokens and remember-me-cookies can also be based on the app secret. The open-source nature of the kernel of Ibexa DXP/ eZ Platform means the how of hash generation is also given.
How much computing power you need depends on how long and how random the secret is, and this is why the whole matter of the app secret is not in itself a security vulnerability. A strong, well-kept secret is impossible to crack within a time useful to the attacker. If it takes 1000 years to crack, no-one will bother. But if your secret is the word “secret”, it won’t last long. In other words, the rules for a strong app secret are the same as for a strong password. And fortunately, you don’t have to memorize your secret, you save it as you set up your site. This means you can make it very long and very random. Our documentation now suggests a 64 characters-long secret based on PHP’s cryptographically secure pseudo-random generator
random_bytes(). Change your secret if it is shorter than 32 characters.
Be aware that old versions of eZ Publish Platform would auto-generate a random secret that wasn’t secure enough. It depended on the current time when the secret was generated, which can be leaked by checking the creation dates of the oldest content in an installation. This can limit the time to crack the secret to mere hours. If your app secret is years old, we strongly recommend replacing it with a new one. It’s a good idea to do this regularly in any case, for instance at one- or two-year intervals.
The third way for an attacker to get hold of the secret is through vulnerabilities. If the secret is stored in your config files, make sure your web server blocks all external access to those, as it should in any case. If your code is hosted on a public code repository on e.g. GitHub, make sure you don’t store this critical configuration there. Even if your repository isn’t public, it’s risky to put secrets into it. Repositories are duplicated onto developer’s private machines, where they can be leaked in many ways. If your secret is stored in an environment variable as is common in Platform.sh, it can be leaked for instance by phpinfo(), which is exposed by the Symfony web debug toolbar when the site is running in dev mode. If your site is reachable on the public internet, either don’t use dev mode, or protect all access with a strong password.
I hope this is all clear. Don’t hesitate to contact us in the comments, or through secure channels if that is needed. Thanks for reading, and stay secure!