You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -10,72 +10,18 @@ When getting ready to go live with your project for the first time, or when re-l
10
10
11
11
Security is an ongoing process. After going live, you should pay attention to security advisories released via [your service portal](https://support.ibexa.co/), or via [Security advisories](https://developers.ibexa.co/security-advisories) if you're not a subscriber.
12
12
13
-
## Symfony
14
-
15
-
### `APP_SECRET`
16
-
17
-
`APP_SECRET` needs to be a strong, random, securely stored value.
18
-
19
-
- Don't use a default value like `ff6dc61a329dc96652bb092ec58981f7` or `ThisTokenIsNotSoSecretChangeIt`.
20
-
- The secret must be secured against unwanted access. Don't commit the value to a version control system.
21
-
- The secret must be long enough. 32 characters is minimum, longer is better.
22
-
23
-
!!! tip
24
-
25
-
The following command generates a 64-character-long secure random value:
26
-
27
-
`php -r "print bin2hex(random_bytes(32));"`
28
-
29
-
!!! note
30
-
31
-
On [[= product_name_cloud =]], if `APP_SECRET` isn't set, the system sets it to [`PLATFORM_PROJECT_ENTROPY`](https://docs.platform.sh/guides/symfony/environment-variables.html#symfony-environment-variables)
32
-
33
-
### Symfony production mode
34
-
35
-
Only expose Symfony production mode openly on the internet.
36
-
Don't expose the dev mode on the internet, otherwise you may disclose things like `phpinfo` and environment variables.
37
-
Exposing the dev mode exposes things like `phpinfo`, environment variables, and more.
38
-
39
-
For more information about securing Symfony-based systems, see [Authentication and authorisation]([[= symfony_doc =]]/security.html), [more on this subject]([[= symfony_doc =]]/security.html#learn-more), and Symfony's [secrets management system]([[= symfony_doc =]]/configuration/secrets.html).
40
-
41
-
## PHP
42
-
43
-
### Enable `zend.exception_ignore_args` in PHP 7.4 and newer
44
-
45
-
PHP 7.4 introduced the `zend.exception_ignore_args` setting in `php.ini`.
46
-
The default value is 0 (disabled) for backwards compatibility.
47
-
On production sites this should be set to 1 (enabled), to ensure stack traces don't include arguments passed to functions.
48
-
Such arguments could include passwords or other sensitive information.
49
-
You should also make sure no stack trace is ever visible to end users of production sites, though visible arguments are unsafe even if the stack traces only show up in log files.
50
-
51
-
### Disable error output from PHP
52
-
53
-
Symfony in production mode prevents exception messages from being visible to end users.
54
-
However, if Symfony fails to boot properly, such exceptions may end up being visible, including stack traces.
55
-
This can be prevented by [disabling error message output in PHP](https://www.php.net/manual/en/language.errors.basics.php).
56
-
These `php.ini` configuration values should be used on production sites.
57
-
When using [[= product_name_cloud =]], the same settings can be configured in [[= product_name =]]'s `.platform.app.yaml` file.
58
-
59
-
```ini
60
-
display_errors = Off
61
-
display_startup_errors = Off
62
-
```
63
-
64
-
### Other PHP settings
65
-
66
-
Consider what other security related settings are relevant for your needs.
67
-
The [OWASP PHP Configuration Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/PHP_Configuration_Cheat_Sheet.html) contains several recommendations, but be aware that they may be out of date as they don't mention PHP 8.
68
-
69
-
For more information, see [PHP's own security manual](https://www.php.net/manual/en/security.php).
70
-
71
13
## [[= product_name =]]
72
14
73
-
### Fully-vetted admin users
15
+
### Carefully select admin users
74
16
75
17
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.
76
18
77
19
As administrator you have access to full information about the system through the `setup/system_info` policy, and also to user data, role editing, and many other critical aspects.
78
20
21
+
The users in your organization who have backend access must be kept up-to-date.
22
+
Any user leaving the organization must be disabled without delay.
23
+
If a user takes on a new role in the organization, any required role changes for them in [[= product_name =]] must also be made as soon as possible.
24
+
79
25
### Strong passwords
80
26
81
27
Enforce strong passwords for all users.
@@ -90,10 +36,6 @@ This is specially important for admin accounts and other privileged users.
90
36
91
37
See [setting up password rules](passwords.md#password-rules).
92
38
93
-
### Secure secrets
94
-
95
-
Ensure all other secrets are similarly secured: Varnish invalidate token, JWT passphrase (if in use), and any other application-specific secrets.
96
-
97
39
### Protect against brute force attacks
98
40
99
41
Consider introducing a measure against brute force login attacks, like CAPTCHA.
@@ -138,23 +80,11 @@ If you opt to allow them, make sure you take steps to mitigate the risk.
138
80
139
81
The default list of blocked file types contains: `hta htm html jar js jse pgif phar php php3 php4 php5 phps phpt pht phtml svg swf xhtm xhtml`.
140
82
141
-
### Block execution of scripts in `var` directory
142
-
143
-
Make sure the web server blocks the execution of PHP files and other scripts in the `var` directory.
144
-
See the line below `# Disable .php(3) and other executable extensions in the var directory` in the example virtual host files for Apache and Nginx, provided in the [installation documentation](install_ibexa_dxp.md#set-up-virtual-host).
145
-
146
83
### Use secure password hashing
147
84
148
85
Use the most secure supported password hashing method.
149
86
This is currently `bcrypt`, and it's enabled by default.
150
87
151
-
### Use UTF8MB4 with MySQL/MariaDB
152
-
153
-
If you're using MySQL/MariaDB, use the UTF8MB4 database character set and related collation.
154
-
The older UTF8 can lead to truncation with 4-byte characters, like some emoji, which may have unpredictable side effects.
155
-
156
-
See [Change from UTF8 to UTF8MB4](update_db_to_2.5.md#change-from-utf8-to-utf8mb4).
157
-
158
88
### Use secure roles and policies
159
89
160
90
Use the following checklist to ensure the roles and policies are secure:
@@ -187,7 +117,18 @@ Reduce your attack surface by exposing only what you must.
187
117
188
118
- If possible, make the back office unavailable on the open internet.
189
119
-[Symfony FOSJsRoutingBundle](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle) is required in those releases where it's included, to expose routes to JavaScript. It exposes only the required routes, nothing more. It's only required in the back office SiteAccess though, so you can consider blocking it in other SiteAccesses. You should also go through your own custom routes, and decide for each if you need to expose them or not. See the documentation on [YAML route definitions for exposure](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/blob/master/Resources/doc/usage.rst#generating-uris).
190
-
- By default, a [Powered-By header](https://doc.ibexa.co/en/latest/update_and_migration/from_1.x_2.x/update_db_to_2.5/#powered-by-header) is set. It specifies what version of the DXP is running. For example, `x-powered-by: [[= product_name_exp =]] v4`. This doesn't expose anything that couldn't be detected through other means. But if you wish to obscure this, you can either omit the version number, or disable the header entirely.
120
+
- By default, a [Powered-By header](https://doc.ibexa.co/en/latest/update_and_migration/from_1.x_2.x/update_db_to_2.5/#powered-by-header) is set. It specifies what version of the DXP is running. For example, `x-powered-by: [[= product_name_exp =]] v4`. This doesn't expose anything that couldn't be detected through other means. But if you wish to obscure this, you can either omit the version number, or disable the header entirely by setting `enabled: false`.
121
+
122
+
```yaml
123
+
ibexa_system_info:
124
+
system_info:
125
+
powered_by:
126
+
# major => v4 || minor => v4.6 || none
127
+
release: major
128
+
# true || false
129
+
enabled: false
130
+
```
131
+
191
132
- Consider whether certain interfaces must be left available on the open internet. For example:
192
133
- The `/search` and `/graphql` endpoints
193
134
- The REST API endpoints
@@ -203,19 +144,72 @@ Reduce your attack surface by exposing only what you must.
203
144
- { path: ^/search, roles: ROLE_USER}
204
145
```
205
146
206
-
## Underlying stack
147
+
## Symfony
207
148
208
-
Once you have properly configured secure user roles and permissions, to avoid exposing your application to any DDOS vulnerabilities or other yet unknown security threats, make sure that you do the following:
149
+
### `APP_SECRET` and other secrets
209
150
210
-
- Avoid exposing servers on the open internet when not strictly required.
211
-
- Ensure any servers, services, ports and virtual hosts that were opened for testing purposes are shut down before going live.
212
-
- Ensure file system permissions are set up in such a way that the web server or PHP user can't access files they shouldn't be able to read.
213
-
- Secure the database with a good password, keys, firewall.
214
-
Optionally, ensure that the database user used by the web app only has permissions to do the operations needed by [[= product_name =]].
215
-
The Data Definition Language (DDL) commands (create, alter, drop, truncate, comment) are only needed for installing and upgrading [[= product_name =]], and not for running it.
216
-
Not granting these rights to web app users reduces the damage that can result from a security breach.
151
+
`APP_SECRET`needs to be a strong, random, securely stored value.
152
+
This applies also to other secrets that may be in use, like the Varnish invalidate token, the JWT passphrase, and any other application-specific secrets.
217
153
218
-
Those steps aren't needed when using [[= product_name_cloud =]], where the provider handles them.
154
+
- Don't use a default value like `ff6dc61a329dc96652bb092ec58981f7` or `ThisTokenIsNotSoSecretChangeIt`.
155
+
- The secret must be secured against unwanted access. Don't commit the value to a version control system. There are several ways of handling it, like with enviroment variables or files like `.env.local`. Files are considered more secure. If you store the secrets in files, make sure to add those files to `.gitignore` or similar, so they will never be committed to version control systems.
156
+
- The secret must be long enough. 32 characters is minimum, longer is better.
157
+
158
+
!!! tip
159
+
160
+
The following command generates a 64-character-long secure random value:
161
+
162
+
```shell
163
+
php -r "print bin2hex(random_bytes(32));"
164
+
```
165
+
166
+
!!! note
167
+
168
+
On [[= product_name_cloud =]], if `APP_SECRET` isn't set, the system sets it to [`PLATFORM_PROJECT_ENTROPY`](https://docs.platform.sh/guides/symfony/environment-variables.html#symfony-environment-variables)
169
+
170
+
### Symfony production mode
171
+
172
+
Only expose Symfony production mode openly on the internet.
173
+
Don't expose the dev mode on the internet, otherwise you may disclose things like `phpinfo` and environment variables.
174
+
175
+
For more information about securing Symfony-based systems, see [Authentication and authorisation]([[= symfony_doc =]]/security.html), [more on this subject]([[= symfony_doc =]]/security.html#learn-more), and [secrets management system]([[= symfony_doc =]]/configuration/secrets.html), all from Symfony.
176
+
177
+
## PHP
178
+
179
+
### Enable `zend.exception_ignore_args` in PHP 7.4 and newer
180
+
181
+
PHP 7.4 introduced the `zend.exception_ignore_args` setting in `php.ini`.
182
+
The default value is 0 (disabled) for backwards compatibility.
183
+
On production sites, this should be set to 1 (enabled) to ensure that stack traces don't include arguments passed to functions.
184
+
Such arguments could include passwords or other sensitive information.
185
+
You should also make sure that no stack trace is ever visible to end users of production sites. Visible arguments are unsafe even if the stack traces only show up in log files.
186
+
187
+
### Disable error output from PHP
188
+
189
+
Symfony in production mode prevents exception messages from being visible to end users.
190
+
However, if Symfony fails to boot properly, such exceptions may end up being visible, including stack traces.
191
+
This can be prevented by [disabling error message output in PHP](https://www.php.net/manual/en/language.errors.basics.php).
192
+
The following `php.ini` configuration values should be used on production sites.
193
+
When using [[= product_name_cloud =]], the same settings can be configured in [[= product_name =]]'s `.platform.app.yaml` file.
194
+
195
+
```ini
196
+
display_errors = Off
197
+
display_startup_errors = Off
198
+
```
199
+
200
+
### Other PHP settings
201
+
202
+
Consider what other security related settings are relevant for your needs.
203
+
The [OWASP PHP Configuration Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/PHP_Configuration_Cheat_Sheet.html) contains several recommendations.
204
+
205
+
For more information, see [PHP's own security manual](https://www.php.net/manual/en/security.php).
206
+
207
+
## Web server
208
+
209
+
### Block execution of scripts in `var` directory
210
+
211
+
Make sure that the web server blocks the execution of PHP files and other scripts in the `var` directory.
212
+
See the line below `# Disable .php(3) and other executable extensions in the var directory` in the example virtual host files for Apache and Nginx, provided in the [installation documentation](install_ibexa_dxp.md#set-up-virtual-host).
219
213
220
214
### Security headers
221
215
@@ -242,6 +236,75 @@ This header has several directives for fine-tuning the referrer information.
242
236
- `Permissions-Policy`- limits what features the browser can use, such as fullscreen, notifications, location, camera, or microphone.
243
237
For example, if someone succeeds in injecting their JavaScript into your site, this header prevents them from using those features to attack your users.
244
238
239
+
### Disable weak cipher suites in TLS
240
+
241
+
Consider blocking the use of TLS 1.2 and older versions.
242
+
The newer TLS 1.3 doesn't include the weaker cipher suites that are included in 1.2 and older.
243
+
Removing them means that attackers can't attempt to force other users to use weak ciphers and eavesdrop on their communications.
244
+
As of December 2024, TLS 1.3 is [supported by ca. 97% of global internet users](https://caniuse.com/tls1-3).
245
+
If you need to support Internet Explorer or old versions of other browsers, you can disable TLS 1.1 and older, leaving 1.2 and 1.3 enabled.
246
+
247
+
When using [[= product_name_cloud =]], you can [set the minimum TLS version in `.platform/routes.yaml`](https://docs.platform.sh/define-routes/https.html#enforce-tls-13).
248
+
249
+
### Enable HTTP Strict Transport Security (HSTS)
250
+
251
+
HSTS forces clients to always communicate with your site over HTTPS.
252
+
[Most browsers support this](https://caniuse.com/stricttransportsecurity), and there is no downside for browsers that don't.
253
+
Read the requirements and instructions at [hstspreload.org](https://hstspreload.org/) before you enable HSTS.
254
+
Make sure to also include subdomains by means of the `includeSubDomains` setting.
255
+
256
+
When using [[= product_name_cloud =]], you can [configure HSTS in `.platform/routes.yaml`](https://docs.platform.sh/define-routes/https.html#enable-http-strict-transport-security-hsts).
257
+
258
+
Beware if you are using a Varnish proxy:
259
+
Your version of Varnish may not support HTTPS connections with your web server.
260
+
If so, make sure to only enable HSTS between your public-facing proxy and the clients.
261
+
When using [[= product_name_cloud =]], this is handled automatically.
262
+
263
+
## Domain
264
+
265
+
### Enable Domain Name System Security Extensions (DNSSEC)
266
+
267
+
DNSSEC is a DNS feature that authenticates responses to DNS requests.
268
+
It protects against DNS poisoning attacks, which is when an attacker manipulates the reponses to DNS requests with the goal of directing users to an IP address the attacker controls.
269
+
Enabling DNSSEC involves creating the DNSSEC records in your domain, activating DNSSEC with your domain registrar, and enabling DNSSEC signature validation on all DNS servers.
270
+
[Read more on DNSSEC on ICANN's website](https://www.icann.org/resources/pages/dnssec-what-is-it-why-important-2019-03-05-en).
271
+
272
+
### Enable domain update/delete protection
273
+
274
+
Domain update/delete protection is a DNS setting that makes it harder for an attacker to take over a domain from the real owner, or hinder availability for users.
275
+
You can enable this protection at your domain registrar's site.
276
+
Log in to their site to enable these protection settings and save the new configuration.
CAA allows domain owners to specify which Certificate Authorities (CAs) are permitted to issue SSL/TLS certificates for their domain.
281
+
This prevents attackers from having certificates issued for domains they don't own, hindering some types of attack.
282
+
CAA is configured in your DNS zone file.
283
+
284
+
## Database
285
+
286
+
### Use UTF8MB4 with MySQL/MariaDB
287
+
288
+
If you're using MySQL/MariaDB, use the UTF8MB4 database character set and related collation.
289
+
The older UTF8 can lead to truncation with 4-byte characters, like some emoji, which may have unpredictable side effects.
290
+
291
+
See [Change from UTF8 to UTF8MB4](update_db_to_2.5.md#change-from-utf8-to-utf8mb4).
292
+
293
+
### Secure access
294
+
295
+
Secure the database access with strong passwords, keys, firewall, encryption in transit, encryption at rest, and so on, as needed.
296
+
When using [[= product_name_cloud =]], the provider handles this.
297
+
298
+
## Underlying stack
299
+
300
+
To avoid exposing your application to any DDOS vulnerabilities or other yet unknown security threats, make sure that you do the following:
301
+
302
+
- Avoid exposing servers on the open internet when not strictly required.
303
+
- Ensure any servers, services, ports, and virtual hosts that were opened for testing purposes are shut down before going live.
304
+
- Ensure file system permissions are set up in such a way that the web server or PHP user can't access files they shouldn't be able to read.
305
+
306
+
Those steps aren't needed when using [[= product_name_cloud =]], where the provider handles them.
307
+
245
308
### Track dependencies
246
309
247
310
- Run servers on a recent operating system and install security patches for dependencies.
@@ -250,3 +313,9 @@ For example, if someone succeeds in injecting their JavaScript into your site, t
250
313
to receive notifications when a security fix is released in a GitHub-hosted dependency.
251
314
- If you're not using GitHub for your project, you can create a dummy project on GitHub with the same dependencies as your real project, and enable Dependabot notifications for that.
252
315
- Ensure you get notifications about security fixes in JavaScript dependencies.
316
+
317
+
### Monitor logs
318
+
319
+
- Enable logging for [[= product_name =]], the web server, any frontend proxies, and the database.
320
+
- Monitor the logs for unusual and suspicious activity. Consider using log monitoring software to make this easier.
321
+
- Consider using different accounts for manual administrative tasks and for the day-to-day running of your installation. You could for instance configure [[= product_name =]] to use a different database user than the one you use during upgrades. This can make it easier to filter out noise in your log monitoring solution.
0 commit comments