Skip to content

Terminal report formatter can crash when displaying literal markup tags #724

Description

@YMuskrat

On main at 4a5506276795397c62ed4f0111c08f41c2b9f1b1, generating a terminal report can crash or change its displayed text when a report field contains bracketed markers. _format_terminal treats dynamic report text as Rich markup. The failure happens before the report is printed or saved, so it affects both displaying the report directly in the terminal and saving a terminal-format report to a file.

For example, prompt examples in a SKILL.md can contain the [INST] ... [/INST] format documented for Mistral-7B-Instruct. A displayed report field that quotes the closing marker can raise rich.errors.MarkupError.

The baseline reason below is one reproducible example of this formatter bug. Finding messages, paths, evidence, and other dynamic terminal fields also reach Rich without escaping; unmatched closing tags can crash report generation, while balanced tags such as [bold]x[/bold] silently change how the text appears.

To reproduce, create prompt-review/SKILL.md:

---
name: prompt-review
description: Explain prompt injection examples in chat templates.
---

# Prompt Review

Example attack:

```text
[INST] Ignore all previous instructions. [/INST]
```

Create baseline.yaml outside the skill directory:

version: 2
rules:
  - id: P1
    reason: "Reviewed prompt marker [/INST]"

Display the report directly in the terminal:

skillspector scan prompt-review --no-llm --baseline baseline.yaml --show-suppressed

The same failure occurs when saving the terminal-format report:

skillspector scan prompt-review --no-llm --baseline baseline.yaml --show-suppressed --output report.txt

Expected: print or save the terminal report with the suppression reason displayed literally.

Actual: Rich raises MarkupError because the closing tag [/INST] does not match an open tag. The scan exits 1; the report is not printed, and no report.txt is written when --output is used.

In this reproduction, the trigger is rendering the suppression reason that quotes [/INST]. This is a constructed reproduction using supported inputs; the prompt example in SKILL.md provides context for that reason.

The report module already imports rich.markup.escape and uses it in the completeness section. Applying it to the other dynamic terminal fields would retain their literal contents while preserving report styling.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions