When getting ready to go live with your project for the first time, or when re-launching it, make sure that your setup is secure.
Please also refer to development guidelines during development.
APP_SECRET needs to be a strong, random, securely stored value.
- Do not use a default value like
- The secret must be secured against unwanted access. Do not commit the value to a version control system.
- The secret must be long enough. 32 characters is minimum, longer is better.
The following command will generate a 64-character-long secure random value:
Symfony production mode¶
Only expose Symfony production mode openly on the internet.
Do not expose the dev mode on the internet, otherwise you may disclose things like
phpinfo and environment variables.
Exposing the dev mode exposes things like
phpinfo, environment variables and so on.
More information about Symfony security
For more information about securing Symfony-based systems, see:
Fully-vetted admin users¶
Make sure Admin users and other privileged users who have access to System Information and setup in the back end are vetted and fully trustworthy.
As administrator you have access to full information about the system through the
and also to user data, Role editing, and many other critical aspects.
Enforce strong passwords for all users. This is specially important for admin accounts and other privileged users.
- Never go online with admin password set to
publishor any other default value.
- Introduce password quality checks. Make sure the checks are strict enough (length/complexity).
- 16 characters is a quite secure minimum length. Do not go below 10.
Ensure all other secrets are similarly secured: Varnish invalidate token, JWT passphrase (if in use), and any other application-specific secrets.
Protect against brute force attacks¶
Introduce a measure against brute force login attacks (captcha, etc.).
Disable Fastly when using Varnish¶
If you are using Fastly, disable Varnish. See Security advisory: EZSA-2020-002.
Block the execution of scripts in the
Make sure the web server blocks the execution of PHP files and other scripts in the
Use secure password hashing¶
Use the most secure supported password hashing method.
This is currently
bcrypt, see Increased password hash length.
Restrict access to the back end¶
If possible, make the back end unavailable on the open internet.
Use UTF8MB4 with MySQL/MariaDB¶
If you are using MySQL/MariaDB, use the UTF8MB4 database character set and related collation. The older UTF8 can lead to truncation with 4-byte characters, like some emoji, which may have unpredictable side effects.
Use secure Roles and Policies¶
Use the following checklist to ensure the Roles and Policies are secure:
- Do Roles restrict read/write access to content as they should? Is read/write access to personal data, like User Content items, properly restricted?
- Are the Roles and their use properly differentiated and restricted? Is an editor Role used for everyday editorial work?
- Is the admin Role used only for high-level administrative work? Is the number of people with admin access properly restricted and vetted?
- Should people be allowed to create new user accounts themselves? Should such accounts be enabled by default, or require vetting by admins?
- Is the Role of self-created new users restricted as intended?
- Is there a clear Role separation between the organisation's internal and external users?
- Is access to user data properly restricted, in accordance with GDPR?
- Avoid exposing servers on the open internet when not strictly required.
- Ensure any servers, services, ports and virtual hosts that were opened for testing purposes are locked down before going live.
- Secure the database with a good password, keys, firewall, etc.
- Run the server on a recent operating system and dependencies with security patches installed.
- Configure the server to alert you about security updates from vendors. Pay special attention to dependencies used by your project directly, or by PHP.
eZ Publish Legacy¶
If you are using Legacy Bridge, there are a few more things to check:
- Is there a measure in place against brute force login attacks?
MaxNumberOfFailedLogin > 0will do.
GeneratePasswordLength(if used) have sane values? The default values are low. 16 characters is a secure minimum. Do not go below 10.
- Is verification of user email enabled? See
- If the site is from the era of MD5 hashes, is
UpdateHash=trueset? This will update hashes as they are used, to the much more secure bcrypt algorithm.
- Do you require unique emails? You should, if emails are allowed to be used when logging in. See