The Symfony2 core team takes security issues very seriously; we have a dedicated procedure to report such issues, and the framework itself tries to give the developer all the features needed to secure his code easily.

Thanks to our successful community donation drive, SektionEins performed a security audit on the Symfony2 code earlier this year. The audit is now over and the good news is that the Symfony2 code is pretty solid; only minor problems have been found. They have all been addressed now, but here is the full report with the relevant commits for reference:

  • Symfony\Component\HttpFoundation\Request::isSecure() trusts SSL_HTTPS and X_FORWARDED_PROTO HTTP headers to decide if served by SSL. Can be used to do HTTP downgrade attacks while performing MITM. Maybe make usage configureable.

    Symfony\Component\HttpFoundation\Request::getHost() trusts X_FORWARDED_HOST HTTP header. Can potentially lead to problems if getHost() is used for dev/production toggle. Or if hostname is output (xss, sql, ...) Maybe make usage configureable.

    Symfony\Component\HttpFoundation\Request::prepareRequestUri() trusts X_REWRITE_URL HTTP header. Can be used to bypass URL filters enforced by Web Application Firewalls. Maybe make usage configureable.

    Fixed here and here.

  • Symfony\Component\Validator\Constraints\TimeValidator::isValid(): Regular expression is not anchored. " evil payload ' 11:11:11 'bla " will be validated as valid time.

    Fixed here

  • Symfony\Component\HttpFoundation\HeaderBag::__toString() uses preg_replace with /e modifier. Seems safe but it would be better to replace with some statement not doing dynamic eval()

    Symfony\Component\DependencyInjection\Container::camelize() uses preg_replace with /e modifier. Seems safe but it would be better to replace with some statement not doing dynamic eval()

    Symfony\Component\Form\Util\PropertyPath::camelize() uses preg_replace with /e modifier. Seems safe but it would be better to replace with some statement not doing dynamic eval()

    Fixed here

  • Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder: Usage of this encoder should be discouraged. Remove it or issue warning on usage.

    The PlaintextPasswordEncoder has been kept as it is needed when using Digest authentication.

  • Cookie::fromString() trusts the data string. Therefore a cookie header can set a cookie as secure even if the response/uri is HTTP only. This is a security problem because a HTTP man in the middle attack could inject a HTTPS cookie into BrowserKit. Suggestion is to ignore the secure flag if the original uri is not given or is not HTTPS.

    Fixed here

  • Symfony\Bundle\FrameworkBundle\Client::getScript(): If any of the $kernel/$request properties contain input like ');phpinfo();// this will get executed. Also ' in filenames would just break the code.

    Symfony\Component\HttpKernel\Client::getScript(): If any of the $kernel/$request properties contain input like ');phpinfo();// this will get executed. Also ' in filenames would just break the code.

    Fixed here

  • Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider::authenticate(): $key is compared with !=. For security purposes !== is recommended.

    Fixed here

  • Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.html.twig: The message of an exception is printed in the format_file_from_text format. This format is marked as secure for html. However it often contains user input for exceptions. Demo: /web/app_dev.php/_profiler/export/xx<script src=data:text;,alert(123);>.txt

    Fixed here