Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid POSTed UTF-8 is accepted and stored, causing JSON GET endpoints to fail #42

Open
wandernauta opened this issue Jan 19, 2024 · 2 comments

Comments

@wandernauta
Copy link

wandernauta commented Jan 19, 2024

Trifecta does not generally check that the string values it receives in POST requests are valid UTF-8, instead passing along the bytes as-is. SQLite will for the most part do the same. However, nlohmann's json will not, and cannot per JSON spec; instead, it will throw on invalid sequences, causing any GET endpoints that try to include bad UTF-8 in their JSON responses to fail.

For robustness, it may be better to already refuse POST requests that have these invalid values, before storing the values in the database. Actual browsers will not make these kinds of requests.

An example that does not require authentication, but which does need direct access to Trifecta (so without nginx), would be the following:

curl -H "X-Real-IP: $(printf '\xc3\x28')" -F user=@<(printf admin) http://localhost:3456/get-signin-email

After this request, the admin panel's sessions table would now include the attacker-provided X-Real-Ip value, but this is invalid. The app logs:

/all-sessions: exception for An error occurred: [json.exception.type_error.316] invalid UTF-8 byte at index 1: 0x28

And the UI appears broken:

Screenshot

Other examples would be e.g. putting invalid UTF-8 into post titles, image captions, user-agent headers, email addresses, and so on, but those would require authentication.

@wandernauta
Copy link
Author

Note that if exceptions are thrown with messages that contain invalid UTF-8, this will cause the process to abort: the exception handler tries to turn the exception into JSON, which then throws.

For instance, if you have an admin session, you can do:

curl -H "Cookie: session=..." -F $'user=\xc3\x28' -F $'password=x' http://localhost:3456/change-password

which will log as follows:

Attemping to set password for user �(
/change-password: exception for An error occurred: Tried to change password for user '�(', but does not exist
terminate called after throwing an instance of 'nlohmann::json_abi_v3_11_2::detail::type_error'
  what():  [json.exception.type_error.316] invalid UTF-8 byte at index 55: 0x28
zsh: IOT instruction (core dumped)  ./build/trifecta --rnd-admin-password=continue

Of course, admin users can POST to /stop anyway which has roughly the same effect, so as far as I can tell this does not really let users do anything they couldn't do before.

@berthubert
Copy link
Owner

The crash in the exception handler has been addressed in 60448c7 - thanks for spotting this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants