This bundle provides:
- Console commands that scan configured translation directories, read and write YAML files, and optionally call machine translation APIs over HTTPS.
- An optional HTTP Web UI for the missing-translation log (
missing_translation_log.web_ui) — disabled by default.
- Filesystem: commands resolve paths under the project’s configured translation directories and write YAML when not using
--dry-run. - HTTP (optional Web UI): list / mark-added / clear routes under a configurable path prefix when
web_ui.enabledistrue. - Configuration: bundle options and Symfony parameters (
translator.default_path,framework.translator.paths). - Outbound HTTP:
fill-missingsends source strings to Google / DeepL / LibreTranslate when configured. - Environment:
GOOGLE_TRANSLATE_API_KEY,DEEPL_AUTH_KEY, and similar must remain secret.
| Threat | Mitigation |
|---|---|
| Unauthenticated Web UI | Default web_ui.enabled: false. Enabling the UI requires security.authorization_checker (SecurityBundle) unless allow_unauthenticated: true (dev/demo only). Default required_role: ROLE_ADMIN via MissingLogUiAccessSubscriber. Also protect with firewall / access_control. |
| Path traversal via crafted domain/locale names | Domain/locale options are validated against discovered file names; new files are created only under resolved translation directories with a safe domain.locale.ext pattern. |
| SSRF / data exfiltration via translator | Backends use fixed HTTPS endpoints (or configured LibreTranslate base URL); request bodies contain text snippets from translation files. |
| Secret leakage | API keys are read from environment / DI parameters, never logged by the bundle. Do not enable verbose HTTP dumps in production for the same process. |
| YAML bomb / DoS | TranslationYamlFileHandler rejects files above 2 MiB, trees deeper than 64, or more than 50 000 nodes. Framework config YAML discovery skips oversized files. |
| Path traversal (fill-missing) | Domain/locale constrained to [a-zA-Z0-9_-]+; new YAML paths must resolve under configured translation directories. |
| SSRF via LibreTranslate URL | libretranslate_base_url host must be in libretranslate_allowed_hosts (default libretranslate.com); HTTPS-only unless libretranslate_allow_http. |
| MT quota / hang DoS | Optional machine_translation_min_interval_ms pacing, machine_translation_max_requests_per_run cap, and machine_translation_http_timeout (default 30s) on all backends. |
| CSRF on UI mutations | POST actions require CSRF tokens (missing_log_mark_added, clear, clear-status). |
When enabling missing_translation_log.web_ui.enabled:
- Install
symfony/security-bundle(and Twig + CSRF as documented in CONFIGURATION.md). - Keep
allow_unauthenticated: false(default). - Keep
required_role: ROLE_ADMIN(or a stricter role). - Add
access_controlfor yourpath_prefix. - Prefer installing the bundle as
require-devso production kernels do not register it.
- No symmetric crypto in the bundle.
- Store API keys in
.env.local, your secret manager, or CI secrets — not in Git.
- Commands use Symfony Console output only; they do not log translation values or API keys.
- Run
composer auditregularly and keepsymfony/*andphpranges aligned with supported versions.
- Install as
require-devwhere possible so production containers do not register the bundle. - Restrict who can run
bin/consolein shared environments. - Never expose demos that set
allow_unauthenticated: trueon a public host.
| Item | Confirm before release |
|---|---|
docs/SECURITY.md up to date |
[ ] |
.env / secrets not committed |
[ ] |
| No hard-coded API keys | [ ] |
| Safe defaults in Flex recipe / docs | [ ] |
| Web UI requires SecurityBundle (or explicit allow_unauthenticated) | [ ] |
| Input validation for CLI options | [ ] |
| YAML size/depth/node caps | [ ] |
composer audit reviewed |
[ ] |
| No sensitive data in logs | [ ] |
| Outbound calls documented (MT APIs) | [ ] |
| File write scope documented (translations dirs) | [ ] |
| Dependency updates for known CVEs | [ ] |
| Permissions / dev-only install guidance | [ ] |
| Rate limits / quotas understood for translation API | [ ] |