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

Safer parse_str() usage #566

Merged
merged 3 commits into from
May 12, 2022

Conversation

tanakahisateru
Copy link
Contributor

@tanakahisateru tanakahisateru commented Apr 12, 2022

Description of the change

parse_str() reports warning if parsed items exceeded over thanmax_input_vars. Rollbar Logger logs this internal error instead of user errors.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Maintenance
  • New release

Related issues

None

Checklists

Development

  • Lint rules pass locally
  • The code changed/added as part of this pull request has been covered with tests
  • All tests related to the changed code pass in development

Code review

  • This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached
  • "Ready for review" label attached to the PR and reviewers assigned
  • Issue from task tracker has a link to this pull request
  • Changes have been reviewed by at least one other engineer

@danielmorell
Copy link
Collaborator

Hi @tanakahisateru, thank you for the contributions. bb0e839 looks good to me. I have some questions about 86b4483, though.

I tried to reproduce the behavior you described in your comment. I was not able to get Rollbar to log the just the PHP Warning: parse_str(): Input variables exceeded... warning and not log any user generated error. I tried to do it a couple different ways, but each time Rollbar logged the user generated error. Both the error from parse_str() and the user generated error were logged to stdout. What is the context in which you saw this behavior?

There are a couple things about using the @ operator that are worth mentioning. First, I generally try to avoid it. I usually like to know about errors. Using @ can suppress more errors than intended and that should be reported. Additionally, @ does not change the behavior of a custom error handler set with set_error_handler(). This means using @ will not cause an error to be suppressed by Rollbar.

Because of these two factors, I don't think merging 86b4483 would be wise or produce the results you are looking for. What are your thoughts?

@danielmorell
Copy link
Collaborator

I just read #565, which adds a little more context about your thought process. Can you think of a scenario where we would have an error generated from parse_str() inside the Rollbar SDK that would not be generated elsewhere as well?

@tanakahisateru
Copy link
Contributor Author

Thanks @danielmorell . I actually experienced that no original errors reported while 100+ of parse_str() warnings.

function badTypeFunction(string $str): string
{
    return preg_replace(..., $str, ...); // returns null when internal error occurred.
}

We got a massive data violation to this function like below:

ด็็็็็็็็็็็็็... (more than 1000 strange pattern)

@tanakahisateru
Copy link
Contributor Author

tanakahisateru commented Apr 26, 2022

I think that PHP native functions don't have proper error handling. For example, fopen() and fclose() should be used with @ and return value for unexpected IO error. Though ignoring items after 1001 is bad idea, parse_str() never do so correctly even if using without @. This is not general better practice but special case for this PHP behavior. (This is just my opinion. It's OK that someone else don't think same.)

@tanakahisateru
Copy link
Contributor Author

tanakahisateru commented Apr 26, 2022

My another idea is like below:

final class Utilities
{
    public static function saferParseStr($string)
    {
        try {
            parse_str($string, $result);
        } catch (\Throwable) {
            @parse_str($string, $result);
            $result = array_merge($result, ["...more than max_input_vars items"]);
        }
        return $result;
    }
}

To see \Symfony\Component\Filesystem\Filesystem::copy(), they are avoiding suddenly crash by PHP native function.

        if ($doCopy) {
            // https://bugs.php.net/64634
            if (!$source = self::box('fopen', $originFile, 'r')) {
                throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile);
            }

Copy link
Collaborator

@danielmorell danielmorell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long term it would be nice to avoid running every string through parse_str(), but that would take some rethinking of how we handle inputs.

I think this is a good solution for our current problem. Thank you @tanakahisateru!

@danielmorell danielmorell merged commit 786ae24 into rollbar:master May 12, 2022
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

Successfully merging this pull request may close these issues.

None yet

2 participants