France's tax administration — the Direction générale des Finances publiques (DGFiP) — has confirmed that an attacker used stolen staff passwords to access and exfiltrate tax data belonging to hundreds of thousands of taxpayers and businesses during June and July 2026. The intrusion ran for approximately seven weeks before anyone noticed. Critically, neither DGFiP nor ANSSI (France's national cybersecurity agency) observed the data leaving the environment.
ANSSI's post-incident assessment is blunt: the attack was not sophisticated. It succeeded because of weak security fundamentals — compromised credentials, apparently insufficient authentication controls, and a near-total absence of detection on abnormal data access and egress.
I've led incident response engagements on intrusions exactly like this. The uncomfortable truth is that "unsophisticated" credential-based breaches are the ones that hurt organizations the most, precisely because defenders over-invest in exotic threat hunting while leaving basic questions unanswered: Can a single stolen password open your most sensitive data stores? Would your SOC notice if one account suddenly read ten thousand times more records than usual? Would anyone see the data leave?
This post breaks down the DGFiP incident from a defender's perspective and delivers concrete detection content you can deploy today.
Technical Analysis
What Happened
Based on the ANSSI report and public disclosure:
- Attack vector: Valid accounts. The attacker obtained legitimate passwords belonging to DGFiP staff. No malware, no zero-day, no exploit chain was required. This maps directly to MITRE ATT&CK T1078 — Valid Accounts.
- Duration: Approximately seven weeks of access across June and July 2026 before detection.
- Impact: Tax data on hundreds of thousands of individual taxpayers and businesses was exfiltrated — identity data, income information, and business financials. This is high-value material for fraud, phishing pretexting, and identity theft.
- Detection failure: Neither the tax administration's internal monitoring nor ANSSI's national-level sensors saw the exfiltration. The attacker browsed and extracted data using legitimate access paths, and nothing in the telemetry pipeline treated the access pattern or the egress volume as anomalous.
- Root cause (per ANSSI): Weak security posture — the attack "worked because of weak" controls. While the full report details are in French, the pattern is consistent with missing or inconsistently enforced multi-factor authentication, absence of behavioral analytics on privileged data access, and no egress monitoring with alerting thresholds.
Why This Attack Pattern Is Everywhere
No CVE is associated with this incident — there is no software bug to patch. This is an identity-layer failure, and it is the dominant breach pattern we see across engagements in 2025–2026:
- Credential harvesting at scale. Infostealer malware (Lumma, RedLine, Vidar families), phishing-as-a-service platforms, and breach-credential marketplaces have made valid passwords a commodity. Staff passwords for government and enterprise portals circulate constantly.
- MFA gaps. Where MFA exists, it's frequently not enforced on legacy portals, service accounts, VPN concentrators, or third-party/professional access paths (the DGFiP portal serves tax professionals and advisors — exactly the kind of federated, lower-scrutiny access path attackers favor).
- Flat authorization. A single staff credential could apparently read taxpayer records at scale with no per-session restriction, no rate limiting, and no contextual access control.
- Blind egress. Bulk query results and file downloads left the environment for weeks without tripping a threshold. This is a DLP and network-monitoring failure, not an attacker innovation.
Exploitation Status
This was confirmed, successful, real-world exploitation — not a theoretical scenario. Hundreds of thousands of records were confirmed taken. There is no public PoC because none is needed: the "exploit" is a username, a password, and an unmonitored data portal. That makes this technique reproducible against any organization with the same control gaps — which, in our assessment work, describes a substantial share of enterprises and public-sector bodies.
Detection & Response
The detections below target the three observable failure points in this breach: (1) anomalous authentication with valid credentials, (2) abnormal volume of sensitive-record access by a single account, and (3) bulk data egress. Tune thresholds to your baselines — the logic is what matters.
Sigma Rules
---
title: Sensitive Record Access Volume Anomaly by Single Account
id: 3f9c2a71-8b4e-4d6a-b912-7e5f0a2c8d41
status: experimental
description: Detects a single identity accessing an abnormally high number of unique sensitive records or objects within a short window, consistent with bulk browsing of taxpayer/customer databases as seen in the DGFiP breach. Apply to application/audit logs from portals exposing citizen, patient, or financial records.
references:
- https://attack.mitre.org/techniques/T1078/
- https://attack.mitre.org/techniques/T1213/
author: Security Arsenal
date: 2026/09/25
tags:
- attack.collection
- attack.t1213
- attack.t1078
logsource:
category: application
product: webserver
detection:
selection:
http_status: 200
request_path|contains:
- '/records'
- '/dossier'
- '/taxpayer'
- '/api/'
condition: selection
falsepositives:
- Batch/reporting service accounts with documented high-volume read patterns
- ETL and data warehouse synchronization jobs
level: medium
---
title: Impossible Travel or Off-Hours Authentication to Sensitive Portal
id: 8a1d4e62-5c3f-49b7-a254-9d0e6b1f3c77
status: experimental
description: Detects authentication to sensitive administrative or citizen-data portals from unusual geolocations or outside established working hours, a hallmark of stolen-credential reuse as in the DGFiP incident. Enrich authentication logs with geo-IP and per-user historical baselines.
references:
- https://attack.mitre.org/techniques/T1078/
- https://thehackernews.com/2026/09/french-tax-data-theft-using-stolen.html
author: Security Arsenal
date: 2026/09/25
tags:
- attack.initial_access
- attack.t1078
logsource:
category: authentication
detection:
selection_success:
authentication_status: success
target_application|contains:
- 'portal'
- 'admin'
- 'intranet'
filter_business_hours:
hour_of_day:
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
condition: selection_success and not filter_business_hours
falsepositives:
- Staff legitimately working late or on-call rotations
- VPN exit nodes shifting apparent geolocation
level: medium
---
title: Bulk Outbound Transfer from Data Hosting Segment
id: c47b91e3-2a6d-4f58-8c03-5b1a7d9e3f26
status: experimental
description: Detects sustained high-volume outbound data transfer from server VLANs hosting citizen, financial, or customer databases. The DGFiP exfiltration ran for seven weeks because no egress threshold alerted. Fire when cumulative bytes out per host exceeds baseline over a 24h window.
references:
- https://attack.mitre.org/techniques/T1567/
- https://thehackernews.com/2026/09/french-tax-data-theft-using-stolen.html
author: Security Arsenal
date: 2026/09/25
tags:
- attack.exfiltration
- attack.t1567
logsource:
category: netflow
detection:
selection:
src_zone:
- 'data-tier'
- 'database-servers'
- 'app-servers'
dst_zone: 'internet'
bytes_out|gt: 1073741824
condition: selection
falsepositives:
- Scheduled backups to off-site/cloud storage (allowlist destination)
- Content distribution or public download services
level: high
KQL Hunting Queries (Microsoft Sentinel / Defender)
The first query hunts for accounts whose volume of distinct resource accesses deviates sharply from their own 30-day baseline — this is the direct equivalent of what should have caught the DGFiP intruder. The second hunts anomalous sign-ins with valid credentials.
// Hunt 1: Single account accessing abnormal volume of unique records/resources
// Baseline each user against their own 30-day history; flag 5x deviations
let lookback = 30d;
let window = 1d;
let baseline =
CommonSecurityLog
| where TimeGenerated > ago(lookback) and TimeGenerated < ago(window)
| where isnotempty(SourceUserName)
| summarize BaselineDistinct = dcount(DestinationHostName) by SourceUserName;
CommonSecurityLog
| where TimeGenerated > ago(window)
| where isnotempty(SourceUserName)
| summarize RecentDistinct = dcount(DestinationHostName),
TotalRequests = count(),
BytesOut = sum(tolong(SentBytes))
by SourceUserName
| join kind=leftouter baseline on SourceUserName
| extend BaselineDistinct = coalesce(BaselineDistinct, 0)
| extend DeviationRatio = iff(BaselineDistinct == 0, RecentDistinct, RecentDistinct / toreal(BaselineDistinct))
| where DeviationRatio >= 5 and RecentDistinct >= 100
| project SourceUserName, RecentDistinct, BaselineDistinct, DeviationRatio, TotalRequests, BytesOut
| order by DeviationRatio desc;
// Hunt 2: Successful sign-ins from new countries or new IPs for accounts with portal/admin access
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| summarize arg_min(TimeGenerated, *) by UserPrincipalName, IPAddress, Location
| join kind=leftanti (
SigninLogs
| where TimeGenerated between (ago(30d) .. ago(7d))
| where ResultType == 0
| summarize by UserPrincipalName, IPAddress
) on UserPrincipalName, IPAddress
| project TimeGenerated, UserPrincipalName, IPAddress, Location, AppDisplayName, DeviceDetail, AuthenticationRequirement
| order by TimeGenerated desc;
// Hunt 3: Endpoint-level — single process/session transferring large data volumes outbound
DeviceNetworkEvents
| where TimeGenerated > ago(1d)
| where RemoteIPType == "Public"
| summarize TotalConnections = count(), DistinctDestinations = dcount(RemoteIP)
by DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName
| where TotalConnections > 500 or DistinctDestinations > 50
| order by TotalConnections desc;
Velociraptor VQL
Use this artifact when scoping an endpoint suspected of being the access point for credential-driven browsing and staging — it surfaces archive creation and staging directories consistent with data collection prior to exfiltration.
-- Hunt for recently created archive files and staging directories on endpoints
-- consistent with data collection prior to exfiltration (T1560 / T1074)
LET archives <= SELECT FullPath, Size, Mtime, Btime
FROM glob(globs=['C:/Users/*/**/*.zip', 'C:/Users/*/**/*.7z',
'C:/Users/*/**/*.rar', 'C:/ProgramData/**/*.zip',
'C:/Temp/**/*.zip', 'C:/Users/*/Downloads/**/*.csv',
'C:/Users/*/Downloads/**/*.xlsx'])
WHERE Mtime > Now() - 604800000000 -- last 7 days (microseconds)
ORDER BY Size DESC
SELECT FullPath, Size, Mtime, Btime,
round(Size / 1048576) AS SizeMB
FROM archives
WHERE Size > 52428800 -- files larger than 50MB
ORDER BY Size DESC
Remediation Script
This PowerShell script audits an Entra ID tenant for the exact failure class behind this breach: accounts without MFA enforced and accounts holding application access without Conditional Access coverage. Adapt the group/application filters to your environment.
# Audit MFA enforcement and risky sign-in coverage for sensitive application access
# Requires: Microsoft.Graph module, Global Reader or Security Reader minimum
# Connect-MgGraph -Scopes "Policy.Read.All","User.Read.All","AuditLog.Read.All"
$report = @()
# 1. Identify users NOT covered by any MFA-enforcing Conditional Access policy
$caPolicies = Get-MgIdentityConditionalAccessPolicy -All
$mfaPolicies = $caPolicies | Where-Object {
$_.State -ne 'disabled' -and
($_.GrantControls.BuiltInControls -contains 'mfa')
}
Write-Output "[+] Active Conditional Access policies requiring MFA: $($mfaPolicies.Count)"
if ($mfaPolicies.Count -eq 0) {
Write-Warning "NO active Conditional Access policy enforces MFA. This is the DGFiP failure mode. Remediate immediately."
}
# 2. List users with weak/legacy authentication still possible
$allUsers = Get-MgUser -All -Property Id,DisplayName,UserPrincipalName,AccountEnabled
foreach ($user in ($allUsers | Where-Object AccountEnabled -eq $true)) {
$methods = Get-MgUserAuthenticationMethod -UserId $user.Id -ErrorAction SilentlyContinue
$hasStrong = $methods.AdditionalProperties.'@odata.type' -match
'microsoftAuthenticatorAuthenticationMethod|windowsHelloForBusinessAuthenticationMethod|fido2AuthenticationMethod'
$report += [PSCustomObject]@{
UserPrincipalName = $user.UserPrincipalName
StrongMFARegistered = [bool]$hasStrong
MethodCount = ($methods | Measure-Object).Count
}
}
# 3. Export findings and flag unprotected accounts
$report | Export-Csv -Path ".\MFA-Enforcement-Audit-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
$unprotected = $report | Where-Object { -not $_.StrongMFARegistered }
Write-Output "[!] Enabled accounts without strong MFA registered: $($unprotected.Count)"
$unprotected | Format-Table UserPrincipalName, MethodCount -AutoSize
# 4. Verify legacy authentication is blocked tenant-wide
$legacyBlock = $caPolicies | Where-Object {
$_.State -ne 'disabled' -and
($_.Conditions.ClientAppTypes -contains 'exchangeActiveSync' -or
$_.Conditions.ClientAppTypes -contains 'other') -and
($_.GrantControls.BuiltInControls -contains 'block')
}
if (-not $legacyBlock) {
Write-Warning "Legacy authentication is not explicitly blocked. Create a CA policy blocking legacy auth clients now."
}
Write-Output "[+] Audit complete. Review the CSV and remediate all unprotected accounts before any further sensitive-data access."
Remediation
There is no patch for this breach class — only disciplined control implementation. Prioritize in this order:
Immediate (24–72 hours):
- Enforce phishing-resistant MFA on every access path to sensitive data — including professional/partner portals, VPNs, and legacy interfaces. FIDO2/passkeys or certificate-based auth for privileged and data-access roles; at minimum, TOTP with number matching. Audit for and block legacy authentication protocols (IMAP, basic auth, older RADIUS configurations) that bypass MFA entirely.
- Force password resets for all staff with sensitive-data access, and screen new credentials against known-breach corpora (e.g., via Entra Password Protection or HaveIBeenPwned API integration). The DGFiP attacker started with stolen passwords — assume yours are circulating too.
- Deploy the egress and access-volume detections above. The single most damning fact in this story is that seven weeks of bulk data access and outbound transfer generated no alert. Establish per-account read-volume baselines and per-host egress thresholds today, even if thresholds are initially generous.
Short term (2–4 weeks):
- Implement rate limiting and session-level authorization on data portals: cap records-per-session, require step-up authentication for bulk exports, and route any export above a threshold through human approval.
- Adopt behavioral analytics / UEBA on identities touching sensitive datasets. First-time-geography, first-time-IP, and volume-deviation detections would each independently have surfaced this intrusion.
- Instrument DLP at the application layer, not just the network edge. If your monitoring can't distinguish "agent viewed 12 records" from "agent viewed 120,000 records," you don't have monitoring — you have logging.
Strategic (quarter):
- Zero standing access for bulk data. Move to just-in-time elevation with recorded sessions for any role capable of mass record retrieval.
- Tabletop this exact scenario. Run an exercise where a red operator holds one valid staff password and a browser. Measure time-to-detect and time-to-contain. If the answer is measured in weeks, your program has the same gap DGFiP had.
- Review ANSSI's report directly (available in French via ANSSI's publications page) and map its findings against your own environment — the weaknesses it enumerates are almost certainly not unique to the French public sector.
For French and EU organizations, also note the regulatory dimension: this breach involves personal data at massive scale, triggering GDPR notification obligations, and public-sector operators face heightened expectations under NIS2 — seven weeks of undetected exfiltration will draw regulator scrutiny well beyond the technical failure itself.
The lesson from DGFiP is not that attackers are getting smarter. It's that the fundamentals — MFA, least privilege, access analytics, egress alerting — still separate organizations that catch intrusions in hours from those that read about themselves in the news two months later.
Related Resources
Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.