/ Модель

Характеристики

Контекст
8 192 токена
Параметры
149 млн
Лицензия
Apache 2.0
Архитектура
modernbert · dense
Базовая модель
ModernBERT-base
Опубликована
8 сен 2026

IronJean-1.0-ModernBERT-WAF

Классификация текстаТекст → label4 профессии

Классификатор на базе ModernBERT для определения безопасных и вредоносных HTTP-запросов в веб-приложениях и API.

470скачиваний за 30 дней1лайквеса обновлены13 сен 2026

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

Iron Jean WAF — англоязычный классификатор HTTP-запросов, разработанный Franck ANDRIANO для обнаружения вредоносных payload в веб-трафике. Модель дообучена на ModernBERT-base и классифицирует запросы как безопасные или атакующие; она предназначена для inline-фильтрации на API-шлюзах и в серверных приложениях, в том числе для выявления SQL-инъекций, XSS и Path Traversal.

Модель содержит 149 млн параметров, использует архитектуру ModernBERT и поддерживает контекст до 8192 токенов. Для работы запрос нужно представить в заданной разметке с полями METHOD, URI, HEADERS и, при наличии, BODY; сырые сетевые байты не подходят. В репозитории доступны веса safetensors и варианты ONNX, включая INT8 для CPU и FP16 для GPU. Автор сообщает об оценке на наборе из 84 221 HTTP-запроса, однако описанное внесение шума и инверсия меток в обучающие данные затрудняют интерпретацию приведённых метрик.

Модель рассчитана на HTTP-трафик в форматах JSON, XML и URL-encoded и не предназначена для общих языковых задач. Лицензия — Apache-2.0.

Сценарии применения

  • фильтрация HTTP-запросов на API-шлюзе
  • обнаружение SQL-инъекций в веб-трафике
  • выявление XSS-payload в запросах
  • обнаружение Path Traversal
  • классификация запросов как безопасных или атакующих

Ограничения

Для корректной классификации запрос необходимо передавать в ожидаемом формате METHOD, URI, HEADERS и BODY; сырые сетевые данные не поддерживаются. Модель специализирована на HTTP-трафике и не подходит для общих языковых задач; автор сообщает о внесении шума и инверсии меток в обучающие данные, поэтому заявленные метрики требуют осторожной интерпретации.

Для каких профессий подходит4

Разделы каталога профессий, в задачах которых используется эта модель

Все профессии

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

Iron Jean WAF v1.0

Model Description

Iron Jean WAF (ModernBERT-base) is a high-performance Web Application Firewall filter fine-tuned for detecting malicious HTTP payloads. Built on top of ModernBERT-base, it leverages a massive 8192-token context window to analyze entire HTTP headers and bodies without truncation, effectively preventing obfuscated attacks (SQLi, XSS, Path Traversal) that bypass traditional regex-based filters.

Intended Uses & Limitations

  • Primary Use Case: Inline HTTP payload classification (Safe vs. Attack) for API Gateways and backend services.
  • Supported Architectures: Ready for Python (transformers) and highly optimized for Java/C++ backends via ONNX Runtime (INT8 quantized).
  • Limitations: This model is designed for HTTP traffic (JSON, XML, URL-encoded data). It is not intended for general sentiment analysis or natural language tasks.

Training Data

The model was trained on a highly curated, proprietary dataset consisting of 84,221 unique HTTP requests.

  • Safe Traffic (Class 0): 45,951 requests (54.5%)
  • Attack Traffic (Class 1): 38,270 requests (45.5%)

The raw dataset is released separately under a permissive data license for community review.

Evaluation & Metrics

The model achieves production-grade metrics, heavily optimized to minimize False Positives (legitimate traffic being blocked).

  • Global Accuracy: 98.45%
  • Precision (Attack): 98.09% (Extremely low false positive rate)
  • Recall (Attack): 97.84%
  • Latency (PyTorch): ~7.9 ms/request (Batch size 1, RTX GPU).
  • Latency (ONNX INT8): < 2 ms/request (Targeted for Java backend).

