Is your feature request related to a problem? Please describe.
I am getting sick and tired of all the typecasting I have to do in order to check whether a variable is safe to use. I propose that we introduce some way to manage user controlled input like how we can do in routes (by using it to check whether something is an int or string).
Describe the solution you'd like
There should be a new service that allows us to validate request data. This could be done very easily by calling a function:
class ProductsController extends Controller {
/**
* Get stock levels of a physical store
*
* @param array $params
*
* @return void
*/
public function getStoreStock(array $params): void
{
// If not validated, return to 403 page
$this->request->require([
'productId' => 'required|int',
'storeId' => 'required|int'
]);
...
}
}
Three more examples on how we could set data in keys and values:
$var = [
# Two request parameters
'productId, storeId' => 'required|int',
#string with max 18 characters
'data[key1][key2]' => 'string|max:18',
# Age limit
'age' => 'min:16|numeric',
];
Describe alternatives you've considered
Extending the controller class (which I have done), however, I feel like this is something that should be baked into the framework as a lot of new users have no clue attacks like the one described below exist.
Additional context
User input types are dangerous. A very good example of a way this could be exploited is the hash_hmac function. If an array is passed to this function instead of a string, it will throw a warning and return NULL. This is a very big security concern and there are many other functions that have behavior like this. Therefore this is a must have in order to mitigate attacks based on these kinds of quirks.
P.S. This is not the same as the form component request that someone else submitted. This is about controlling the types on a controller level. This is especially useful when working with REST API's.
What's wrong with Validation component? Is it too hard to use? Well this way could be easier and i guess we could just use Validation component for this.
@Jurigag There is nothing wrong with the validation component. This is simply easier and faster to use. It is also more clear than the validation component.
If you decide to implement this, please do proper arrays instead of using | seperator and also call it something more descriptive like; $this->request->filter(). If we start using | or : seperators in arrays, our code can become unmanageable. Unless of course this is added as an optional alias. I don't mind having this seperators for advanced users :-) Also title of this issue should be Request Filter not Security Improvement.
$filters = [
'storeId' => [
'filter' => 'int', // integer
'required' => true
],
'productId' => [
'filter' => 'int', // integer
'required' => true
]
];
$this->request->filter($filters);
or second example;
$dataKey = $data[key1][key2];
$filters = [
'storeId' => [
'filter' => 'int', // integer
'required' => true
],
'age' => [
'min' => 16,
'filter' => 'num' // numeric
],
$dataKey => [
'max' => 18,
'filter' => 'str' // string
]
];
$this->request->filter($filters);
In v4 there is something similar
$this
->request
->setParameterFilters(
'productId'
['int'],
'post'
)
->setParameterFilters(
'storeId'
['int'],
'post'
)
;
echo $this->request->getFilteredPost('productId'); // int
echo $this->request->getFilteredPost('storeId'); // int
@niden Thanks, will probably write a quick wrapper for that, but it still doesn't allow you to make a variable 'required'.
Closing this: Please vote for this feature here: https://github.com/phalcon/cphalcon/issues/14608
Most helpful comment
@Jurigag There is nothing wrong with the validation component. This is simply easier and faster to use. It is also more clear than the validation component.