Trust But Don't Verify (Forti CVE-2025-59718)

CVE-2025-59718 & CVE-2025-59719 - Who Needs Signature Verification Anyway?

Trust But Don't Verify (Forti CVE-2025-59718)

You know that feeling when you find out a critical enterprise security appliance will just accept any SAML response you throw at it, signature or not? Yeah, that’s where we are with CVE-2025-59718 and CVE-2025-59719. Fortinet dropped these two gems in December 2025, and within three days of disclosure, threat actors were already in production environments downloading config files like it was Black Friday.

Let’s talk about what happens when you forget that cryptographic signatures exist for a reason.

The Vulnerability(s)

CVE-2025-59718 and CVE-2025-59719 are essentially the same vulnerability affecting different Fortinet product lines. Both stem from improper verification of cryptographic signatures in SAML response messages used by FortiCloud Single Sign-On. In practical terms, these devices were accepting unsigned or improperly signed SAML assertions and handing out admin sessions like candy.

The vulnerability is classified as CWE-347 (Improper Verification of Cryptographic Signature), and it’s about as straightforward as authentication bypasses get. If FortiCloud SSO is enabled, an attacker can craft a SAML response with whatever identity they want, send it to the device, and the device just says “yeah sure, you’re the admin now.”

Both vulnerabilities carry a CVSS v3.1 score of 9.8, which tracks. Unauthenticated remote code execution to admin? That’s a critical any day of the week.

CVE-2025-59718 affects:

CVE-2025-59719 affects:

The root cause is identical - both involve the same signature verification failure in the SAML authentication flow, just implemented across different product codebases.

Timeline: The Speed Run

December 9, 2025: Fortinet publishes advisory FG-IR-25-647 and releases patches. Credit goes to Fortinet’s internal team members Yonghui Han and Theo Leleu for the discovery.

December 12, 2025: Arctic Wolf starts observing active exploitation in the wild. Threat actors are already authenticating as admin via SSO and downloading system configuration files from compromised FortiGate appliances. That’s 72 hours from disclosure to widespread exploitation.

December 16, 2025: CISA adds CVE-2025-59718 to the Known Exploited Vulnerabilities catalog with a remediation deadline of December 23, 2025 - just seven days.

December 17, 2025: Rapid7 observes exploitation attempts against their honeypots. Public PoC code starts appearing on GitHub.

The weaponization window on this one was basically nonexistent. By the time most organizations even read the advisory, attackers were already in.

Affected Versions and Patch Status

Here’s the damage report:

FortiOS:

FortiProxy:

FortiSwitchManager:

FortiWeb:

Proof of Concept Details

The public PoC that surfaced on GitHub demonstrates exactly how trivial this exploitation is. The attack flow is dead simple:

  1. Craft a SAML response with your chosen username (typically “admin”)
  2. Include proper XML structure but skip the signature or include an invalid one
  3. POST it to /remote/saml/login on the target device
  4. Device accepts it without proper signature verification
  5. You’re now authenticated as that user with full privileges

The PoC includes functionality for:

What makes this particularly nasty is that FortiCloud SSO is automatically enabled when administrators register devices to FortiCare via the GUI unless they explicitly disable it. Most admins never realized they were exposing this attack surface.

The default factory setting has FortiCloud SSO disabled, but the moment you go through the registration workflow without unchecking that box, you’re vulnerable. This created a massive exposure across enterprise Fortinet deployments.

Technical Deep Dive: The Exploitation Mechanics

Let’s get into the weeds of how this actually works.

SAML (Security Assertion Markup Language) is an XML-based protocol for exchanging authentication and authorization data between an identity provider and a service provider. The entire security model depends on cryptographic signatures to ensure assertions haven’t been tampered with.

In a proper SAML flow:

  1. User initiates authentication
  2. Identity Provider (IdP) generates a SAML assertion
  3. IdP signs the SAML response and/or assertion with its private key
  4. Service Provider (SP) receives the SAML response
  5. SP verifies the signature using IdP’s public certificate
  6. If signature is valid, SP trusts the assertion and creates a session

The vulnerability exists in step 5 - the signature verification. Fortinet’s FortiCloud SSO implementation was failing to properly validate that:

This means an attacker could send a completely unsigned SAML response, or one signed with a bogus key, and the device would process it as legitimate.

The SAML response structure attackers are exploiting looks something like this:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        <saml:Subject>
            <saml:NameID>admin</saml:NameID>
        </saml:Subject>
        <saml:AttributeStatement>
            <saml:Attribute Name="username">
                <saml:AttributeValue>admin</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

The attacker controls the NameID and username fields. With no signature verification enforcing that these came from a legitimate IdP, you can just claim to be whoever you want.

What’s particularly interesting is the fix. In FortiOS 7.2.12, 7.4.9, and 7.6.4, Fortinet added enforcement that SAML response messages must have valid signatures. They also added a configuration option in 7.6.5 to control whether both the response and assertion must be signed:

config user saml
    edit <n>
        set require-signed-resp-and-asrt <enable | disable>
    next
end

The default is enable, meaning both must be signed. This is the correct behavior that should have existed from day one.

The patch essentially added the signature verification logic that was completely missing or broken. It now:

  1. Checks that a signature element exists
  2. Validates the signature cryptographically
  3. Verifies it matches the configured IdP certificate
  4. Rejects the SAML response if any check fails

Forensic Data Collection

Forensic Considerations and Limitations

Here’s where things get dicey from an incident response perspective: this attack leaves minimal forensic evidence.

What you WILL see:

What you WON’T see:

The observed attack pattern from Arctic Wolf shows this log signature:

logid="0100032001" type="event" subtype="system" level="information"
logdesc="Admin login successful" user="admin" ui="sso(199.247.7.82)" 
method="sso" srcip=199.247.7.82 action="login" status="success" 
profile="super_admin"

Followed by:

logid="0100032095" type="event" subtype="system" level="warning"
logdesc="Admin performed an action from GUI" user="admin" 
ui="GUI(199.247.7.82)" action="download" status="success"
msg="System config file has been downloaded"

Critical forensic limitation: If an attacker authenticated via this vulnerability and immediately disabled logging or modified the syslog configuration, you might have zero visibility into what they did post-compromise.

Additionally, downloaded configuration files contain:

If your config was exfiltrated, assume all credentials in it are compromised. The hashes can be cracked offline, and weak passwords will fall quickly to dictionary attacks.

What we’ve observed in the wild:

This suggests initial access operations, likely for follow-on attacks. Stolen credentials enable:

Forensic Evidence Collection

When exploitation is suspected or confirmed, evidence collection needs to happen fast. FortiGate logs rotate, memory is volatile, and attackers with admin access can disable logging or wipe evidence. The following methods preserve forensic artifacts before they disappear.

Collection Priority Order

Time matters. The forensic window closes fast. If you can’t collect everything immediately:

  1. System logs - Rotate fastest, contain authentication and admin action evidence
  2. Memory dump - Most volatile, shows active sessions and in-memory configurations
  3. Configuration backup - Shows what the attacker could access or modify
  4. Disk image - Time-consuming but comprehensive preservation
  5. Network flow logs - May show data exfiltration or C2 communication
  6. External SIEM data - If forwarding was enabled and not disabled by attacker

Logs rotate. Sessions expire. Attackers clean up. Collect what matters first.

FortiGate Log Extraction

FortiGate devices store logs in memory and disk depending on configuration. Critical for CVE-2025-59718 investigations because they contain the only evidence of SSO authentication and post-compromise actions.

Export all event logs:

# Via CLI - exports to TFTP/FTP server
execute backup disk full-config tftp <filename> <tftp_server_ip>

# Export system logs to USB (if available)
execute backup disk full-log usb <filename>

# Export logs via SCP (requires SSH enabled)
execute backup disk alllogs scp <filename> <scp_server_ip>:<path> <username>

Export specific log categories:

# Export only system event logs (authentication, admin actions)
execute log filter category 0
execute log filter field subtype system
execute log display
execute log export tftp <filename> <tftp_server>

# Export traffic logs (network connections)
execute log filter category 1
execute log display
execute log export tftp <filename> <tftp_server>

# Export security logs (IPS, AV, etc.)
execute log filter category 2
execute log display
execute log export tftp <filename> <tftp_server>

Check log storage locations:

# Show current log storage settings
diagnose sys top-summary

# Check disk space and log usage
get system status

# Show logging configuration
show log setting
show log syslogd setting
show log fortianalyzer setting

Critical logs for CVE-2025-59718:

If using FortiAnalyzer or Syslog:

Logs may be preserved externally even if local logs are cleared:

# Check if FortiAnalyzer is configured
get log fortianalyzer setting

# Check if syslog forwarding is active
get log syslogd setting

# Verify last successful log upload
diagnose test application miglogd 4

If external logging was active, immediately secure those log stores before the attacker accesses them.

Memory Acquisition

Memory contains active sessions, cached credentials, in-memory configurations, and runtime state that doesn’t exist on disk. For FortiGate investigations, memory is critical because it may contain:

Physical FortiGate Appliance Memory Dump:

FortiGate devices run FortiOS (a hardened Linux kernel). Direct memory access requires specific procedures:

# Check available memory
diagnose hardware deviceinfo mem

# Enable core dump (requires reboot)
diagnose debug enable
diagnose debug core-dump enable

# Trigger controlled crash to generate core dump (USE WITH EXTREME CAUTION)
# This will reboot the device - only use if authorized
diagnose debug crash

Core dumps are stored in /data/core/ and can be extracted via SCP or USB.

VM-based FortiGate (FortiGate-VM) Memory Dump:

For virtual appliances, use hypervisor snapshot capabilities:

# VMware ESXi - suspend to capture memory
vim-cmd vmsvc/power.suspend <vmid>
# Memory saved to .vmss file in VM directory
# Resume after copying: vim-cmd vmsvc/power.on <vmid>

# Hyper-V memory dump
Stop-VM -Name FortiGateVM -Save
# Memory saved to .bin and .vsv files
Start-VM -Name FortiGateVM

# KVM/QEMU memory dump
virsh dump <domain> /forensics/fortigate-memory.dump --memory-only --live

# AWS EC2 (if EBS-backed)
# Create snapshot, then extract from snapshot volume
aws ec2 create-snapshot --volume-id vol-xxxxx --description "FortiGate forensics"

Alternative: Configuration and Session State Extraction:

If full memory dump isn’t possible, extract runtime state:

# Dump current configuration (includes all settings)
show full-configuration

# Show active admin sessions
diagnose sys session list

# Show cached certificates and keys
diagnose vpn ssl list

# Show SAML configuration and status
diagnose debug application samld -1
diagnose debug enable
# Let it run for 30 seconds to capture SAML processing
diagnose debug disable
diagnose debug reset

Disk Imaging

Disk images preserve FortiGate system files, logs, configuration, and forensic artifacts. For CVE-2025-59718, disk imaging captures:

Physical Appliance Disk Imaging:

Physical FortiGate devices use internal storage (SSD/HDD). Imaging requires physical access; if this is impossible or risk is not accepted to crack open the device; consider working with FortiSupport to have a bitwise image generated after shipping the entire device


# Using dc3dd (forensically sound)
sudo dc3dd if=/dev/sdb of=/forensics/fortigate-disk.img hash=sha256 log=/forensics/imaging.log

# Using dd and dumping output to a remote host (Few methods)
dd if=/dev/<source> bs=16M | ssh <user>@<host> “/bin/dd of=/path/to/save/<device_name>.dd bs=16M”
dd if=/dev/<root device> bs=5M conv=fsync status=progress | gzip -c -9 | ssh <user>@<DestinationIP> 'gzip -d | dd of=<device_name>.dd bs=5M'

VM-based FortiGate Disk Imaging:

For virtual appliances, snapshot the virtual disks:

# VMware - Clone VMDK files
vmkfstools -i fortigate.vmdk fortigate-forensic.vmdk

# Hyper-V - Export VM disks
Export-VM -Name FortiGateVM -Path C:\Forensics\

# KVM/QEMU - Copy qcow2 images
cp /var/lib/libvirt/images/fortigate.qcow2 /forensics/fortigate-forensic.qcow2

# AWS EC2 - Create AMI or snapshot
aws ec2 create-image --instance-id i-xxxxx --name "FortiGate-Forensic-Image"
# Or snapshot specific volumes
aws ec2 create-snapshot --volume-id vol-xxxxx --description "FortiGate forensics"

# Azure - Create managed disk snapshot
az snapshot create --resource-group myRG --name fortigate-snap --source /subscriptions/.../disks/fortigate-disk

# GCP - Snapshot persistent disk
gcloud compute disks snapshot fortigate-disk --snapshot-names=fortigate-forensic --zone=us-central1-a

Live Backup (If Device Can’t Be Taken Offline):

If the FortiGate must remain operational:

# Full configuration backup (includes encrypted passwords)
execute backup full-config tftp backup.conf <tftp_server>

# Or via SCP (preferred for security)
execute backup full-config scp backup.conf <user>@<server>:<path>

# Full disk backup (includes logs, firmware)
execute backup disk full-config tftp full-backup.img <tftp_server>

# Verify backup integrity
execute restore verify tftp backup.conf <tftp_server>

Configuration Files

Configuration reveals what was enabled during the exploitation window and what the attacker could access or modify.

Critical FortiGate configurations:

Triage Extract via CLI: For a starting triage and forensic command reference, see our FortiGate triage command collection at https://gist.github.com/gottlabs/4fdc425bd8c50944e9a5c67806d7639c. It includes system integrity checks, process enumeration, filesystem inspection, and network state collection commands useful during incident response.

Configuration file locations on disk:

System logs and forensic artifacts:

Certificate and key stores:

External SIEM/Log Aggregation

If FortiGate was forwarding logs to external systems:

FortiAnalyzer logs:

Syslog servers:

Detection and Hunting

Given the forensic limitations, detection relies heavily on behavioral analytics and log correlation.

Primary detection logic:

Hunt for SSO authentication followed by configuration downloads:

event="Admin login successful" AND method="sso" 
FOLLOWED BY 
action="download" AND msg CONTAINS "config file"
WITHIN 15 minutes

Look for admin actions from unexpected source IPs:

user="admin" AND method="sso" 
WHERE srcip NOT IN [known_admin_ips]

Detect FortiCloud SSO logins outside normal business hours:

method="sso" AND (hour < 6 OR hour > 20) 
AND day IN [Saturday, Sunday]

Check for multiple admin logins from different IPs in short timeframes:

COUNT(DISTINCT srcip) WHERE method="sso" AND user="admin"
GROUP BY 15_minute_window
HAVING count > 1

Configuration audit:

show system global | grep admin-forticloud-sso-login

If this returns enable, you’re exposed (assuming vulnerable version).

Log queries to hunt for historical compromise:

# All SSO logins in the past 30 days
execute log filter category 0
execute log filter field subtype system
execute log filter field action login
execute log filter field method sso
execute log display
# Configuration downloads
execute log filter category 0
execute log filter field action download
execute log display

Network-based detection:

Monitor for POST requests to /remote/saml/login with SAML payloads lacking proper signatures. This requires SSL inspection capabilities and deep packet inspection of SAML XML structure.

YARA rule for SAML responses in network traffic:

rule CVE_2025_59718_SAML_Exploit {
    strings:
        $saml1 = "samlp:Response" nocase
        $saml2 = "Assertion" nocase
        $saml3 = "NameID" nocase
        $endpoint = "/remote/saml/login" nocase
    condition:
        all of them and not (
            $sig1 = "ds:Signature" or
            $sig2 = "SignatureValue"
        )
}

Endpoint forensics:

Check web server logs on the FortiGate:

execute log filter category 1
execute log filter field action login
execute log display

Review historical SAML authentication attempts:

diagnose debug application samld -1
diagnose debug enable

Note: This won’t show historical events, only new ones while debug is enabled.

Remediation and Workarounds

Immediate action required:

  1. Disable FortiCloud SSO (if patches can’t be applied immediately):

Via GUI:

System -> Settings -> Disable "Allow administrative login using FortiCloud SSO"

Via CLI:

config system global
    set admin-forticloud-sso-login disable
end
  1. Verify the setting:
    show system global | grep admin-forticloud-sso-login
    

Should return: set admin-forticloud-sso-login disable

  1. Restrict management access:
    config system admin
     edit admin
         set trusthost1 <trusted_subnet> <netmask>
     next
    end
    

Limit admin GUI access to specific trusted networks only. Don’t expose management to the internet.

Patch upgrade path:

Use Fortinet’s upgrade tool to determine safe upgrade paths. Some versions require intermediate upgrades. For example, FortiOS 7.0.17 can’t directly upgrade to 7.6.4 - you need to go through 7.0.18 first.

Recommended upgrade sequence:

  1. Back up current configuration
  2. Test upgrade in non-production environment
  3. Schedule maintenance window
  4. Upgrade during low-traffic period
  5. Verify FortiGuard service connectivity post-upgrade
  6. Re-enable FortiCloud SSO only if required

Post-patch validation:

After patching, verify SAML signature enforcement is active:

config user saml
    edit <saml_config_name>
        get
    next
end

Look for set require-signed-resp-and-asrt enable in versions 7.6.5+.

Assessment and Impact

CVE-2025-59718 and CVE-2025-59719 represent everything wrong with authentication bypass vulnerabilities in critical infrastructure devices. The combination of factors makes this particularly nasty:

Attack complexity: Low. Send a crafted HTTP POST request, get admin access. Privilege required: None. Completely unauthenticated. User interaction: None. No social engineering required. Exploitability: Trivial. Public PoC available, observed exploitation within 72 hours. Impact: Complete device compromise with admin privileges.

The vulnerability is especially dangerous because FortiCloud SSO is silently enabled during device registration, a workflow most administrators don’t associate with opening security holes. This created widespread exposure without explicit admin awareness.

The 72-hour window from disclosure to active exploitation demonstrates that threat actors have mature capabilities for rapid weaponization. This wasn’t script kiddies fumbling around - it was organized groups with infrastructure ready to go.

The targeting of configuration files suggests credential harvesting for persistent access and lateral movement. Expect these stolen credentials to be used in follow-on attacks for months to come.

Bottom line: If you run Fortinet devices with FortiCloud SSO enabled on vulnerable versions, assume compromise until proven otherwise. Patch immediately, disable the feature if you can’t patch, and hunt through logs for signs of exploitation.

The fact that this vulnerability existed in a security appliance’s authentication mechanism - the thing literally designed to verify identity - is ironic in the worst way possible. It’s 2025 and we’re still seeing basic cryptographic verification failures in enterprise security products.

SAML isn’t new. Signature verification isn’t rocket science. This should never have made it to production.

References