O que é o OWASP ML Security Top 10?

O OWASP Machine Learning Security Top 10 identifica os riscos de segurança mais significativos específicos de sistemas de machine learning. Diferentemente de software tradicional, sistemas ML são vulneráveis a ataques únicos que visam dados de treinamento, componentes internos do modelo e pipelines de inferência. Este guia abrange ataques adversariais, envenenamento de dados, roubo de modelos, riscos na cadeia de suprimentos e mais  Ecom exemplos práticos de código Python.

1�E�⃣ ML01 - Ataque de Manipulação de Entrada

Critical

Visão Geral

Ataques de manipulação de entrada (ataques adversariais) criam entradas especialmente projetadas para fazer com que modelos ML façam previsões incorretas. Pequenas perturbações, muitas vezes imperceptíveis, em imagens, texto ou outras entradas podem enganar classificadores, burlar sistemas de detecção e evadir filtros de conteúdo. Este é o vetor de ataque mais conhecido específico de ML.

Risco

Exemplos adversariais podem burlar sistemas ML críticos para segurança: percepção de veículos autônomos, detecção de malware, detecção de fraude e moderação de conteúdo. Um atacante pode fazer com que uma placa de pare seja classificada como uma placa de limite de velocidade, ou fazer malware parecer benigno para um antivírus baseado em ML.

Exemplo de Código Vulnerável

Python ❁EBad
import numpy as np
from tensorflow import keras

# Model with no adversarial robustness
model = keras.models.load_model("classifier.h5")

def predict(image):
    # Direct prediction  Eno input validation or preprocessing
    result = model.predict(np.expand_dims(image, axis=0))
    return np.argmax(result)
    # No confidence threshold check
    # No input bounds validation
    # Vulnerable to FGSM, PGD, C&W attacks

Exemplo de Código Seguro

Python ✁EGood
import numpy as np
from tensorflow import keras
from art.defences.preprocessor import SpatialSmoothing
from art.defences.detector.evasion import BinaryInputDetector

# Load adversarially trained model
model = keras.models.load_model("classifier_robust.h5")

# Input preprocessing to remove perturbations
smoother = SpatialSmoothing(window_size=3)
detector = BinaryInputDetector(model)

def predict_secure(image):
    # Validate input bounds
    if image.min() < 0 or image.max() > 1:
        raise ValueError("Input out of expected range")

    # Detect adversarial input
    if detector.detect(image):
        raise ValueError("Adversarial input detected")

    # Apply spatial smoothing defense
    cleaned = smoother(image)[0]
    result = model.predict(np.expand_dims(cleaned, axis=0))

    # Reject low-confidence predictions
    confidence = np.max(result)
    if confidence < 0.85:
        return {"label": "uncertain", "confidence": confidence}
    return {"label": np.argmax(result), "confidence": confidence}

Lista de Verificação de Mitigação

2�E�⃣ ML02 - Ataque de Envenenamento de Dados

Critical

Visão Geral

Ataques de envenenamento de dados injetam amostras maliciosas em conjuntos de dados de treinamento para corromper o comportamento aprendido do modelo. Atacantes podem introduzir backdoors (padrões de gatilho que causam classificações errôneas específicas), deslocar limites de decisão ou degradar a precisão geral do modelo. Isso é especialmente perigoso quando dados de treinamento vêm da internet ou conteúdo gerado por usuários.

Risco

Um modelo envenenado pode se comportar normalmente em entradas limpas, mas classificar incorretamente quando um padrão de gatilho específico está presente. Por exemplo, um classificador de malware com backdoor poderia aprovar qualquer amostra de malware contendo uma sequência de bytes específica. O ataque é furtivo porque a precisão do modelo em dados limpos permanece alta.

Exemplo de Código Vulnerável

Python ❁EBad
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# Training on unvalidated, crowdsourced data
data = pd.read_csv("user_submitted_data.csv")  # No validation!

# No outlier detection or data quality checks
X = data.drop("label", axis=1)
y = data["label"]

model = RandomForestClassifier()
model.fit(X, y)  # Training directly on untrusted data!

# No comparison against clean baseline
# No data provenance tracking

Exemplo de Código Seguro

Python ✁EGood
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier, IsolationForest
from sklearn.model_selection import cross_val_score

# Load data with provenance tracking
data = pd.read_csv("training_data.csv")
data_hash = hashlib.sha256(data.to_csv().encode()).hexdigest()
log.info(f"Training data hash: {data_hash}")

X = data.drop("label", axis=1)
y = data["label"]

# Detect and remove anomalous samples
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outlier_mask = iso_forest.fit_predict(X) == 1
X_clean, y_clean = X[outlier_mask], y[outlier_mask]
log.info(f"Removed {(~outlier_mask).sum()} outliers from {len(X)} samples")

# Train and validate against baseline
model = RandomForestClassifier(random_state=42)
scores = cross_val_score(model, X_clean, y_clean, cv=5)
if scores.mean() < BASELINE_ACCURACY - 0.05:
    raise ValueError("Model accuracy dropped  Epossible data poisoning")

model.fit(X_clean, y_clean)

Lista de Verificação de Mitigação

3�E�⃣ ML03 - Ataque de Inversão de Modelo

High

Visão Geral

Ataques de inversão de modelo reconstroem dados sensíveis de treinamento consultando o modelo e analisando suas saídas. Um atacante pode recuperar informações privadas como rostos, registros médicos ou dados pessoais usados durante o treinamento. Isso é particularmente preocupante para modelos treinados em conjuntos de dados sensíveis (saúde, biometria, dados financeiros).

Risco

Inversão de modelo pode violar regulamentações de privacidade de dados (GDPR, HIPAA) ao expor informações pessoalmente identificáveis de dados de treinamento. Um atacante com acesso à API de um modelo de reconhecimento facial poderia reconstruir rostos de indivíduos no conjunto de treinamento.

Exemplo de Código Vulnerável

Python (API) ❁EBad
from flask import Flask, request, jsonify

app = Flask(__name__)
model = load_model("face_classifier.h5")

@app.route("/predict", methods=["POST"])
def predict():
    image = request.files["image"]
    result = model.predict(preprocess(image))
    # Returns full probability vector  Eenables model inversion!
    return jsonify({
        "probabilities": result.tolist(),  # All class probabilities!
        "prediction": int(np.argmax(result)),
        "confidence": float(np.max(result))
    })
    # No rate limiting, no query logging
    # Unlimited API access for gradient estimation

Exemplo de Código Seguro

Python (API) ✁EGood
from flask import Flask, request, jsonify
from flask_limiter import Limiter
import numpy as np

app = Flask(__name__)
limiter = Limiter(app, default_limits=["100/hour"])
model = load_model("face_classifier_dp.h5")  # Trained with DP

@app.route("/predict", methods=["POST"])
@limiter.limit("100/hour")
def predict():
    image = request.files["image"]
    result = model.predict(preprocess(image))

    # Return only top-1 prediction  Eno probability vector
    prediction = int(np.argmax(result))
    log_query(request.remote_addr, prediction)  # Audit logging

    return jsonify({
        "prediction": prediction
        # No probabilities, no confidence scores
    })

Lista de Verificação de Mitigação

4�E�⃣ ML04 - Ataque de Inferência de Pertencimento

High

Visão Geral

Ataques de inferência de pertencimento determinam se um ponto de dados específico foi usado no conjunto de treinamento do modelo. Ao analisar as pontuações de confiança e o comportamento do modelo em entradas conhecidas vs. desconhecidas, atacantes podem inferir informações privadas de pertencimento. Esta é uma ameaça significativa à privacidade para modelos treinados em dados sensíveis.

Risco

