• Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login
Netgate Discussion Forum
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login

PHP fatal error related to output buffering in the csrf-magic.php file

Scheduled Pinned Locked Moved webGUI
9 Posts 2 Posters 328 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F
    foxhnd
    last edited by foxhnd Jun 30, 2024, 10:49 PM Jun 30, 2024, 10:33 PM

    Received this error from pfsense.

    Crash report begins. Anonymous machine information:

    amd64
    14.0-CURRENT
    FreeBSD 14.0-CURRENT amd64 1400094 #1 RELENG_2_7_2-n255948-8d2b56da39c: Wed Dec 6 20:45:47 UTC 2023 root@freebsd:/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/obj/amd64/StdASW5b/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/sources/F

    Crash report details:

    PHP Errors:
    [30-Jun-2024 15:45:11 US/Mountain] PHP Fatal error: str_ireplace(): Cannot use output buffering in output buffering display handlers in /usr/local/www/csrf/csrf-magic.php on line 165
    [30-Jun-2024 16:05:27 US/Mountain] PHP Fatal error: str_ireplace(): Cannot use output buffering in output buffering display handlers in /usr/local/www/csrf/csrf-magic.php on line 165

    No FreeBSD crash data found.


    Has anyone else seen this issue? ChatGPT 4o suggests the following.

    Replace str_ireplace with preg_replace: To resolve this issue, we should ensure no output buffering functions like str_ireplace are used directly within the output buffer handler. This change ensures that output buffering functions are not nested within the output buffer handler, which prevents conflicts and errors.

    Original Function:

    function csrf_ob_handler($buffer, $flags) {
    static $is_html = false;
    if (!$is_html) {
    if (stripos($buffer, '<html') !== false) {
    $is_html = true;
    } else {
    return $buffer;
    }
    }
    $tokens = csrf_get_tokens();
    $name = $GLOBALS['csrf']['input-name'];
    $endslash = $GLOBALS['csrf']['xhtml'] ? ' /' : '';
    $input = "<input type='hidden' name='$name' value="$tokens"$endslash>";
    $buffer = preg_replace('#(<form[^>]method\s=\s*["']post["'][^>]*>)#i', '$1' . $input, $buffer);

    if ($GLOBALS['csrf']['frame-breaker']) {
        $buffer = str_ireplace('</head>', '<script type="text/javascript">if (top != self) {top.location.href = self.location.href;}</script></head>', $buffer);
    }
    
    if ($js = $GLOBALS['csrf']['rewrite-js']) {
        $buffer = str_ireplace(
            '</head>',
            '<script type="text/javascript">'.
                'var csrfMagicToken = "'.$tokens.'";'.
                'var csrfMagicName = "'.$name.'";</script>'.
            '<script src="'.$js.'" type="text/javascript"></script></head>',
            $buffer
        );
        $script = '<script type="text/javascript">CsrfMagic.end();</script>';
        $buffer = str_ireplace('</body>', $script . '</body>', $buffer, $count);
        if (!$count) {
            $buffer .= $script;
        }
    }
    return $buffer;
    

    }

    Refactored Function:

    function csrf_ob_handler($buffer, $flags) {
    static $is_html = false;
    if (!$is_html) {
    if (stripos($buffer, '<html') !== false) {
    $is_html = true;
    } else {
    return $buffer;
    }
    }
    $tokens = csrf_get_tokens();
    $name = $GLOBALS['csrf']['input-name'];
    $endslash = $GLOBALS['csrf']['xhtml'] ? ' /' : '';
    $input = "<input type='hidden' name='$name' value="$tokens"$endslash>";
    $buffer = preg_replace('#(<form[^>]method\s=\s*["']post["'][^>]*>)#i', '$1' . $input, $buffer);

    if ($GLOBALS['csrf']['frame-breaker']) {
        $buffer = preg_replace('#</head>#i', '<script type="text/javascript">if (top != self) {top.location.href = self.location.href;}</script></head>', $buffer);
    }
    
    if ($js = $GLOBALS['csrf']['rewrite-js']) {
        $buffer = preg_replace(
            '#</head>#i',
            '<script type="text/javascript">'.
                'var csrfMagicToken = "'.$tokens.'";'.
                'var csrfMagicName = "'.$name.'";</script>'.
            '<script src="'.$js.'" type="text/javascript"></script></head>',
            $buffer
        );
        $script = '<script type="text/javascript">CsrfMagic.end();</script>';
        if (stripos($buffer, '</body>') !== false) {
            $buffer = str_ireplace('</body>', $script . '</body>', $buffer);
        } else {
            $buffer .= $script;
        }
    }
    return $buffer;
    

    }

    1 Reply Last reply Reply Quote 0
    • J
      JonathanLee
      last edited by JonathanLee Jun 30, 2024, 10:52 PM Jun 30, 2024, 10:52 PM

      Are you using php custom memory limits? They are under advanced options.

      Make sure to upvote

      F 1 Reply Last reply Jun 30, 2024, 11:00 PM Reply Quote 0
      • F
        foxhnd @JonathanLee
        last edited by Jun 30, 2024, 11:00 PM

        @JonathanLee Nothing is set so the default size is 512 MiB.

        J 1 Reply Last reply Jun 30, 2024, 11:01 PM Reply Quote 0
        • J
          JonathanLee @foxhnd
          last edited by Jun 30, 2024, 11:01 PM

          @foxhnd do me a favor increase it to 1GB and see if you want test what you were doing again. How much memory do you have available to access? Keep in mind it would use that php memory when it is needed.

          Make sure to upvote

          F 2 Replies Last reply Jun 30, 2024, 11:07 PM Reply Quote 1
          • F
            foxhnd @JonathanLee
            last edited by foxhnd Jun 30, 2024, 11:09 PM Jun 30, 2024, 11:07 PM

            @JonathanLee I'll try increasing it to 1024 MiB. Plenty of memory, my physical hardware is a Protectli VP2420 with 16GB memory and 4GB swap space. Memory usage usually sits around 6 - 10% normal load on my network. Thank you for the suggestion, I'm still learning this product.

            1 Reply Last reply Reply Quote 1
            • F
              foxhnd @JonathanLee
              last edited by Jul 1, 2024, 12:20 AM

              @JonathanLee Increasing the PHP Settings to 1024 MiB, seems to have resolved my issue. Thank you!

              J 1 Reply Last reply Jul 1, 2024, 3:31 PM Reply Quote 1
              • J
                JonathanLee @foxhnd
                last edited by JonathanLee Jul 1, 2024, 3:31 PM Jul 1, 2024, 3:31 PM

                @foxhnd I think it is designed that way to help stop memory overflow attacks. Example if the memory overflows it just errors out with that buffer error, versus attempting to adapt the stack for accessing more memory, they have a limit built in that simply says nope not on my stack and moves on with firewalling. I see that error sometimes when I attempt to look at very large logs but my system only has 4GB ram and I have my php set to 512mb. The things I would do with 16GBs that’s amazing.

                Glad it fixed it.

                Make sure to upvote

                F 1 Reply Last reply Jul 1, 2024, 7:53 PM Reply Quote 1
                • F
                  foxhnd @JonathanLee
                  last edited by Jul 1, 2024, 7:53 PM

                  @JonathanLee In my case, I was doing something similar. I had two browser tabs open, monitoring Snort alerts on two different LANs to fine-tune Snort. Thanks again.

                  J 1 Reply Last reply Jul 1, 2024, 11:58 PM Reply Quote 1
                  • J
                    JonathanLee @foxhnd
                    last edited by Jul 1, 2024, 11:58 PM

                    @foxhnd that is the same thing I was doing when I got that error too

                    Make sure to upvote

                    1 Reply Last reply Reply Quote 1
                    9 out of 9
                    • First post
                      9/9
                      Last post
                    Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.
                      This community forum collects and processes your personal information.
                      consent.not_received