Non-vulnerable apps showing when filtering by "Vulnerable software" on host details page
Fleet version: v4.63.0 Web browser and operating system: n/a
💥 Actual behavior
All VPP Apps installed on the host are showing as vulnerable when they have no associated vulnerabilities
🧑💻 Steps to reproduce
- Enable VPP for a team and add a few macOS VPP apps in Software >> Add Software
- On an enrolled host with MDM on in that Team, navigate to the host's detail page, click on "Software"
- Filter by "Available for install" and click "Actions" >> Install for the VPP apps added in step 1
- Once the apps have been installed, refetch inventory
- Trigger the vulnerabilities cron, wait for it to finish
- On the host's detail page, click on "Software", then filter by "Vulnerable software"
🕯️ Expected
Only vulnerable software is shown when filtered
@noahtalerman this should probably be resolved asap because it may cause confusion when using this new feature that is being worked on: #22445
@jmwatts thanks for calling this out. If you think we should hop on this ASAP please feel free to add the P2 label: https://fleetdm.com/handbook/company/communications#high-priority-user-stories-and-bugs
I did it this time.
Up to @lukeheath to decide if we can pull this one into the current sprint.
Hey team! Please add your planning poker estimate with Zenhub @iansltx @jahzielv @ksykulev
It's not just VPP apps either from what I can tell? Repro is on @jmwatts's env.
Ah, yep, you're right... not sure if it's reporting on "Installed" software and vulnerable software maybe?
That looks like a reasonable explanation of the behavior we're seeing. Tweaked the title as this is a more generic issue.
There is a piece of the query that is checking if the software has been installed on the host: https://github.com/fleetdm/fleet/blob/main/server/datastore/mysql/software.go#L2271-L2282
This is where we check to see if the software is vulnerable or not. However, later in the query we are attempting to see if the software has been attempted to be installed or uninstalled:
https://github.com/fleetdm/fleet/blob/main/server/datastore/mysql/software.go#L2517
lsia.host_id IS NOT NULL OR lsua.host_id IS NOT NULL OR lvia.host_id IS NOT NULL
It is the combination of this OR that is causing software that is not vulnerable to be surfaced:
-- software is installed on host or software un/install has been attempted
-- on host (via installer or VPP app). If only available for install is
-- requested, then the software installed on host clause is empty.
(
EXISTS (
SELECT 1
FROM
host_software hs
INNER JOIN
software s ON hs.software_id = s.id
INNER JOIN software_cve scve ON scve.software_id = s.id
WHERE
hs.host_id = ? AND
s.title_id = st.id
) OR lsia.host_id IS NOT NULL OR lsua.host_id IS NOT NULL OR lvia.host_id IS NOT NULL )
The filters introduced with https://github.com/fleetdm/fleet/pull/26995 also suffered from this bug. Thus it will be useful to go through the testing criteria for #26995 along with the steps to reproduce listed in this issue.
Upgrading the effort here due to the complex nature of the host details query and the refactor needed to make this change viable.
Notes on call with @mostlikelee
Add 2 hosts. On host 1 install a piece of software that is vulnerable. On host 2 create a software install request for the same software you installed on host 1. Make sure it's left as pending install.
Now go to the host software page for host 1. With "vulnerable filter ON" check to make sure that software is present in the list. Now go to the host software page for host 2. With "vulnerable filter ON" should that software appear in the list?
Repeat the same process with "failed to install" and "available for install"
QA Notes
- Enable VPP for a team and add a few macOS VPP apps in Software >> Add Software
- On an enrolled host with MDM on in that Team, navigate to the host's detail page, click on "Software"
- Filter by "Available for install" and click "Actions" >> Install for the VPP apps added in step 1
- Once the apps have been installed, refetch inventory
- Trigger the vulnerabilities cron, wait for it to finish
- On the host's detail page, click on "Software", then filter by "Vulnerable software"
- [x] Only vulnerable software is shown for this macOS host.
- [x] Tested with combinations of "All software" "Available for install" and Vulnerable software filters on both Windows and Ubuntu hosts as well.
Noticed and filed #27504 while testing this one.
tl;dr
- should we completely exclude pending software when filtering by vulnerability?
- should we attempt to match on different version columns knowing they are from two different places and we might get false negatives.
@noahtalerman @mostlikelee We have a problem with this issue and the fundamental concept of showing "pending vulnerable software"
We currently associate software_installers with software_tiles and software with software_titles. The software_installers table has a version column and the software table has a version column.
The reason we are getting false positives here is we are not comparing those two version columns. What's happening is that when a host has a pending software install we are pulling up ANY of the software records associated to the linked software_title.
Example, we are installing firefox v137.0 (as told by the software installer row)
*************************** 1. row ***************************
id: 822
team_id: 82
global_or_team_id: 82
title_id: 2185
filename: Firefox 137.0.dmg
version: 137.0
platform: darwin
pre_install_query:
install_script_content_id: 753
post_install_script_content_id: NULL
storage_id: bd9bff96ae3701f9c4957675ff3990fcb8306cbb2f6554fb81ad2427b1ec8464
uploaded_at: 2025-04-03 14:24:27.137453
self_service: 1
user_id: 1
user_name: admin
user_email: [email protected]
url:
package_ids:
extension: dmg
uninstall_script_content_id: 14
updated_at: 2025-04-03 14:24:27.137453
fleet_maintained_app_id: 7
install_during_setup: 0
In the software_title table we have:
> select * from software_titles where id = 2185;
+------+-------------+--------+---------+---------------------+-----------------------+---------------------+
| id | name | source | browser | bundle_identifier | additional_identifier | unique_identifier |
+------+-------------+--------+---------+---------------------+-----------------------+---------------------+
| 2185 | Firefox.app | apps | | org.mozilla.firefox | 0 | org.mozilla.firefox |
+------+-------------+--------+---------+---------------------+-----------------------+---------------------+
1 row in set (0.01 sec)
However, because we haven't installed v137, it doesn't exist in the software table yet
+-------------+---------+
| name | version |
+-------------+---------+
| Firefox.app | 134.0.2 |
| Firefox.app | 134.0 |
+-------------+---------+
2 rows in set (0.00 sec)
Firefox 134.0 and/or 134.0.2 might have vulnerabilities, and we are matching on software_title so we know we are install firefox. But we don't have a good way to filter by version.
If we try to match the software_installer.version and the software.version column we may get some false negatives as those version don't necessarily match up. One comes from the installer one comes from osquery software inventory.
@ksykulev IMO if a piece of software isn't in inventory on a host, it isn't vulnerable on that host. "It isn't installed yet but it'll be vulnerable when it is" is out of scope for the current implementation (that would be potentially in scope for #27827). So when filtering to vulnerable software on a host, pending installs flat-out don't matter and should always be omitted.
Vulnerable tags shed, Only truth in software shown, Safety in each thread.