Hi Stas,

On Sun, Aug 21, 2016 at 1:39 PM, Stanislav Malyshev <smalys...@gmail.com> wrote:
>
>> It's possible to design web pages/services to "unknown clients", but
>> it's exceptional cases.
>
> No, it's not. Every service exposed to the internet is for unknown clients.

Right and wrong.

Every service exposed to the internet is for unknown clients, but we
can impose certain input/output rules defined by web application
developers and/or standards.

>
>> Almost all systems have intended clients. If protocol is HTTP/HTTPS,
>> developers may reject strange data that cannot be right for
>> HTTP/HTTPS. Even higher level than PHP does this. i.e. HTTP servers
>> will rejects malformed and/or prohibited request and terminates
>> execution. Web Application Firewall does more fancy things and
>
> True, because we can have no PHP business logic that can work on HTTPS
> level. We can have PHP business logic that works on PHP level though.
>
>> validate/check, in general.  IMHO, use of WAF is more burden and
>> costly than the input validation that I'm proposing.
>
> I'm not sure where WAF comes in - these are two completely different uses.

Not really.

The more application validates inputs, the less WAF rules for web app
are required. There is close relationship between web apps and WAF.

WAF can do more than web application like mitigating protocol/web
server/language vulnerabilities. This differs, but most web app
protection rules can be implemented in web app. Whitelist parameter
validation in WAF is hard, but it's easy in web app because developers
know what parameter should be exactly. e.g. "id" parameter could be
integers or strings like userid, WAF admins have to refer to code to
be precise while app developers know.

>
>> Web application developers have right to define "valid" inputs. ("have
>> right" does not mean "can do anything") PHP script termination for
>> invalid input is just one of terminations. It's nothing special.
>
> You can perfectly well have your app do anything you like - including
> termination - on filter failure. I don't see how it necessitates making
> new set of filters though?
>
>> I think your premise is "Show nice error message for any errors,
>> proceed as normal case".  (Handle invalid/insane data just like mistakes)
>>
>> My premise is "Shouldn't show nice messages to attacker, terminate as
>> abnormal case". (Treat them as attack or serious system bug)
>>
>> It's design choice. Either way is possible.
>
> Sure, and it's possible with current filters too. If the check fails,
> and you want to terminate, what prevents you from doing:
>
> if(!filter_var($var, FILTER_VALIDATE_INT) === false) { exit(); }
>
> Am I missing some important point here?

There is no string validation filter while string is the most dangerous input.

It does not allow multiple rules for an array element with filter_*_array().

Current validation filters are designed for filter and convert. e.g.
FILTER_VALIDATE_BOOL converts empty to FALSE.

Do you think it's nicer to have many lines of

// Assuming log_validation_error_and_exit($key_name, $value)
// is implemented properly.
if(!filter_var($_POST['int'], FILTER_VALIDATE_INT) === false) {
log_validation_error_and_exit('int', $_POST['int']); }
if(!filter_var($_POST['bool'], FILTER_VALIDATE_BOOL) === false) {
log_validation_error_and_exit('bool', $_POST['bool']); }
if(!filter_var($_POST['float'], FILTER_VALIDATE_FLOAT) === false) {
log_validation_error_and_exit('float', $_POST['float']); }
if(!filter_var($_POST['string'],
FILTER_VALIDATE_REGEX,array("options"=>array("regexp"=>"/^M(.*)/")))
=== false) { log_validation_error_and_exit('string',
$_POST['string']); }

rather than this?

// Assuming exception handler is set properly.
$post_def = array(
   'int' => FILTER_VALIDATE_INT,
   'bool' => FILTER_VALIDTE_BOOL,
   'float' => FILTER_VALIDATE_FLOAT,
   'string' => array(FILTER_VALIDTE_REGEX,
                    array("options"=>array("regexp"=>"/^M(.*)/")
                  ),
);
filter_require_var_array($_POST, $post_def);

Try to implement "strict validation rules" with current filter,
especially with filter_*_array(). They do not work well as I mentioned
in the RFC.

https://wiki.php.net/rfc/add_validate_functions_to_filter#why_not_compare_filter_var_array_result
=================
Why not compare filter_var_array() result?

Following code may seem to work, but it would not.

$ret = filter_var_array($arr, $validation_spec);
if ($ret != $arr) {
  die('Input does not validate');
}

One should never compare float equality. (Float string is converted to
float type. Think of huge string value and result of float converted
value comparison.)
They are filter(conversion) functions. e.g. URLs are converted to lowercase.
It allows empty input by default and add NULL element.
int/float/bool validation filters trim and convert type. (They cannot
match by “==” comparison)

For these reasons, comparing original and return(filtered) value is
not suitable for strict input validation.
=================

It's obvious to me current filter module needs improvements to write
better validation code.

Regards,

--
Yasuo Ohgaki
yohg...@ohgaki.net

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

Reply via email to