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 330 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

      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
      • JonathanLeeJ
        JonathanLee
        last edited by JonathanLee

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

        Make sure to upvote

        F 1 Reply Last reply Reply Quote 0
        • F
          foxhnd @JonathanLee
          last edited by

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

          JonathanLeeJ 1 Reply Last reply Reply Quote 0
          • JonathanLeeJ
            JonathanLee @foxhnd
            last edited by

            @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 Reply Quote 1
            • F
              foxhnd @JonathanLee
              last edited by foxhnd

              @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

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

                JonathanLeeJ 1 Reply Last reply Reply Quote 1
                • JonathanLeeJ
                  JonathanLee @foxhnd
                  last edited by JonathanLee

                  @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 Reply Quote 1
                  • F
                    foxhnd @JonathanLee
                    last edited by

                    @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.

                    JonathanLeeJ 1 Reply Last reply Reply Quote 1
                    • JonathanLeeJ
                      JonathanLee @foxhnd
                      last edited by

                      @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
                      • First post
                        Last post
                      Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.