Skip to content

Form submissions with !!binary YAML tags crash the CP forms listing (bypasses #6860 fix) #14447

@SwaleySmart

Description

@SwaleySmart

Bug description

PR #9282 (fixing #6860) added a try/catch around YAML parsing in FormSubmissionsStore::makeItemFromFile() to prevent invalid form submissions from breaking the CP. However, there is a code path that bypasses this protection.

When a form submission contains non-UTF-8 bytes (e.g. control characters from copy-paste, or spam bots injecting binary data), Symfony's YAML dumper stores the value using the !!binary tag with base64 encoding. This is valid YAML, so it parses successfully — the ParseException catch doesn't trigger.

The error occurs later when the CP tries to return the paginated JSON response. JsonResponse::setData() calls json_encode(), which throws an InvalidArgumentException: Malformed UTF-8 characters, possibly incorrectly encoded. This crashes the entire forms listing — not just the single bad entry.

Stack trace (abbreviated):

InvalidArgumentException: Malformed UTF-8 characters, possibly incorrectly encoded
  at vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php:89

#0 symfony/http-foundation/JsonResponse.php(49): JsonResponse->setData()
#1 laravel/framework/.../JsonResponse.php(31): JsonResponse->__construct()
#2 laravel/framework/.../ResponseFactory.php(104): JsonResponse->__construct()
#3 laravel/framework/.../PaginatedResourceResponse.php(17): ResponseFactory->json()
#4 laravel/framework/.../ResourceCollection.php(133): PaginatedResourceResponse->toResponse()

How to reproduce

  1. Create a form in Statamic
  2. Create a YAML submission file with a !!binary tagged field containing bytes that are invalid UTF-8 when decoded. For example:
name: 'Test User'
email: test@example.com
message: !!binary dGVzdCBtZXNzYWdlIHdpdGggYmFkIGJ5dGVzOiDtoL3tsYk=

Logs

[2026-04-07 13:41:44] local.ERROR: Malformed UTF-8 characters, possibly incorrectly encoded {"userId":"639ec853-938f-4b60-9bb8-e3816ac6fd26","exception":"[object] (InvalidArgumentException(code: 0): Malformed UTF-8 characters, possibly incorrectly encoded at /home/ploi/site_url/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php:89)
[stacktrace]
#0 symfony/http-foundation/JsonResponse.php(49): Illuminate\\Http\\JsonResponse->setData()
#1 laravel/framework/src/Illuminate/Http/JsonResponse.php(31): Symfony\\Component\\HttpFoundation\\JsonResponse->__construct()
#2 laravel/framework/src/Illuminate/Routing/ResponseFactory.php(104): Illuminate\\Http\\JsonResponse->__construct()
#3 laravel/framework/src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php(17): Illuminate\\Routing\\ResponseFactory->json()
#4 laravel/framework/src/Illuminate/Http/Resources/Json/ResourceCollection.php(133): Illuminate\\Http\\Resources\\Json\\PaginatedResourceResponse->toResponse()

Environment

Environment
Laravel Version: 12.7.2
PHP Version: 8.4.11
Composer Version: 2.9.5
Environment: local
Debug Mode: OFF
Maintenance Mode: OFF

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: NOT CACHED

Drivers
Broadcasting: reverb
Cache: file
Database: sqlite
Logs: stack / single
Mail: mailgun
Queue: sync
Session: file

Statamic
Addons: 1
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 5.63.0 PRO

Installation

Existing Laravel app

Additional details

The existing try/catch in FormSubmissionsStore::makeItemFromFile() (added in PR #9282)
only catches Statamic\Yaml\ParseException. The !!binary YAML tag is valid YAML, so it
parses without error. The decoded binary data then passes through to the CP's JSON
response where json_encode() throws InvalidArgumentException.

This means any form submission containing non-UTF-8 bytes (common from spam bots or
copy-pasted text from Word/Google Docs containing control characters) will completely
break the CP forms listing for that form.

We had 25 spam submissions that brought down the entire forms section. The workaround
was to delete the offending YAML files and clear the Stache cache.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions