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
Ppsl: final step Input_Instance lazy reading php://input #2126
base: 1.9/develop
Are you sure you want to change the base?
Conversation
As in 9d6f4e6 , in subsequent \Requests with php 5.6+ we have redundant re-reading 'php://input' one time per request (simple example is request to non-exist page that leads to forge 2 Request instances - for initial request and for 404 == 2 times 'php://input' reading) , and this commit fix this by reading php://input on demand 1 time to class' static var, not object attr + retains what was achieved by previous commit NOTE: this can potentially break functionality of Input_Instance's child user's classes
Because of your NOTE, I am not in favour of this. It might be better to add this to the constructor, in case an Input_Instance was passed:
like is done with all other global inputs... |
we use $this->raw() inside Input_Instance every time we create object of this class with Input_Instance $input === null Would it better then to make private static variable $php_input_cache (or siimilar name), fill it with php://input content 1 time inside Input_Instance::_init and lazy copy this var into object' variable $this->input_raw = static::$php_input_cache ? Due to the fact that if we autoload Input_Instance, then we need at least 1 reading of 'php://input' (main request), so we can do that in Input_Instance::_init fn without unnecessary reading and re-reading. And such a change doesn't break child classes. |
I don't see the point. The first time |
When requesting an non-exists controller https://github.com/fuel/fuel/blob/1.9/develop/public/index.php#L172
==> call 2 times https://github.com/fuel/fuel/blob/1.9/develop/public/index.php#L131
call first time with $options = true and second with $options = false https://github.com/fuel/core/blob/1.9/develop/classes/request.php#L60 ($options['driver'] is empty)
which create 2 times instance of \Request => forge 2 times \Input with Request $new = $this (this new object of class \Request)
which leads to direct create 2 objects of Input_Instance (not reuse prev instance)
taking into account this
and this
and taking into account above ATN (1), we always have $input === null at least in subsequent HttpNotFoundException which actually leads to double call $this->hydrate() at least when 404
https://github.com/fuel/core/blob/1.9/develop/classes/input/instance.php#L460
so we actually really re-read php://input one more time |
Ah, that is what you mean. Catching the exception in index.php does indeed create a new "primary" request. I can't be to bothered with that to be honest, in apps it shouldn't really happen, as it is an exception, and only as a fallback in case if your application doesn't deal with the exception. |
But with great value of nginx.client_max_body_size (e.g. I admin project with 128M client_max_body_size), we can get a potential blind (i.e. attacker should not to know what exactly endpoint shoul be used, any of non-existent is enough https://github.com/fuel/core/blob/1.9/develop/classes/request.php#L391) DDoS with overmemallocation ~== size of forged huge request on e.g. small vps, and I think we should protect from such type of attack here, isn't it?
Sorry for bad english |
If your worry is DDoS because of memory allocation, then you have a problem, as there are a lot of ways to achieve that. If you allow 128M as body size, you should have the power to process that, as you could easily have legitimate requests with that body size, which can also swamp your server? The code can't (without specific code for that) determine what is a legitimate request, and what isn't? edit: Also, when it gets to that point in index.php, isn't the old request object, and it's linked objects not discarded? |
It was just an example that such settings are possible. And finally what should I do with this commit: make new with proposed private static var, turn it into issue, revoke it or nothing? ) |
I wrote a wrapper class for this issue which dont break users' child classes
Feel free to join it inside a core Input_Instance if you will |
As in 9d6f4e6 , in subsequent \Requests with php 5.6+ we have redundant re-reading 'php://input' one time per request (simple example is request to non-exist page that leads to forge 2 Request instances - for initial request and for 404 == 2 times 'php://input' reading) , and this commit fix this by reading php://input on demand 1 time to class' static var, not object attr + retains what was achieved by previous commit
NOTE: this can potentially break functionality of Input_Instance's child user's classes