⚠️ Note on Dataset Entropy & Noise Injection

The apparent errors in this matrix (692 False Negatives and 609 False Positives) are not standard model failures. They are the direct result of deliberate Noise Injection (label inversion/chaos) introduced into the training dataset.

In complex systems, a perfectly sterile dataset creates a fragile, dogmatic model prone to overfitting. By injecting controlled entropy, the model was forced to develop a much deeper, structural understanding of malicious payloads rather than relying on simple keyword memorization. This adversarial training ensures maximum resilience and nuanced decision-making in unpredictable production environments.

Model Input Format (Semantic Layout)

To achieve optimal accuracy and prevent "Out-of-Distribution" uncertainty (probabilities hovering around ~50%), the input payload must be strictly formatted to match the training dataset.

The model expects a specific semantic tagging layout. Do not send raw HTTP network bytes.

Required Tags:

  • METHOD: The HTTP verb (GET, POST, PUT, etc.)
  • URI: The requested path and query string.
  • HEADERS: Relevant security headers (one per line).
  • BODY: (Optional) The request body, ideally minified or flattened (a mandatory empty line before BODY).

Examples

Safe Traffic

METHOD: POST
URI: /oauth/token
HEADERS:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Host: docs-api.nexus
X-Request-ID: 8763

BODY:
grant_type=password&client_id=gan&client_secret=4qs6d81q2sdsj&scope=user.public

How to Use (Code Snippets)

import os
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModelForSequenceClassification

# Define the local model path
model_id = "Metabaron6/IronJean-1.0-ModernBERT-WAF"
print(f"Loading local model from: {model_id}")

# GPU (CUDA) ou CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Load the model and tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(
    model_id,
    dtype=torch.bfloat16,
    attn_implementation="sdpa"
).to(device)

def test_payload(payload_text):
    # Tokenize the input payload
    inputs = tokenizer(payload_text, return_tensors="pt", truncation=True, max_length=8192).to(device)

    # Run inference and extract probabilities
    with torch.no_grad():
        logits = model(**inputs).logits

        # Apply Softmax to get percentages (0.0 to 1.0)
        probabilities = F.softmax(logits, dim=-1)

        # Extract the probability for class 1 (Attack)
        attack_prob = probabilities[0][1].item()

    # Apply our production threshold (85%)
    is_attack = attack_prob >= 0.85

    print("-" * 50)
    print(f"Payload:\n{payload_text.strip()}")
    print(f"Attack Probability: {attack_prob * 100:.2f}%")
    print("Decision: 🚨 ATTACK BLOCKED" if is_attack else "Decision: ✅ SAFE TRAFFIC ALLOWED")

payload_bare= """METHOD: GET
URI: /api/v1/users?id=1' OR '1'='1
HEADERS:
Host: api.domain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json"""

payload_bare2 = """METHOD: POST
URI: /api/v1/users
HEADERS:
Host: api.domain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json

BODY:
{\"data1\": \"<a href='java+script:alert(1)'>click me</a>\",\"data2\": \"hello\"}"""

payload_full = """METHOD: POST
URI: /api/v1/users?param1=hello
HEADERS:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Host: api.domain.com
X-Request-ID: 25112

BODY:
{\"data1\": \"name\",\"data2\": \"hello\"}"""

payload_safe = """METHOD: POST
URI: /oauth/token
HEADERS:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Host: docs-api.nexus
X-Request-ID: 8763

BODY:
grant_type=password&client_id=gan&client_secret=4qs6d81q2sdsj&scope=user.public"""

payload_safe2 = """METHOD: POST
URI: /blog/wp-login.php?action=register
HEADERS:
Content-Type: application/x-www-form-urlencoded
Content-Length: 93
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Host: test-site.com

BODY:
user_login=humorousLizard8&user_email=foo-bar@example.com&redirect_to=none&wp-submit=Register"""

