A form with
enctype="text/plain" can send a body that looks like JSON, and a server that ignores Content-Type will parse itA form with enctype="text/plain" and an input named {"amount":100,"x":" produces a body that is valid JSON. Forms don't trigger a preflight. So if the server parses the body as JSON whatever the Content-Type says, the attack works. The fixes: require Content-Type: application/json (a cross-site request with that type needs a preflight, which your CORS setup rejects), use SameSite cookies, and add CSRF tokens.
"Browsers block every cross-site POST with cookies" is the tempting wrong answer. SameSite decides that, and not every browser defaults to Lax. "Forms can set any Content-Type" is wrong. They can only send form-encoded, multipart or plain text.