918 labeled ADS-B records, real traffic paired one-to-one with synthetically injected attacks, 38 documented columns, a shipped baseline, and a license that lets you use it for anything. This page is the landing page, the numbers are recomputed from the file itself.
The AeroScope ADS-B Anomaly Benchmark (v1) pairs 459 real airborne ADS-B records, captured live from public crowdsourced feeds and de-duplicated by ICAO 24-bit address, with 459 synthetically injected attacks built on top of that same real traffic. Injected attacks follow the taxonomy used in the ADS-B security literature (methodology after Habler and Shabtai, Computers & Security, 2018): altitude tampering, velocity tampering, ghost kinematics, and integrity-field downgrade. Every one of the 918 rows also carries the anomaly score from a deployed scikit-learn IsolationForest model, so a baseline is not something you have to build yourself before you can compare against it.
Nothing in this dataset comes from a satellite feed, a proprietary receiver network, or multilateration. AeroScope's own data sources are adsb.fi, adsb.lol and an OpenSky fallback, the same class of public, crowdsourced feed anyone can access, which is part of why this dataset is reproducible by other researchers rather than tied to infrastructure only one organization has.
| Attack type | Rows | What it does |
|---|---|---|
altitude_tamper | 115 | Alters barometric or geometric altitude away from the real captured value, desyncing the two altitude sources in a way a real transponder should not produce. |
velocity_tamper | 115 | Alters ground speed, airspeed or Mach so the reported kinematics no longer agree with each other or with the aircraft's real performance envelope. |
ghost_kinematics | 115 | Injects an implausible combined motion profile, position, speed and track together, modeling a fabricated track with no real aircraft behind it. See ghost aircraft in ADS-B. |
integrity_downgrade | 114 | Lowers the reported NIC, NACp, NACv or SIL fields inconsistently with the rest of the message, modeling a spoofed or malfunctioning integrity report. See NIC and NACp explained. |
Injected altitude values are clamped at -1000 ft, the Mode-S altitude encoding floor, so attack rows stay within what a real transponder could physically transmit rather than producing an obviously impossible value a trivial range check would catch.
Every row carries the raw ADS-B fields, the signal-integrity fields, four derived self-consistency features, and the deployed baseline's score. The full schema, read directly from the published CSV header:
| # | Column | Description |
|---|---|---|
| 1 | record_id | Sequential row id |
| 2 | label | 0 = real traffic, 1 = injected attack |
| 3 | attack_type | null, or one of the four attack types above |
| 4 | capture_ts_utc | Unix epoch seconds at capture |
| 5 | hex | ICAO 24-bit address, as broadcast (public data, not anonymized) |
| 6 | callsign | Flight callsign, trimmed |
| 7 | registration | Tail registration, if broadcast |
| 8 | aircraft_type | ICAO type designator, e.g. B738 |
| 9 | category | ADS-B emitter category, A0 to C3 |
| 10 | source | Message type, e.g. adsb_icao, mlat |
| 11 | lat | Latitude, degrees |
| 12 | lon | Longitude, degrees |
| 13 | alt_baro_ft | Barometric altitude, ft |
| 14 | alt_geom_ft | Geometric (GNSS) altitude, ft |
| 15 | gs_kts | Ground speed, kts |
| 16 | ias_kts | Indicated airspeed, kts (sparse, enhanced-surveillance only) |
| 17 | tas_kts | True airspeed, kts (sparse) |
| 18 | mach | Mach number (sparse) |
| 19 | track_deg | Ground track, degrees |
| 20 | mag_heading_deg | Magnetic heading, degrees (sparse) |
| 21 | track_rate_dps | Turn rate, deg/s (sparse) |
| 22 | roll_deg | Roll angle, degrees (sparse) |
| 23 | baro_rate_fpm | Barometric vertical rate, ft/min |
| 24 | geom_rate_fpm | Geometric vertical rate, ft/min |
| 25 | squawk | Transponder code |
| 26 | nic | Navigation integrity category, 0 to 11 |
| 27 | nac_p | Navigation accuracy category, position, 0 to 11 |
| 28 | nac_v | Navigation accuracy category, velocity, as broadcast (values above the nominal 0-4 range appear in real feeds) |
| 29 | sil | Source integrity level, 0 to 3 |
| 30 | rssi_dbfs | Received signal strength, dBFS |
| 31 | seen_s | Seconds since last message |
| 32 | seen_pos_s | Seconds since last position |
| 33 | geom_baro_alt_diff_ft | Derived: |geometric minus barometric altitude| |
| 34 | gs_mach_resid_kts | Derived: ground-speed-vs-Mach self-consistency residual |
| 35 | baro_geom_rate_diff_fpm | Derived: |barometric minus geometric vertical rate| |
| 36 | track_hdg_diff_deg | Derived: angular |track minus magnetic heading| |
| 37 | iforest_score | Anomaly score, 0 to 1, from the deployed baseline |
| 38 | iforest_is_anomaly | 1 if the score crosses the FPR-calibrated threshold |
A scikit-learn IsolationForest, the same model AeroScope runs in production as one of its detectors, scores every one of the 918 rows. Recomputed directly from the labels and scores shipped in the published file, across all 459 real records and 459 injected attacks, it achieves ROC-AUC 0.87, with a 54% detection rate at a 3.1% false-positive rate using the shipped iforest_is_anomaly threshold.
To reproduce it yourself: load the CSV, treat label as ground truth and iforest_score as the model's continuous anomaly score, then compute ROC-AUC with any standard implementation (for example scikit-learn's roc_auc_score(label, iforest_score)). To reproduce the detection-rate figure, compare label against the already-shipped iforest_is_anomaly column rather than picking a new threshold: true-positive rate among the 459 attack rows and false-positive rate among the 459 real rows should land at 54% and 3.1% respectively. No retraining is required, the scores are already in the file, which is the point: the baseline is meant to be checked, not taken on faith.
Honest limitations: synthetic injection is a proxy for real attacks, not the real thing. Coverage is biased toward busy terminal areas in the capture regions. Enhanced-surveillance fields (IAS, TAS, Mach, magnetic heading, track rate, roll) are only broadcast by a subset of aircraft, roughly 25 to 40 percent non-null, which is expected sparsity rather than a data quality problem. Full details are in the dataset card linked below.
Download CSV Download JSONL Hugging Face mirror ↗
The Hugging Face mirror includes a load_dataset() loader for direct use in Python. See the research and dataset page and the dataset card for the full column reference and provenance notes. Licensed CC-BY 4.0: use it for any purpose, including commercial, with attribution.
@misc{uzair2026aeroscopebenchmark,
title={AeroScope ADS-B Anomaly Benchmark v1},
author={Uzair, Muhammad},
year={2026},
publisher={AeroScope},
howpublished={Hugging Face Datasets},
url={https://huggingface.co/datasets/Muhammaduazir69/aeroscope-adsb-anomaly-benchmark},
license={CC-BY-4.0}
}
A Zenodo DOI for this release is being minted; this page and the dataset card will be updated once it is issued.