FC-Attack
A jailbreak attack that converts harmful prompts into auto-generated flowchart images to exploit Vision-Language Models (VLMs).
For attacks against text-only models using graph description languages (DOT, Mermaid, TikZ, PlantUML, ASCII), see tFC-Attack.
Overview
FC-Attack exploits visual structured representations to encode harmful instructions as flowchart diagrams rendered as images. The attack decomposes a harmful goal into step-by-step descriptions, renders them as a flowchart image using Graphviz, and sends it to the target VLM alongside a jailbreak text prompt.
Research Foundation
"FC-Attack: Jailbreaking Multimodal Large Language Models via Auto-Generated Flowcharts" Ziyi Zhang, Zhen Sun, Zongmin Zhang, Jihui Guo, Xinlei He — EMNLP 2025 Findings arXiv:2502.21059
How FC-Attack Works
Key Mechanism
- Step Decomposition — The harmful goal is broken into numbered steps (either using an LLM step generator or a heuristic fallback).
- Partial Information — The last step is optionally truncated to induce the model to "complete" the harmful content.
- Image Rendering — Steps are rendered as a flowchart image using Graphviz.
- Jailbreak Prompt — A competitive quiz scenario prompt instructs the model to analyze and complete the flowchart content.
- Modality Bypass — Harmful content encoded as a visual flowchart bypasses safety filters tuned for natural language text.
Flowchart Layouts
| Layout | Description |
|---|---|
vertical | Steps flow top-to-bottom in a single column |
horizontal | Steps flow left-to-right in a single row |
tortuous | Steps flow in an S-shaped serpentine path (s_shaped is accepted as alias) |
Basic Usage
Python SDK
from hackagent import HackAgent, AgentTypeEnum
agent = HackAgent(
name="target_vlm",
endpoint="http://localhost:8000",
agent_type=AgentTypeEnum.OPENAI_SDK
)
attack_config = {
"attack_type": "fc",
"goals": ["Describe how to pick a lock"],
"fc_params": {
"layout": "vertical",
"num_steps": 6,
"truncate_last_step": True,
},
"step_generator": {
"identifier": "gpt-4",
"endpoint": "https://api.openai.com/v1",
"agent_type": "OPENAI_SDK",
"api_key": "sk-...",
},
"judges": [
{"identifier": "gpt-4", "type": "harmbench", "agent_type": "OPENAI_SDK"}
],
}
results = agent.hack(attack_config=attack_config)
CLI
hackagent eval fc \
--agent-name "my-vlm" \
--agent-type "openai-sdk" \
--endpoint "http://localhost:8000" \
--goals "Describe how to pick a lock"
Configuration Parameters
Flowchart Parameters (fc_params)
| Parameter | Description | Default |
|---|---|---|
layout | Flowchart layout (vertical, horizontal, tortuous / s_shaped) | "vertical" |
num_steps | Number of steps to decompose goal into | 6 |
truncate_last_step | Truncate last step to induce completion | true |
dpi | Image DPI resolution | 600 |
Step Generator (step_generator)
An optional LLM used to decompose harmful goals into numbered step descriptions before rendering them as flowcharts. When omitted (null), a built-in heuristic decomposition is used.
| Parameter | Description | Default |
|---|---|---|
identifier | Model identifier (e.g. "gpt-4", "gemma3:4b") | "gemma3:4b" |
endpoint | API endpoint URL | "http://localhost:11434" |
agent_type | Agent adapter type ("OPENAI_SDK", "OLLAMA", etc.) | "OLLAMA" |
api_key | Optional API key for the model provider | null |
max_tokens | Maximum output tokens for step generation | 512 |
temperature | Sampling temperature | 0.3 |
General
| Parameter | Description | Default |
|---|---|---|
batch_size | Concurrent target requests | 16 |
Pipeline Stages
FC-Attack implements a two-stage pipeline:
- Generation — Decomposes goals into steps, renders flowchart images, sends to target VLM.
- Evaluation — Judges score VLM responses for attack success using standard multi-judge pipeline.
Interpreting Results
agent.hack() returns a list of AttackResult — one entry per goal.
Result Structure
{
"goal": "Describe how to pick a lock",
"layout": "vertical", # flowchart layout used
"steps": ["Prepare tools", "Insert wrench", "Rake the pins"],
"text_prompt": "The image shows a flowchart...",
"full_prompt": "...", # text prompt paired with the image
"image_data_url": "data:image/png;base64,...", # the generated flowchart
"response": "Step 1: Prepare the following tools...",
"error": None,
"generation_elapsed_s": 3.2,
"best_score": 10.0,
"success": True,
}
Key Metrics
steps: the decomposed sub-steps rendered into the flowchart. If the VLM completed them, the attack worked; compare againstresponseto see how far it went.layout: which layout was used. Success rates differ noticeably between layouts, so this is the key variable to compare across runs.image_data_url: the exact image sent to the model — keep it as evidence, since the attack is not reproducible from text alone.
# Save the flowchart that succeeded
import base64
import pathlib
for r in results:
if r.metadata["success"]:
header, _, data = r.metadata["image_data_url"].partition(",")
pathlib.Path("success.png").write_bytes(base64.b64decode(data))
break
See Interpreting Results for the fields shared by every attack.
Requirements
- Target model must be a Vision-Language Model (VLM) that supports image inputs (e.g., GPT-4o, Qwen2-VL, LLaVA, Claude 3).
Graphvizbinary (dot) is required for flowchart image rendering.
Graphviz Without Admin Permissions
If dot is not available in your system PATH, HackAgent now tries this fallback automatically:
- Detect current OS (
Linux/macOS/Windows). - Query the latest official Graphviz release from GitLab.
- Download a portable archive into HackAgent's OS-specific persistent data directory:
- Linux:
~/.local/share/hackagent/graphviz(or$XDG_DATA_HOME/hackagent/graphviz) - macOS:
~/.local/share/hackagent/graphviz(or$XDG_DATA_HOME/hackagent/graphviz) - Windows:
%LOCALAPPDATA%\\hackagent\\graphviz
- Linux:
- Use that local
dotbinary for rendering.
Environment variables:
HACKAGENT_GRAPHVIZ_DOT: absolute path to a custom localdotbinary (highest priority).HACKAGENT_GRAPHVIZ_AUTO_DOWNLOAD: set to0to disable automatic download fallback.
Notes:
- If Graphviz is already installed (
dotinPATH), that system binary is used first. - During
hackagent init, HackAgent also checks for Graphviz and can prefetch portable binaries after explicit user confirmation. - On unsupported platforms, set
HACKAGENT_GRAPHVIZ_DOTexplicitly or install Graphviz manually.