Inferência de pertencimento pode revelar que os dados de um indivíduo específico foram usados para treinamento  Epor exemplo, confirmar que o registro de um paciente estava em um conjunto de dados clínicos, ou que o rosto de uma pessoa foi usado para treinamento de vigilância. Isso viola expectativas de privacidade e potencialmente regulamentações como GDPR.

Exemplo de Código Vulnerável

Python ❁EBad
from sklearn.neural_network import MLPClassifier

# Overfitted model  Ememorizes training data
model = MLPClassifier(
    hidden_layer_sizes=(512, 512, 256),  # Over-parameterized!
    max_iter=1000,
    # No regularization
    # No early stopping
)
model.fit(X_train, y_train)

# Model memorizes training data ↁEmembership inference possible
# Training accuracy: 99.9% vs Test accuracy: 82%
# This gap indicates overfitting = information leakage

def predict_with_confidence(x):
    proba = model.predict_proba([x])[0]
    return {"probabilities": proba.tolist()}  # Leaks membership info!

Exemplo de Código Seguro

Python ✁EGood
from sklearn.neural_network import MLPClassifier
import numpy as np

# Regularized model with early stopping to reduce overfitting
model = MLPClassifier(
    hidden_layer_sizes=(128, 64),
    max_iter=500,
    alpha=0.01,               # L2 regularization
    early_stopping=True,       # Prevents memorization
    validation_fraction=0.15,
)
model.fit(X_train, y_train)

# Verify train/test gap is small (low overfitting)
train_acc = model.score(X_train, y_train)
test_acc = model.score(X_test, y_test)
assert train_acc - test_acc < 0.05, "Overfitting detected!"

def predict_secure(x):
    pred = model.predict([x])[0]
    return {"prediction": int(pred)}  # Label only, no probabilities

Lista de Verificação de Mitigação

5�E�⃣ ML05 - Roubo de Modelo

Critical

Visão Geral

Ataques de roubo de modelo (extração de modelo) criam uma cópia funcional de um modelo ML proprietário consultando-o sistematicamente e treinando um modelo substituto nos pares entrada-saída. O modelo roubado pode então ser usado para encontrar exemplos adversariais, competir comercialmente ou fazer engenharia reversa dos dados de treinamento do modelo.

Risco

Um modelo roubado representa perda de propriedade intelectual e vantagem competitiva. O modelo extraído pode ser usado offline para criar ataques adversariais ou entender limites de decisão. Milhões de dólares de investimento em treinamento podem ser replicados com milhares de consultas à API.

Exemplo de Código Vulnerável

Python (API) ❁EBad
from flask import Flask, request, jsonify

app = Flask(__name__)
model = load_proprietary_model()

@app.route("/predict", methods=["POST"])
def predict():
    data = request.json["features"]
    result = model.predict_proba([data])[0]

    # Returns full probability distribution
    return jsonify({
        "probabilities": result.tolist(),
        "prediction": int(np.argmax(result))
    })
    # No rate limiting  Eunlimited queries
    # No anomaly detection on query patterns
    # Attacker can extract model with ~10K queries

Exemplo de Código Seguro

Python (API) ✁EGood
from flask import Flask, request, jsonify
from flask_limiter import Limiter
import numpy as np

app = Flask(__name__)
limiter = Limiter(app, default_limits=["50/hour"])

# Watermarked model for theft detection
model = load_watermarked_model()
query_monitor = QueryPatternDetector()

@app.route("/predict", methods=["POST"])
@limiter.limit("50/hour")
def predict():
    data = request.json["features"]
    api_key = request.headers.get("X-API-Key")

    # Detect extraction patterns (uniform sampling, grid queries)
    if query_monitor.is_suspicious(api_key, data):
        log_alert(f"Possible extraction: {api_key}")
        return jsonify({"error": "rate limited"}), 429

    result = model.predict([data])[0]
    return jsonify({
        "prediction": int(result)  # Label only, no probabilities
    })

Lista de Verificação de Mitigação

