Hi internals,

I recently ran into issues with the ini setting `max_input_vars`.
By default, it will truncate input variables in `$_POST` etc. to the first 1000, and issue a E_WARNING.

The form I was using had an extremely big multiselect, where in one case around 1000 options were actively selected, each selected option being sent to the server as a separate `my_select[]` POST variable. The select was the final field in the form, thus is was not immediately noticed when `max_input_vars` truncated options from the select.

I have since changed `max_input_vars` to a higher value, but there was nevertheless an unknown amount of data loss in the meantime.

I would have strongly preferred if the request had been aborted with an error, instead of issuing a warning and continuing with incomplete
data.
However, I could not find a way to reliably detect a way that input variables had been truncated. There are some suggested solutions in [1], but all of them have downsides:
- Counting variables inside `$_POST`:
    If there are multiple variables with the same name (without `[]` at the end), they will be counted for `max_input_vars`, but only show up once in `$_POST`.     (This happens in the legacy application I am working on, I do not see it changing anytime soon.)
- Checking `php://input`:
    This is not possible if the request uses `multipart/form-data`.
- Checking `error_get_last()` for the warning:
    This seems extremely brittle - even if currently there is no other warning thrown at startup, if that changes in the future, this might break.
- Custom error handler using `set_error_handler()`:
    This is not possible, as the warning is thrown before any PHP code can run (and register the handler).

If I missed a reliable method, I would be thankful, and this email can be ignored.

In summary, I believe this can only be solved inside of PHP itself, by allowing to configure a way for `max_input_vars` to abort the request instead of truncating the input.
The options I see feasible are:
- A new ini setting `max_input_vars_abort` (default to 0), which, if set to 1, will abort the request if there are more input variables than allowed. - A method to reliably detect whether the input vars were truncated (eg. `function has_post_been_truncated(): bool`), so the application can decide whether to abort or not. - Deciding that `max_input_vars` is not relevant anymore and should be handled by the likes of Apache and NGINX, thus changing the default to `0` and removing the setting
    over a deprecation period.

I am leaning towards the first option, but would be open to either outcome.

Regards,

Mel Dafert

[1]: https://stackoverflow.com/questions/12169818/in-php-how-can-i-detect-that-input-vars-were-truncated-due-to-max-input-vars-be

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to