Symfony Configuration Cheat Sheet


Symfony Configuration Cheat Sheet

Symfony is one of the most widely used PHP frameworks with many components and options. Our Symfony Configuration Cheat Sheet shows how to ensure a secure baseline for your framework in 10 steps.

The Symfony framework provides web developers with a great foundation for their PHP applications. Several components can be used for many recurring tasks that are required in every application, such as handling input forms or accessing a database. In addition to functional tasks, security-relevant tools such as user management or protection mechanisms against popular web attacks are available. Our cheat sheet provides an overview of the 10 most important settings you should verify in your Symfony configuration.



1. Use Strong Database Credentials

Do not use the root user for your database connection and choose a strong password that is long and secure. Create different users for different applications. Use environment variables for secrets.

A database, whether as a server or SQLite binary, often contains the most sensitive data of your users and customers. You have to make sure that this data is stored securely. The first steps are secure secrets and no default values as credentials when configuring the database.

config/packages/doctrine.yaml

1234
doctrine:
    dbal:
        url: '%env(DATABASE_URL)%'	
	# 'mysql://unique_user:secure_password@127.0.0.1:3306/unique_db_name'
Use environment variables for secrets and credentials.

.env

1
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

2. Enable CSRF Protection

Enable the built-in CSRF protection globally. If necessary, disable protection only for specific form controller.

Cross-Site Request Forgery (CSRF) is an often forgotten vulnerability in web applications. It allows attackers to submit requests in the name of other users to impersonate their privileges. With an activated CSRF protection, a secret token prevents that attackers can immitate arbitrary requests.

config/packages/framework.yaml

12
framework:
    csrf_protection: true

3. Use Strong Hashing Algorithms

It is important that your passwords are secure, even if your database is leaked. Use a strong hashing algorithm and never save the passwords as plaintext.

A strong algorithm, such as bcrypt, makes it very difficult for an attacker to deduce the plaintext password from the password hash.

config/packages/security.yaml

12345
security:
    encoders:
        Symfony\Component\Security\Core\User\User:
            algorithm: bcrypt
            cost: 15

4. Avoid Hardcoded Credentials

Do not store user data in files located on the server. Internal and external attackers can steal hardcoded credentials and these are hard to manage on production systems.

config/packages/security.yaml

1234567
providers:
  in_memory:
      memory:
          users:
              admin:
                  password: supersecurepassword
                  roles: 'ROLE_ADMIN'
Instead, manage and store your users in a database. For this you can simply use the FOSUserBundle, which after a simple integration relieves you of many steps of user administration.

config/packages/security.yaml

1234
security:
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

5. Use Data Validation

Use the input validation options of Symfony. These allow to check the correctness of user data in forms or database entries and to reject malicious input.

It often helps to use annotations in your code. These can also be used to define validation for properties.

config/packages/framework.yaml

123
framework:
    validation: { enable: true }
    # OR validation: { enable_annotations: true }

6. Enforce HTTPS

Always ensure that controllers that process or display user data can only be accessed via a secure protocol.

This configuration prevents that Man-in-the-Middle attackers can read sensitive data when transmitted over insecure networks.

config/packages/framework.yaml

1234
secure:
    path:       /secure
    controller: App\Controller\MainController::secure
    schemes:    [https]

7. Set Global Access Control

Make sure to set access permissions in the global security configuration for all controllers, following the least-privilege design principle.

Setting access rights in each individual controller can cause you to forget a path or controller so that an unauthorized user can have access to sensitive data. Always whitelist, not blacklist to capture all cases.

config/packages/security.yaml

12345
security:
    access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin, role: ROLE_ADMIN }
    - { path: ^/, role: ROLE_USER }

8. Select Random App Secret

Use a long, random and unique string as secret. Never use the same secret for two different apps.

The secret is used to create unique CSRF tokens, but it is also used for other elements where a unique and random string is required. The secret can also be stored in an env variable.

config/packages/framework.yaml

12
framework:
    secret: '%env(APP_SECRET)%'

9. Review CORS headers

Cross-Origin Resource Sharing helps you if you want to load content and scripts from other servers. If you work with CORS, use it wisely and limit it as much as you can.

The NelmioCorsBundle offers Symfony the possibility to allow sources for CORS. Again it is recommended to use environment variables and always whitelist, not blacklist to capture all cases.

config/packages/nelmio_cors.yaml

1234
nelmio_cors:
    defaults:
        allow_origin: ['^https?://localhost(:[0-9]+)?$']
        # OR allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']

10. Avoid Outdated Dependencies

Use tools to continuously check your dependencies for known and new vulnerabilities.

Complex applications nowadays consist of more public libraries and dependencies than own lines of code. Since your security relies on these external packages, you should regulary check their security. You can use the security checker from Symfony. Load and use it with composer as follows:
12
composer require sensiolabs/security-checker
php bin/console security:check


Our cheat sheet is designed to help users that are new to the Symfony framework to verify if their configuration is secure. But also advanced users can use this guide to double check if any settings were misconfigured over time, especially those that are secure by default.

There are, of course, other configuration options that need to be considered. With the help of static analysis solutions, framework configuration files can be automatically scanned for all subtle misconfigurations. More importantly, static analysis can detect unknown, critical vulnerabilities in your custom code that is build on top of the Symfony framework.



Tags: nils werner, misconfiguration, symfony, framework,

Author: Nils Werner

Software Engineer

Nils philosophy is not to break up existing applications, but to build and lay the foundation for secure web applications. Premising on profound knowledge of his master's degree in IT Security at the Ruhr-University Bochum, he focuses on the secure configuration and integration of frameworks and other libraries.

Comments

comments powered by Disqus