# Note: Base64 payload attempting to exploit Java deserialization
payload_attack = """METHOD: GET
URI: /api/query?param=eyJAdHlwZSI6ImNvbS5zdW4ucm93c2V0LkpkYmNSb3dTZXRJbXBsIn0=
HEADERS:
X-Nexus-Trace: 54d20f0f-f1c8-4eb5-a1b5-a4adc6c027f5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)"""

payload_attack2 = """METHOD: POST
URI: /api/v1/authenticate
HEADERS:
User-Agent: Mozilla/5.0
Content-Type: application/json

BODY:
{"username": "admin", "password": "' OR '1'='1"}"""


# Execute tests
test_payload(payload_bare)
test_payload(payload_bare2)

test_payload(payload_full)

test_payload(payload_safe)
test_payload(payload_safe2)

test_payload(payload_attack)
test_payload(payload_attack2)

Result:

Loading local model from: Metabaron6/IronJean-1.0-ModernBERT-WAF
Using device: cuda
--------------------------------------------------
Payload:
METHOD: GET
URI: /api/v1/users?id=1' OR '1'='1
HEADERS:
Host: api.domain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Attack Probability: 98.44%
Decision: 🚨 ATTACK BLOCKED
--------------------------------------------------
Payload:
METHOD: POST
URI: /api/v1/users
HEADERS:
Host: api.domain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json

BODY:
{"data1": "<a href='java+script:alert(1)'>click me</a>","data2": "hello"}
Attack Probability: 100.00%
Decision: 🚨 ATTACK BLOCKED
--------------------------------------------------
Payload:
METHOD: POST
URI: /api/v1/users?param1=hello
HEADERS:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Host: api.domain.com
X-Request-ID: 25112

BODY:
{"data1": "name","data2": "hello"}
Attack Probability: 18.26%
Decision: ✅ SAFE TRAFFIC ALLOWED
--------------------------------------------------
Payload:
METHOD: POST
URI: /oauth/token
HEADERS:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Host: docs-api.nexus
X-Request-ID: 8763

BODY:
grant_type=password&client_id=gan&client_secret=4qs6d81q2sdsj&scope=user.public
Attack Probability: 0.00%
Decision: ✅ SAFE TRAFFIC ALLOWED
--------------------------------------------------
Payload:
METHOD: POST
URI: /blog/wp-login.php?action=register
HEADERS:
Content-Type: application/x-www-form-urlencoded
Content-Length: 93
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Host: test-site.com

BODY:
user_login=humorousLizard8&user_email=foo-bar@example.com&redirect_to=none&wp-submit=Register
Attack Probability: 62.11%
Decision: ✅ SAFE TRAFFIC ALLOWED
--------------------------------------------------
Payload:
METHOD: GET
URI: /api/query?param=eyJAdHlwZSI6ImNvbS5zdW4ucm93c2V0LkpkYmNSb3dTZXRJbXBsIn0=
HEADERS:
X-Nexus-Trace: 54d20f0f-f1c8-4eb5-a1b5-a4adc6c027f5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Attack Probability: 100.00%
Decision: 🚨 ATTACK BLOCKED
--------------------------------------------------
Payload:
METHOD: POST
URI: /api/v1/authenticate
HEADERS:
User-Agent: Mozilla/5.0
Content-Type: application/json

BODY:
{"username": "admin", "password": "' OR '1'='1"}
Attack Probability: 100.00%
Decision: 🚨 ATTACK BLOCKED

⚡ Production-Ready ONNX Models Included

This repository directly includes highly optimized ONNX exports of the model, specifically engineered for ultra-low latency inference in enterprise backends (Java, Go, C++, Rust).

You can find the following hardware-specific models in the Files and versions tab:

  • onnx/model.onnx (FP32 Standard): The unquantized, full-precision ONNX export (~599 MB). Ideal for backend environments where memory footprint is not a bottleneck and absolute maximum accuracy is required, or as a base for custom quantization pipelines.
  • model_cpu_int8.onnx (INT8 Quantized): CPU-optimized. Drastically reduces the memory footprint and maximizes throughput. Highly recommended for concurrent web servers and standard containerized environments.
  • model_gpu_fp16.onnx (FP16): GPU-optimized. Designed for CUDA execution providers, delivering millisecond-level latency on dedicated hardware (e.g., NVIDIA RTX / Data Center GPUs).