6�E�⃣ ML06 - Ataques à Cadeia de Suprimentos de IA

Critical

Visão Geral

Ataques à cadeia de suprimentos de IA visam o pipeline de desenvolvimento ML: modelos pré-treinados de repositórios de modelos, conjuntos de dados de terceiros, frameworks ML e dependências. Modelos maliciosos podem conter backdoors ocultos, e bibliotecas comprometidas podem injetar vulnerabilidades. Os formatos de serialização usados por frameworks ML (Pickle, SavedModel) podem executar código arbitrário ao carregar.

Risco

Carregar um arquivo de modelo malicioso pode executar código arbitrário (ataques de desserialização Pickle). Modelos pré-treinados de fontes não confiáveis podem conter backdoors. Bibliotecas ML comprometidas afetam todos os usuários downstream. A cadeia de suprimentos ML tem menos controles de segurança do que cadeias de suprimentos de software tradicionais.

Exemplo de Código Vulnerável

Python ❁EBad
import pickle
import torch

# Loading untrusted model  Earbitrary code execution!
with open("model_from_internet.pkl", "rb") as f:
    model = pickle.load(f)  # DANGEROUS: can execute any code!

# Loading unverified PyTorch model
model = torch.load("untrusted_model.pt")  # Uses pickle internally!

# Using unvetted model from public hub
from transformers import AutoModel
model = AutoModel.from_pretrained("random-user/suspicious-model")
# No hash verification, no security scan

Exemplo de Código Seguro

Python ✁EGood
import torch
import hashlib
from safetensors.torch import load_file

# Use SafeTensors  Eno arbitrary code execution
model_state = load_file("model.safetensors")  # Safe format!
model = MyModel()
model.load_state_dict(model_state)

# Verify model hash before loading
EXPECTED_HASH = "sha256:a1b2c3d4..."
with open("model.safetensors", "rb") as f:
    actual_hash = "sha256:" + hashlib.sha256(f.read()).hexdigest()
assert actual_hash == EXPECTED_HASH, "Model integrity check failed!"

# Use trusted models from verified organizations
from transformers import AutoModel
model = AutoModel.from_pretrained(
    "google/bert-base-uncased",  # Verified organization
    revision="a265f77",           # Pin to specific commit
)

Lista de Verificação de Mitigação

7�E�⃣ ML07 - Ataque de Transfer Learning

High

Visão Geral

Ataques de transfer learning exploram a prática comum de ajustar modelos pré-treinados. Backdoors incorporados no modelo base persistem através do ajuste fino e permanecem ativos no modelo downstream. Um atacante que publica um modelo pré-treinado popular pode comprometer todas as aplicações que o usam como fundação.

Risco

Backdoors em modelos pré-treinados sobrevivem ao ajuste fino porque estão incorporados em camadas profundas que são frequentemente congeladas durante o transfer learning. Um único modelo fundacional comprometido pode afetar milhares de aplicações downstream. O ataque é escalável e difícil de detectar.

Exemplo de Código Vulnerável

Python ❁EBad
from transformers import AutoModelForSequenceClassification

# Fine-tuning an unvetted pre-trained model
model = AutoModelForSequenceClassification.from_pretrained(
    "unknown-user/bert-finetuned-sentiment",  # Untrusted source!
    num_labels=2
)

# Freezing base layers  Epreserves any hidden backdoor
for param in model.base_model.parameters():
    param.requires_grad = False  # Backdoor in frozen layers persists!

# Fine-tune only the classification head
trainer.train()  # Backdoor remains undetected

Exemplo de Código Seguro

Python ✁EGood
from transformers import AutoModelForSequenceClassification
from neural_cleanse import BackdoorDetector

# Use only verified, trusted base models
model = AutoModelForSequenceClassification.from_pretrained(
    "google/bert-base-uncased",  # Trusted source
    num_labels=2,
    revision="main",
)

