**Tipo:** Negação de serviço de complexidade Algorítmica. Uma execução de pares fechados de N `~~x~~~~~x~~...` (ou o análogo `==x==` para `mark`, `^^^x^^` para `inser') causa trabalho de O(N2) no analisador de formatação. Com o plugin `strikethrough`, `mark` ou `inser' ativado, um 8 KB insere o CPU para ~ 4 segundos; 16 KB → ~ 17 segundos. **Arquivo:** `src/mistune/plugins/formatting.py`, linhas 13 - 15 (os padrões `_ STRIKE_END` / `_MARK_END` / `_INSERT_END` e sua varredura por posição). ** Causa da rota:** para cada abertura `~~`/`==`/ `^^`, o analisador varre para a frente para o padrão fechado correspondente. O scan em si usa um regex limitado, mas o analisador tenta o close- scan em cada posição inicial potencial. Para entrada em formato de `~~x~~` repetido N vezes, cada `~~` é examinado como um possível início, cada digitalização cobre até o fim da entrada. O trabalho total é O(N2). A configuração padrão sem estes plug-ins manipula a mesma entrada em tempo linear ( 4 ms para 4000 reps), confirmando que o custo está na digitalização por marcador do plug- in de formatação, não na análise do núcleo. **Arquivo:** `src/mistune/plugins/formatting.py`, linhas 12 - 16.
```python _STRIKE_END = re. compile(r"(::" + PREVENT_ BACKSLASH + r"\\~.~[^\s~])~~(?!~)") _MARK_END = re.compile(r"(:" + PREVENT_ BACKSLASH + r"\=.}(?!=)") _INSERT_END = re.compile(r"(:" + PREVENT_ BACKSLASH + r"\\\^. ^\s^])\^\(?\^)") # Cada padrão é escaneado para a frente a partir de cada posição inicial disparada pela regra # correspondente à linha. O próprio padrão final está limitado; o custo # vem do analisador circundante invocando a varredura em cada '~~' / ''== ' / '^^' # na entrada, dando N inicia × O(N) por varredura = O(N^ 2 ) total. ``` **Por que está errado:** a mesma classe de falhas de complexidade algorítmica como `[` / `[a` analisando no núcleo: um loop de reexperimentação por token sem memoização de posições falhadas. Cada marcador de formatação é tentado tanto como um início potencial como como uma continuação. Um algoritmo de delimitador- amontoador de passe linear (comparando como `commonmark-py` e `markdown-it-py` ênfase de manuseio) fariam este trabalho no total de O(N). O regex limitado em cada digitalização individual não liga a repetição do nível de parser.
1. O aplicativo usa mistune para renderizar o marcador fornecido pelo usuário e tem qualquer um dos plug- ins para formatação ativado (`plugins=['strikethrough']`, `['mark']`, `['inser']`, ou qualquer super- configuração). Estes plug- ins são normalmente ativados porque a compatibilidade GitHub- flavoured-Markdown requer `~~strikethrough~~` e muitos editores emitem `== destaque ==` e `^^underline^^` atalhos. 2. O atacante submete um 8 Carga útil de marcação de KB do formulário `~~x~~~~~~~~~~~~~\...` ( 40 000 caracteres de `~~x~~` repetidos 8000 vezes, ou a forma análoga com `==` / `^^`). 3. O servidor chama `mistune.create_markdown(plugins=['strikethrough'])(payload)`. PICS CPU para ~ 4 segundos; 16 KB → ~ 17 segundos; 32 KB → ~ 70 segundos. Custo CPU puro, sem crescimento significativo da memória. 4. Repetir o pedido inunda a piscina de trabalhadores. Em um manipulador WSGI de um único fio, este é um pedido por interrupção; em um grupo de thread, um pequeno número de atacantes concorrentes exausce a capacidade. **Severidade:** sec- alto. Alcançable em rede, sem autenticação, escala previsível, primitivo de uma única carga útil. Só requer um lavatório de marcação fornecido pelo usuário e um plug- in de formatação habilitado — ambos são comuns. **Capabilidade de ataque:** pequeno input → grande CPU. Duplar o tamanho de entrada quadrúplica o tempo da CPU. Os pedidos sustentados negam o serviço a outros usuários. **Precondições:** o aplicativo usa mistune com qualquer um dos plugins `strikethrough', `mark' ou `inser' ativados. A configuração padrão NÃO habilita estes (por isso o ataque só dispara contra a população substancialmente implantada que os liga para a compatibilidade GFM/markdown- extra). **Diferencial:** PoC- verificado contra mistune@ 3.2.1:.
```python import mistune, time md = mistune.create_markdown(plugins=['strikethrough']) para n em [ 500, 1000, 2000, 4000, 8000 ]: s = '~~x~~' * n t = tempo.time() md(s) print(f' ~~x~~ * {n} ({len(s)}b): {(time.time() - t) * 1000:. 0 f} ms') # Saída (Python 3.13, Linux, 2.5 CPU GHz: # ~~x~~ * 500 ( 2500 b): 19 ms # ~~x~~ * 1000 ( 5000 b): 71 ms # ~~x~~ * 2000 ( 10000 b): 272 ms # ~~x~~ * 4000 ( 20000 b): 1090 ms # ~~x~~ * 8000 ( 40000 b): 4302 ms.
# Escalamento idêntico para `==x==` (marca) e `^^^x^^` (inserir): md = mistune.create_markdown(plugins=['marca']) md('==x======* 4000 ) # ~ 1100 ms md = mistune.create_markdown(plugins=['inser']) md('^^^x^^' * 4000 ) # ~ 1080 ms # Sem o plug- in, os mesmos pares de entrada em tempo linear: md = mistune.create_markdown() # sem plug- in md('~~x~~' * 4000 ) # 4 ms ( 1000 x mais rápido) ```.
A compilação correcionada (com a correção sugerida abaixo — quer uma reescrição do delimitador- atalho, quer um cap duro no número de marcadores não pareados rastreados) mantém o tempo linear em N. A correção mínima é a de capear o número de marcadores sem igual, tratados simultaneamente como texto literal. A correção correta é um algoritmo de delimitador- amontoador de um único passe que corresponde à implementação da referência CommonMark. Patch cirúrgico:.
```diff --- a/src/mistune/plugins/formatting.py +++ b/src/mistune/plugins/formatting.py @@... na parse_strikethrough / parse_mark / parse_insert funções + # Ajuste o número de marcadores abertos que o analisador irá rastrear simultaneamente. + # Inputs com mais deste muitos abertos ~~ / == / ^^ no voo são + # quase certamente adversários; CommonMark não dá semânticas a + # marcadores profundamente aninhados. + MAX_OPEN_MARKERS = 100 + se open_marker_count > MAX_OPEN_MARKERS: + # tratar os marcadores restantes como texto literal, não invoque o + # para a frente-scane para encontrar um fechamento +... ``` Um teste de regressão deve afirmar que ` md('~~x~~' * 50 _ 000 )` completa em abaixo 1 Segundo. A mesma forma de correção se aplica a `_MARK_END` e `_INSERT_END`.
Registro de aconselhamento: GHSA- c 8 j 7 - 8 cv 4 - 2 xmq. Identificadores relacionados: CVE- 2026 - 59922. Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 20 T 21: 34: 37.000 Z e lista a sua última modificação como 2026 - 07 - 20 T 21: 34: 37.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: mistune do pacote PyPI — ECOSYSTEM: introduzido 0, corrigido 3.3.0.
Classificação e evidência: identificadores de fraqueza CWE- 1333, CWE- 407. O registro contém 6 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.