
Artefacto de investigación y servidor MCP que audita problemas de seguridad y privacidad en bots de Discord de terceros mediante análisis de reseñas a gran escala, etiquetado con LLM y una taxonomía de 31 temas.
Artículo: Kofi Ampomah y Tu Le. Measuring Users' Security and Privacy Concerns About Third-Party Community Bots on Discord. Network and Distributed System Security (NDSS) Symposium 2027. https://dx.doi.org/10.14722/ndss.2027.230535
Revisores de artefactos: comiencen por
ARTIFACT-EVALUATION.md. Asigna cada afirmación del artículo al comando exacto que la reproduce, enumera las salidas esperadas y los tiempos de ejecución, e indica qué componentes quedan fuera del alcance.
Este repositorio contiene el código fuente del pipeline de BotLens, que analiza las preocupaciones de seguridad y privacidad (S&P) en bots comunitarios de terceros en Discord mediante análisis de reseñas a gran escala y auditoría de metadatos. El pipeline procesa 183.142 reseñas de usuarios de 23.102 bots extraídos de Top.gg, identifica 8.832 reseñas como relevantes para S&P — un rendimiento observado del pipeline del 4,82 % — y las asigna a una taxonomía de S&P de 31 temas.
BotLens/
├── README.md # This file
├── ARTIFACT-EVALUATION.md # Claim → command → expected output
├── LICENSE # See License below
├── CITATION.cff # How to cite (also used by Zenodo)
├── botlens-ndss-data.zip # The data; unpack to data/ (see Data below)
├── requirements-lock.txt # Exact versions used for the paper
├── requirements.txt # Looser version bounds
│
├── config/ # Pipeline configuration
│ ├── __init__.py
│ ├── settings.py # Paths, model params, thresholds
│ └── taxonomy.py # 31-theme S&P taxonomy (single source of truth)
│
├── scrapers/ # Data collection scripts
│ ├── topgg_metadata_scraper.py # Bot metadata scraper (Top.gg pages)
│ ├── topgg_reviews_scraper.py # Bot review scraper (Top.gg reviews)
│ └── discord_server_scanner.py # Server bot scanner — OUT OF SCOPE, see below
│
├── scripts/ # Pipeline stages + analysis
│ ├── stage0_preprocess.py # Merge, clean, detect language, translate
│ ├── stage1_llm_labeling.py # Binary S&P classification via Ollama
│ ├── stage1b_active_learning.py # Active learning loop
│ ├── stage2_prepare_data.py # Train/val/test splits with balancing
│ ├── stage3_finetune_deberta.py # Fine-tune DeBERTa-v3-large classifier
│ ├── stage4_classify_all.py # Classify all 183K reviews
│ ├── stage5_theme_assignment.py # Assign 31-theme taxonomy themes
│ ├── stage6_emotion_classification.py # GoEmotions → Ekman-style groups
│ ├── stage7_analysis.py # Sec. IV-A: SPRR, TPR, per-tag/per-bot tables
│ ├── stage8_visualizations.py # Figs. 2–9
│ ├── rq3_permissions_metadata.py # RQ3 (Sec. IV-D): statistics + Figs. 10–14, 18
│ ├── language_affective_analysis.py # Appendix B: Fig. 17
│ ├── experiment_labeling_pct.py # Labeling-budget experiment (10–45%)
│ ├── create_irr_sheets.py # Inter-rater reliability labeling sheets
│ ├── compute_kappa.py # Cohen's kappa (Sec. III-C3)
│ ├── check_langs.py # Language distribution (Table IV; needs raw crawl)
│ └── prep_30pct_for_al.py # Prepare labels for active learning
│
├── tests/
│ └── test_smoke.py # Fast integrity checks, no data required
│
└── mcp_server/ # BotLens MCP server (Sec. V)
├── server.py # The six tools of Sec. V-B2 (+ internal helpers)
├── example_client.py # MCP SDK client reproducing Use Cases 1 and 2
└── benchmark_latency.py # Sec. V-D latency session
Cada figura que generan los scripts lleva el nombre del número de figura de su artículo
(figures/fig02_sprr_over_time.png es la Fig. 2, y así sucesivamente). Los scripts producen
exactamente las figuras del artículo: Figs. 2–14, 17 y 18. La Fig. 1 es el esquema del pipeline
y las Figs. 15–16 son capturas de pantalla de la interfaz del informe de BotLens.
El artefacto se publica en https://github.com/ua-spectral/BotLens. Cada release de GitHub se archiva de forma permanente en Zenodo con un DOI; el DOI se indica en el apéndice del artefacto del artículo y en la página de releases del repositorio.
Los datos se distribuyen en el repositorio como botlens-ndss-data.zip (41 MB; un archivo
se descomprime a 515 MB, por encima del límite por archivo de GitHub). Descomprímelo una vez, en la
raíz del repositorio:
python -m zipfile -e botlens-ndss-data.zip .
Esto crea data/ junto a config/; no es necesario descargar nada más. La estructura es:
BotLens/
└── data/
├── processed/
│ ├── all_reviews_classified.csv # 183,142 rows — required by the MCP server
│ ├── privacy_reviews_full.csv # 8,832 S&P reviews w/ themes + affect
│ ├── bot_metadata_cleaned.csv # 23,102 bots (Table I, MCP fallback)
│ ├── train.csv / val.csv / test.csv
│ └── label_map.json
├── results/ # Tables behind the paper's numbers
├── reference_figures/ # Our output of every generated figure
└── irr/ # Annotator workbooks (Sec. III-C3)
Verifique la integridad con sha256sum -c SHA256SUMS.txt desde dentro de data/.
data/README.md describe cada archivo.
| Etapa | Script | Descripción | Salida clave |
|---|---|---|---|
| 0 | stage0_preprocess.py | Fusionar reseñas + metadatos, detección de idioma, Argos Translate | data/raw/reviews.csv |
| 1 | stage1_llm_labeling.py | Clasificación binaria S&P con Ollama/Llama 3 8B | phase1_binary_labels.csv |
| 1b | stage1b_active_learning.py | Muestreo por incertidumbre + etiquetas por voto mayoritario | Conjunto de entrenamiento mejorado |
| 2 | stage2_prepare_data.py | Filtrado por confianza, submuestreo 5:1, divisiones estratificadas | train/val/test.csv |
| 3 | stage3_finetune_deberta.py | Ajuste fino de DeBERTa-v3-large (F1 = 0.938 con 30% de etiquetado) | best_model/ |
| 4 | stage4_classify_all.py | Inferencia por lotes sobre las 183.142 reseñas | all_reviews_classified.csv |
| 5 | stage5_theme_assignment.py | Ollama asigna los temas de la taxonomía de 31 temas | privacy_reviews_themed.csv |
| 6 | stage6_emotion_classification.py | GoEmotions (RoBERTa) → 8 grupos de afecto | privacy_reviews_full.csv |
| 7 | stage7_analysis.py | SPRR, TPR, SPRR por etiqueta y por bot, afecto por tema | data/results/analysis_summary.json |
| 8 | stage8_visualizations.py | Figs. 2–9, incluida la tendencia OLS de la Fig. 2 (R² = 0.35) | figures/fig02_* … fig09_* |
unassigned.