☕ Java Integration Tip

Anonymize the Payload

Masks classic sessions and authentication tokens to prevent AI sensitivity to private hashes. Uses pre-compiled regex patterns to improve performance compared to String.replaceAll.

// Data Anonymization Patterns 
private static final Pattern PATTERN_COOKIE = Pattern.compile("(?i)(_cfuvid|__cf_bm|sails\\.sid|jsessionid|phpsessid|aspsessionid|xsrf-token|csrf-token|auth)=[^;\\n\\r]+");
private static final Pattern PATTERN_MAC = Pattern.compile("mac=\"[^\"]+\"");
private static final Pattern PATTERN_BOUNDARY = Pattern.compile("(?i)boundary=[a-zA-Z0-9\\-_]+");
private static final Pattern PATTERN_BEARER = Pattern.compile("(?i)Bearer [a-zA-Z0-9\\-_.]+");
private static final Pattern PATTERN_TOKEN = Pattern.compile("(?i)(access_token|refresh_token|id_token|jwt)=[^;\\n\\r]+");
private static final Pattern PATTERN_POSTMAN = Pattern.compile("Postman-Token: [a-zA-Z0-9\\-]+");

// test anonymize
String safePayload = anonymizePayload(payloadToAnalyze);

/**
 *
 * @param payload The original payload 
 * @return The anonymized payload
 */
private String anonymizePayload(String payload) {
    if (payload == null || payload.isEmpty()) return payload;

    String safePayload = PATTERN_COOKIE.matcher(payload).replaceAll("$1=[COOKIE]");
    safePayload = PATTERN_MAC.matcher(safePayload).replaceAll("mac=\"[TOKEN]\"");
    safePayload = PATTERN_BOUNDARY.matcher(safePayload).replaceAll("boundary=[BOUNDARY]");
    safePayload = PATTERN_BEARER.matcher(safePayload).replaceAll("Bearer [JWT]");
    safePayload = PATTERN_TOKEN.matcher(safePayload).replaceAll("$1=[JWT]");
    safePayload = PATTERN_POSTMAN.matcher(safePayload).replaceAll("Postman-Token: [TOKEN]");
    
    return safePayload;
}

☕ Complete Enterprise Java Implementation (ONNX + DJL)

If you are securing a Java backend (such as a Spring Boot API Gateway or Tomcat server), you can seamlessly load these .onnx files using ONNX Runtime and the Deep Java Library (DJL) for tokenization. Remember to cap your intra-op threads to prevent CPU thrashing in highly concurrent environments!

Below is a production-ready, thread-safe Java class that loads the INT8 ONNX model and the Hugging Face tokenizer via the Deep Java Library (DJL). It includes the payload anonymization step and manages C++ off-heap memory safely using try-with-resources.

