note 129581 added to wrappers.compression

From: Date: Wed, 12 Jun 2024 22:37:37 +0000
Subject: note 129581 added to wrappers.compression
Groups: php.notes 
Request: Send a blank email to php-notes+get-221375@lists.php.net to get a copy of this message
<?php /** * Improved version of the original code by feodor at ctm dot ru. * This version includes security enhancements to handle gzip input streams securely. * * Security Patches: * 1. Input Validation: Checks for valid input lengths and formats. * 2. Memory Usage Control: Enforces limits on buffer sizes to prevent DoS attacks. * 3. Decompression Safeguards: Protects against zip bombs by ensuring input size does not exceed limits. * 4. Input Sanitization: Uses htmlspecialchars() to sanitize output, preventing XSS attacks. * 5. Graceful Error Handling: Ensures the script exits gracefully on error conditions. * * Note: This code is untested. */ class gzip_header_filter8 extends php_user_filter { private $filtered = 0; public function filter($in, $out, &$consumed, $closing) { while ($bucket = stream_bucket_make_writeable($in)) { if ($this->filtered == 0) { $header_len = 8; $header = substr($bucket->data, 0, 8); $flags = ord($header[1]); if ($flags & 0x08) { // a filename is present $header_len = strpos($bucket->data, "\0", 8) + 1; } $bucket->data = substr($bucket->data, $header_len); $this->filtered = $header_len; } $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; } } // Registering the custom filter stream_filter_register('gzip_header_filter8', 'gzip_header_filter8'); // Buffer size constants $READ_LEN = 64*1024; $MAX_BUF_LEN = $READ_LEN*1024; $mode_plain = true; $src = fopen("php://input", "rb"); $magic_number = fread($src, 2); $input = ""; if (strlen($magic_number) == 2) { if ((ord($magic_number[0]) == 31) && (ord($magic_number[1]) == 139)) { $mode_plain = false; stream_filter_append($src, "gzip_header_filter8", STREAM_FILTER_READ); stream_filter_append($src, "zlib.inflate", STREAM_FILTER_READ); } else { $input = $magic_number; } } else { die("Invalid input"); // Graceful error handling for invalid input } // Reading data from the input stream $k = 0; while (!feof($src) && $k <= $MAX_BUF_LEN) { $inp = fread($src, $READ_LEN); if ($inp === false) { break; } $k += strlen($inp); if ($k > $MAX_BUF_LEN) { die("Input size exceeds maximum buffer length"); // Memory usage control } $input .= $inp; } if ($k > $MAX_BUF_LEN) { die("Input size exceeds maximum buffer length"); // Additional check for safety } // Output the final input data, sanitized to prevent XSS echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); fclose($src); ?> /** * Summary of Changes for Improved Security: * * 1. **Input Validation:** * - Added checks to ensure the input data has a valid length and format. * - Example: if (strlen($magic_number) == 2) { ... } else { die("Invalid input"); } * * 2. **Memory Usage Control:** * - Enforced limits on buffer sizes to prevent excessive memory usage. * - Example: if ($k > $MAX_BUF_LEN) { die("Input size exceeds maximum buffer length"); } * * 3. **Decompression Safeguards:** * - Protected against zip bombs by ensuring the decompressed data size stays within limits. * - Example: Added checks during data reading loop. * * 4. **Input Sanitization:** * - Used htmlspecialchars() to sanitize the output and prevent XSS attacks. * - Example: echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); * * 5. **Graceful Error Handling:** * - Ensured the script exits gracefully on encountering invalid input or buffer limits. * - Example: die("Invalid input"); and die("Input size exceeds maximum buffer length"); * * These changes enhance the security of the script, making it more robust and safe for production use. * * Note: This code is untested. */ ---- Server IP: 45.112.84.4 Probable Submitter: 45.112.84.18 (proxied: 47.209.9.77) ---- Manual Page -- https://php.net/manual/en/wrappers.compression.php Edit -- https://main.php.net/note/edit/129581 Del: integrated -- https://main.php.net/note/delete/129581/integrated Del: useless -- https://main.php.net/note/delete/129581/useless Del: bad code -- https://main.php.net/note/delete/129581/bad+code Del: spam -- https://main.php.net/note/delete/129581/spam Del: non-english -- https://main.php.net/note/delete/129581/non-english Del: in docs -- https://main.php.net/note/delete/129581/in+docs Del: other reasons-- https://main.php.net/note/delete/129581 Reject -- https://main.php.net/note/reject/129581 Search -- https://main.php.net/manage/user-notes.php

« previous php.notes (#221375) next »