# Scan pre-trained model for backdoors before fine-tuning
detector = BackdoorDetector(model)
if detector.scan():
    raise SecurityError("Potential backdoor detected in base model")

# Fine-tune ALL layers (not just head) to overwrite potential backdoors
for param in model.parameters():
    param.requires_grad = True  # Train all layers

# Validate with clean test set + trigger test set
trainer.train()
evaluate_for_backdoors(model, trigger_test_set)

Lista de Verificação de Mitigação

8�E�⃣ ML08 - Desvio de Modelo

Medium

Visão Geral

Desvio de modelo ocorre quando a distribuição de dados em produção difere significativamente da distribuição de dados de treinamento (desvio treinamento-serviço). Isso pode acontecer naturalmente ao longo do tempo (deriva de dados) ou ser intencionalmente causado por atacantes que manipulam a distribuição de entrada de produção para degradar o desempenho do modelo ou enviesar previsões.

Risco

Desvio de modelo causa falhas silenciosas onde o modelo produz previsões incorretas mas confiantes. Em sistemas financeiros, atacantes podem explorar desvio para burlar detecção de fraude. Em sistemas de recomendação, desvio pode ser intencionalmente induzido para promover conteúdo ou produtos específicos.

Exemplo de Código Vulnerável

Python ❁EBad
import joblib

# Deploy model with no drift monitoring
model = joblib.load("model_trained_2023.pkl")

def predict(features):
    # No check if input distribution has changed
    # No feature validation against training schema
    return model.predict([features])[0]
    # Model may be months/years old
    # No monitoring of prediction distribution
    # Silent degradation goes undetected

Exemplo de Código Seguro

Python ✁EGood
import joblib
import numpy as np
from scipy import stats
from evidently import ColumnDriftMetric

model = joblib.load("model.pkl")
training_stats = joblib.load("training_stats.pkl")

def predict_with_monitoring(features):
    # Validate feature schema and ranges
    for i, (val, stat) in enumerate(zip(features, training_stats)):
        z_score = abs((val - stat["mean"]) / stat["std"])
        if z_score > 5:
            log.warning(f"Feature {i} out of distribution: z={z_score:.1f}")

    prediction = model.predict([features])[0]

    # Log prediction distribution for drift monitoring
    metrics_collector.log(features, prediction)

    # Periodic drift detection (run by monitoring job)
    # drift_report = ColumnDriftMetric().calculate(reference, current)
    # Alert if drift detected ↁEtrigger retraining

    return prediction

Lista de Verificação de Mitigação

9�E�⃣ ML09 - Ataque de Integridade de Saída

High

Visão Geral

Ataques de integridade de saída adulteram previsões do modelo depois que elas deixam o modelo mas antes de chegarem à aplicação consumidora. Isso inclui ataques man-in-the-middle em APIs de previsão, manipulação de infraestrutura de servir modelo e adulteração de previsões em cache. O ataque visa o pipeline de inferência em vez do modelo em si.

Risco

Previsões adulteradas podem causar decisões incorretas em sistemas downstream: aprovar transações fraudulentas, diagnosticar incorretamente condições médicas ou sobrescrever sistemas de segurança. Como o modelo em si não está comprometido, monitoramento padrão do modelo não detectará o ataque.

Exemplo de Código Vulnerável

Python ❁EBad
import requests

# Consuming model predictions over unencrypted HTTP
def get_prediction(features):
    response = requests.post(
        "http://ml-service/predict",  # HTTP, not HTTPS!
        json={"features": features}
    )
    result = response.json()
    # No integrity verification of the response
    # No validation of prediction format
    return result["prediction"]  # Could be tampered!

Exemplo de Código Seguro

Python ✁EGood
import requests
import hmac
import hashlib