import ai.djl.huggingface.tokenizers.HuggingFaceTokenizer;
import ai.djl.huggingface.tokenizers.Encoding;
import ai.onnxruntime.OnnxTensor;
import ai.onnxruntime.OrtEnvironment;
import ai.onnxruntime.OrtSession;
import ai.onnxruntime.OrtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.LongBuffer;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class IronJeanWafFilter implements AutoCloseable {

    private static final Logger logger = LoggerFactory.getLogger(IronJeanWafFilter.class);

    private final OrtEnvironment environment;
    private final OrtSession session;
    private final HuggingFaceTokenizer tokenizer;

    // Defines the threshold to classify a payload as an attack (e.g., 85% certainty)
    private static final float ATTACK_THRESHOLD = 0.85f;

    /**
     * Initializes the ONNX environment and the HuggingFace tokenizer.
     *
     * @param modelPath     Path to the INT8 quantized .onnx file
     * @param tokenizerPath Path to the directory containing tokenizer.json
     */
    public IronJeanWafFilter(String modelPath, String tokenizerPath) throws Exception {
        // 1. Initialize ONNX Runtime environment and session
        this.environment = OrtEnvironment.getEnvironment();
        OrtSession.SessionOptions options = new OrtSession.SessionOptions();
        options.setOptimizationLevel(OrtSession.SessionOptions.OptLevel.ALL_OPT);

        // Prevent CPU thread thrashing in a concurrent web server
        options.setIntraOpNumThreads(4); // 4 Threads
        options.setInterOpNumThreads(1);

        this.session = environment.createSession(modelPath, options);

        // 2. Load the ModernBERT tokenizer using DJL
        this.tokenizer = HuggingFaceTokenizer.newInstance(Paths.get(tokenizerPath));
    }

    /**
     * Evaluates an HTTP payload to determine if it is malicious.
     *
     * @param payload The raw HTTP request string (headers, URI, body)
     * @return true if an attack is detected, false if the traffic is safe
     */
    public boolean isMalicious(String payload) {
        long startTime = System.currentTimeMillis();

        try {
            /// 1. Tokenize the input payload
            Encoding encoding = tokenizer.encode(payload);
            long[] inputIds = encoding.getIds();
            long[] attentionMask = encoding.getAttentionMask();

            // Hard cap sequence length to prevent DoS via massive payloads
            int maxLength = Math.min(inputIds.length, 8192);

            long[] truncatedInputIds = new long[maxLength];
            long[] truncatedAttentionMask = new long[maxLength];

            System.arraycopy(inputIds, 0, truncatedInputIds, 0, maxLength);
            System.arraycopy(attentionMask, 0, truncatedAttentionMask, 0, maxLength);

            // 2. Prepare tensors with a safe shape
            long[] shape = new long[]{1, maxLength};

            try (
                    OnnxTensor inputIdsTensor = OnnxTensor.createTensor(environment, LongBuffer.wrap(truncatedInputIds), shape);
                    OnnxTensor attentionMaskTensor = OnnxTensor.createTensor(environment, LongBuffer.wrap(truncatedAttentionMask), shape)
            ) {
                // 3. Map inputs to match the ONNX graph expectations
                Map<String, OnnxTensor> inputs = new HashMap<>();
                inputs.put("input_ids", inputIdsTensor);
                inputs.put("attention_mask", attentionMaskTensor);

                // 4. Run inference
                try (OrtSession.Result result = session.run(inputs)) {
                    // ModernBERT sequence classification outputs a tensor of shape [1, 2]
                    float[][] logits = (float[][]) result.get(0).getValue();

                    // 5. Calculate softmax probabilities
                    float safeLogit = logits[0][0];
                    float attackLogit = logits[0][1];

                    double expSafe = Math.exp(safeLogit);
                    double expAttack = Math.exp(attackLogit);
                    double attackProbability = expAttack / (expSafe + expAttack);

                    if (logger.isDebugEnabled()) {
                        long endTime = System.currentTimeMillis();
                        logger.debug("WAF Analysis Execution Time (Prob {}): {} ms",
                                String.format("%.2f", attackProbability * 100), (endTime - startTime));
                    }
                    // 6. Apply threshold logic
                    return attackProbability >= ATTACK_THRESHOLD;
                }
            }
        } catch (Exception e) {
            // In case of an unexpected error, log it and fail-open or fail-close based on security policy
            System.err.println("WAF Inference Error: " + e.getMessage());
            return false;
        }
    }

    @Override
    public void close() throws OrtException {
        // Safely release C++ memory allocated by ONNX Runtime
        if (session != null) session.close();
        if (environment != null) environment.close();
        if (tokenizer != null) tokenizer.close();
    }
}

Author

Franck ANDRIANO.

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм · text-classification

Можно запустить

Подбираем GPU…

Класс архитектуры
ModernBertForSequenceClassification
Ревизия весов
05bc713

0 моделей