Every FortiGate ships with a second firewall policy set that never appears in the main policy table, is hidden from the GUI by default, and governs the one thing an attacker wants most: traffic to the firewall itself. These are local-in policies, and the fact that most admins have never opened them is a fair summary of FortiGate security in practice. The dangerous gaps are rarely in the rules you review every week. They live in the FortiOS behavior you assume you already understand.
This post covers seven FortiGate security details that routinely catch out experienced admins, from how policy order is actually evaluated to why a hit count of zero does not mean a rule is unused, plus the real, exploited vulnerabilities that show why watching your configuration matters more than any single rule.
Key takeaway: Most FortiGate compromises are not clever packet-level attacks. They are configuration events: a rogue admin account, an added SSH key, a loosened local-in policy, or an unpatched SSL-VPN daemon. FortiOS will not tell you any of that changed. Watch the config, not just the traffic.
What are local-in policies, and why do they matter?
Local-in policies are FortiGate rules that control traffic destined for the FortiGate itself, such as administrative access, VPN termination, and routing protocols, as opposed to the traffic passing through it. They are configured separately from standard firewall policies and are not shown in the GUI unless you explicitly turn them on. That separation is the problem. Teams routinely build meticulous rules for transit traffic while leaving management interfaces, SSL-VPN, and BGP reachable, because those services answer to local-in policy, not to the policy list everyone reviews.
By default the FortiGate accepts management traffic on any interface where the service is enabled. If you enable HTTPS administrative access on a WAN interface and never write a local-in policy to constrain the source, the box will answer from anywhere. Local-in policy is where you scope that down:
config firewall local-in-policy
edit 1
set intf "wan1"
set srcaddr "trusted_admin_subnet"
set dstaddr "all"
set service "HTTPS" "SSH"
set action accept
set schedule "always"
next
end
To see and manage these rules in the interface instead of the CLI, enable the toggle first: config system settings then set gui-local-in-policy enable. If you have never done that, it is worth doing today just to look at what your firewall currently accepts on itself.
Why FortiGate policy order is not what the Policy ID suggests
FortiGate evaluates policies top to bottom by sequence order, not by Policy ID. The Policy ID is a stable identifier assigned at creation and it never changes, but it has nothing to do with the order of evaluation. When you drag a rule in the GUI you change its sequence position, not its ID, which is why a policy with ID 47 can be evaluated before ID 3. The first matching policy wins, so a broad rule placed above a more specific one silently shadows it, and the specific rule shows traffic it will never actually process.
This is one of the most common sources of “the rule is there but it is not working” tickets. Before you troubleshoot a policy, confirm what actually matches by using the built-in Policy Lookup tool, which simulates a packet with the source, destination, port, and interface you specify and tells you which policy handles it. Reading the list top to bottom by eye is not the same as knowing the evaluation result.
Does FortiGate log denied traffic by default?
No. The implicit deny policy that catches everything not matched by an explicit rule does not log by default. That means the traffic your firewall blocks, which is exactly the traffic a security team wants to see during an incident or an audit, is invisible unless you turn logging on. Admins often assume that if something were being blocked they would see it in the logs. On a default FortiGate, they will not.
Risk: A firewall that logs allowed sessions but not denied ones gives you a record of what got through and no record of what was turned away. For frameworks that require reviewable denied-traffic evidence, that gap is an audit finding waiting to happen.
Fix it by enabling logging on the implicit deny path (create an explicit catch-all deny rule at the bottom with logging enabled, or enable violation-traffic logging), and make sure those events are forwarded off-box to a syslog target or SIEM. Logs that only live on the firewall disappear the moment the firewall is the thing that gets compromised.
Why “0 hits” does not mean a policy is unused
A hit count of zero does not prove a policy is unused. FortiGate policy hit counters reset on reboot and when a policy is edited, so a low or zero count frequently reflects a recent reboot or a recent change, not a genuinely dead rule. Teams that clean up “unused” policies on hit count alone eventually remove a rule that only fires during quarterly processing, a failover event, or a maintenance window, and then spend an outage rediscovering why it existed.
Policy hygiene is worth doing, but base it on more than a counter that starts over every time the device restarts. Correlate hit counts with the actual age of the counter, with change history, and with traffic logs over a full business cycle before you decide a rule is safe to retire. Firewall sprawl is real, and we have written about why tracking configuration changes is the foundation of doing cleanup safely.
Why SSL-VPN is Fortinet’s most attacked surface
FortiOS SSL-VPN has been the single most frequently exploited FortiGate component, and it is not close. The same daemon shows up year after year in critical, pre-authentication remote code execution advisories, and several of those CVEs sit in CISA’s Known Exploited Vulnerabilities catalog, which means they were used in real attacks, not just discovered in a lab.
| CVE | Component | Impact | Severity (CVSS) | Year |
|---|---|---|---|---|
| CVE-2024-55591 | FortiOS / FortiProxy auth | Auth bypass, rogue super-admin creation | Critical (9.6) | 2025 |
| CVE-2024-21762 | SSL-VPN | Out-of-bounds write, pre-auth RCE | Critical (9.8) | 2024 |
| CVE-2023-27997 | SSL-VPN | Heap overflow, pre-auth RCE (XORtigate) | Critical (9.8) | 2023 |
| CVE-2022-42475 | SSL-VPN | Heap overflow, pre-auth RCE (zero-day) | Critical (9.8) | 2022 |
| CVE-2022-40684 | Admin interface | Auth bypass, config theft, rogue admins | Critical (9.8) | 2022 |
Fortinet SSL-VPN flaws appear repeatedly in CISA’s Known Exploited Vulnerabilities catalog, including CVE-2024-21762, CVE-2023-27997, and CVE-2022-42475.
Fortinet itself has read the pattern. Beginning in FortiOS 7.6, the vendor started removing SSL-VPN features from lower-memory FortiGate models and now steers customers toward IPsec VPN and Zero Trust Network Access instead. If you are still terminating remote access on FortiGate SSL-VPN, treat rapid patching of that daemon as non-negotiable and plan the migration path rather than waiting for the next advisory to force it.
How Fortinet firewalls actually get compromised
The recurring post-exploitation pattern is configuration modification, not data exfiltration in the moment. Once an attacker gets in through an SSL-VPN overflow or an admin-interface bypass, the reliable next move is to make the access durable and quiet. When Fortinet published guidance for CVE-2022-40684, the indicators of compromise were configuration artifacts: newly created administrative accounts, added SSH public keys, and modified admin settings. The 2025 CVE-2024-55591 exploitation followed the same script, with attackers creating rogue super-admin accounts.
This is the uncomfortable part. None of those changes look like an attack in the traffic logs. A new admin account, an extra SSH key, a widened local-in policy, or a redirected DNS server is a legitimate-looking configuration edit. FortiOS keeps only a limited local revision history, and if the attacker has admin, they can edit or clear what is on the box. The firewall cannot be the sole witness to changes made on the firewall.
Two concrete hardening steps push back on this directly. First, lock every admin account to a source with trusted hosts, so a stolen credential is useless from an attacker’s network:
config system admin
edit "admin"
set trusthost1 203.0.113.0 255.255.255.0
next
end
By default an admin account has a trusted host of 0.0.0.0/0, meaning any source is allowed. Most environments never change it. Second, treat the configuration as a monitored asset with an independent audit trail off the device, so that a rogue admin account or an unexpected SSH key is flagged the moment it appears rather than during the post-incident review. That principle is the whole reason unauthorized firewall changes are a visibility crisis, and it is what change detection is built to solve.
A FortiGate hardening checklist you can run today
- Enable GUI visibility for local-in policies and review exactly what your firewall accepts on itself, especially on WAN interfaces.
- Set trusted hosts on every administrative account. Confirm none are still at 0.0.0.0/0.
- Enable logging for denied traffic and forward all logs off-box to syslog or a SIEM.
- Use Policy Lookup to verify evaluation order rather than reading the list by eye, and hunt for broad rules shadowing specific ones.
- Patch SSL-VPN promptly and plan a migration to IPsec or ZTNA on models where Fortinet is deprecating it.
- Baseline the configuration and alert on any change to admin accounts, SSH keys, local-in policy, and DNS settings.
Frequently asked questions
Can attackers change my FortiGate configuration without triggering an alert?
Yes, by default. FortiGate does not raise an alert simply because an admin account was created or an SSH key was added, and those edits do not appear as suspicious in traffic logs. Real Fortinet exploitation campaigns have relied on exactly this, making configuration changes that look legitimate. Detection requires baselining the config and alerting on change, ideally from a system independent of the firewall.
How do I see and control traffic to the FortiGate itself?
Traffic to the firewall is governed by local-in policies, which are separate from your standard firewall policies and hidden in the GUI unless enabled with set gui-local-in-policy enable. Review them to confirm management access, SSL-VPN, and routing protocols are scoped to trusted sources. Combine local-in policy with trusted hosts on admin accounts for defense in depth.
Should I still use FortiGate SSL-VPN in 2026?
Only with aggressive patching and a plan to move off it. SSL-VPN has been Fortinet’s most exploited component for years, and Fortinet has begun removing it from lower-memory models starting in FortiOS 7.6 in favor of IPsec VPN and ZTNA. If you rely on it, keep the daemon patched the moment advisories drop and prioritize migrating remote access to a less-targeted method.
Does FortiGate keep a full history of configuration changes?
Not a durable one you can rely on for security. FortiGate stores a limited local revision history, but its depth is constrained and an attacker with admin access can alter or clear what lives on the device. For audit and incident response you need change records held off the firewall, where they cannot be edited by whoever compromised it.
How often should I review FortiGate policy order?
Review evaluation order any time you add or move a rule, and audit the full set at least quarterly. Because FortiGate matches on sequence rather than Policy ID and stops at the first match, a single misplaced broad rule can shadow many specific ones. Policy Lookup should be part of your change process, not just your troubleshooting process.
The bottom line
FortiGate is a capable platform, but its most important security details are the ones that do not surface in the everyday policy view. Local-in policies govern access to the box, sequence order decides what actually matches, denied traffic is silent by default, hit counters lie after a reboot, SSL-VPN keeps drawing critical CVEs, and real compromises show up as configuration edits rather than obvious attacks. Every one of those is manageable once you know to look.
The common thread is the configuration. If you can see every change to your FortiGate the moment it happens, with an audit trail that lives off the device, most of these risks turn from blind spots into alerts. That is exactly what CyberX does for Fortinet environments: continuous detection of unauthorized firewall changes, a tamper-evident change record for your PCI DSS and SOC 2 evidence, and multi-tenant visibility for MSPs managing many FortiGates at once. See how the platform works or read our guide to simplifying Fortinet firewall change management.