def get_prediction(features):
    response = requests.post(
        "https://ml-service/predict",  # HTTPS (TLS)
        json={"features": features},
        headers={"Authorization": f"Bearer {API_TOKEN}"},
        verify=True  # Verify TLS certificate
    )
    result = response.json()

    # Verify response integrity with HMAC signature
    signature = response.headers.get("X-Signature")
    expected = hmac.new(
        SHARED_SECRET, str(result).encode(), hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(signature, expected):
        raise IntegrityError("Response signature mismatch!")

    # Validate prediction is within expected range
    pred = result["prediction"]
    if pred not in VALID_LABELS:
        raise ValueError(f"Unexpected prediction: {pred}")
    return pred

Lista de Verificação de Mitigação

🔟 ML10 - Envenenamento de Modelo

Critical

Visão Geral

Envenenamento de modelo modifica diretamente os pesos, parâmetros ou arquitetura do modelo treinado para injetar backdoors ou alterar comportamento. Diferentemente do envenenamento de dados (que corrompe dados de treinamento), envenenamento de modelo visa o artefato do modelo em si  Eatravés de repositórios de modelos comprometidos, ameaças internas ou ataques à cadeia de suprimentos no pipeline de armazenamento e implantação do modelo.

Risco

Um modelo diretamente envenenado pode conter backdoors altamente direcionados que são virtualmente indetectáveis através de testes padrão. O atacante tem controle preciso sobre o comportamento do modelo em entradas de gatilho. Se o registro de modelos ou pipeline de implantação estiver comprometido, cada implantação usa o modelo envenenado.

Exemplo de Código Vulnerável

Python ❁EBad
import mlflow

# Loading model from registry with no integrity checks
model_uri = "models:/fraud-detector/Production"
model = mlflow.pyfunc.load_model(model_uri)

# No hash verification
# No signature validation
# No comparison with expected model metrics
# Model registry has weak access controls
# Anyone with push access can replace the model

predictions = model.predict(new_data)

Exemplo de Código Seguro

Python ✁EGood
import mlflow
import hashlib
from sigstore.verify import Verifier

# Verify model signature before loading
model_uri = "models:/fraud-detector/Production"
model_path = mlflow.artifacts.download_artifacts(model_uri)

# Cryptographic signature verification
verifier = Verifier.production()
verifier.verify(
    model_path,
    expected_identity="ml-team@company.com"
)

# Verify model hash against approved registry
model_hash = hash_directory(model_path)
approved_hash = get_approved_hash("fraud-detector", "Production")
assert model_hash == approved_hash, "Model integrity check failed!"

# Validate model metrics on reference dataset before serving
model = mlflow.pyfunc.load_model(model_path)
ref_score = evaluate(model, reference_dataset)
assert ref_score >= MINIMUM_ACCURACY, "Model quality below threshold"

predictions = model.predict(new_data)

Lista de Verificação de Mitigação

📊 Tabela Resumo

ID Vulnerabilidade Severidade Mitigação Chave
ML01Ataque de Manipulação de EntradaCriticalTreinamento adversarial, validação de entrada, limites de confiança
ML02Ataque de Envenenamento de DadosCriticalDetecção de outliers, proveniência de dados, comparação com baseline
ML03Ataque de Inversão de ModeloHighPrivacidade Diferencial, saída mínima, limitação de taxa
ML04Ataque de Inferência de PertencimentoHighRegularização, treinamento DP, sem exposição de probabilidade
ML05Roubo de ModeloCriticalLimitação de taxa, marca d'água, detecção de padrão de consulta
ML06Ataques à Cadeia de Suprimentos de IACriticalSafeTensors, verificação de hash, apenas fontes confiáveis
ML07Ataque de Transfer LearningHighModelos base confiáveis, escaneamento de backdoor, ajuste completo
ML08Desvio de ModeloMediumMonitoramento de deriva, validação de entrada, retreinamento automático
ML09Ataque de Integridade de SaídaHighTLS/mTLS, assinatura de resposta, validação de saída
ML10Envenenamento de ModeloCriticalAssinatura de modelo, controle de acesso a registro, validação de métricas