REST API for Baseline Creation

Curious, has any headway been made on simplifying adding fixlets to baselines using the REST API? I’m currently in the same boat of trying to automate baseline creation, and dealing with XML is a bit of a pain. I found this script on the forum, but it appears to be a bit dated, and doesn’t work when I import it into my environment.

Having the ability to supply a list of fixlet IDs to add/remove from a baseline would be very helpful.

Yes, for example expand the ‘POST’ action at https://developer.bigfix.com/rest-api/api/baseline.html

You do still have to supply the baseline as an XML document, including source Fixlet id, site, and action name; but when this thread was started back in 2016 one also had to supply the relevance and ActionScript for each component

Gotcha… that helps a lot not having to feed in the action script and relevance statement per fixlet. But now I’m running into another problem… How can I capture the SourceSiteURL for each fixlet?

Currently, I run a query from the autopatch api (same query used to get me a list of applicable updates for all servers in my environment), which provides me with JSON output of the following:

SiteID            : 2
CVE               : N/A
ContentID         : 96764201
SourceReleaseDate : 4/24/2009 12:00:00 AM
ModificationTime  : 7/4/2022 6:20:49 PM
DownloadSize      : 5663504
OperatingSystem   : Office 2007
SiteName          : Enterprise Security
Name              : 967642: You receive an error message when you try to install 2007 Microsoft Office suite service packs - Office 2007
Category          : Critical Updates
SourceSeverity    : Unspecified
SiteDisplayName   : Patches for Windows

I currently fill in SourceSiteURL with [http]://sync.bigfix.com/cgi-bin/bfgather/bessecurity for all components, but when I try to upload the xml, i get the following error which leads me to believe a few fixlets are originating from a different Source Site URL.

Invoke-RestMethod: A baseline component cannot be filled in from source because the provided source link is invalid. (The gather URL of the site of the source, and/or the id of the source, are missing.

Can you provide the query you’re running? I’m not sure which autopatch api things are exposed publicly. I have something similar I can retrieve but it’ll probably be easier if I stick more closely to what you have working already.

What I’m retrieving for my setup is

(
    type of it
    , id of it
    , name of it
    , url of site of it
    , relevance of it
    , content id of (default action of it | action 0 of it)
    , script type of (default action of it | action 0 of it)
    , script of (default action of it | action 0 of it)
    , (if (success on run to completion of (default action of it | action 0 of it)) then "RunToCompletion" else "OriginalRelevance") of it
) of fixlets whose (
    name of it contains "Windows" 
    and exists applicable computers of it 
    and exists default action of it
) of all bes sites whose (name of it = "Enterprise Security") 

Can you give a sample of the baseline fragment you’re trying to POST? For posting here it should be enough to just have the first BaselineComponent

(edit: also, I moved this to a new topic so I don’t have to scroll the old history on it)

So, I’m not using a relevance query, perhaps that’s my issue. I originally configured a patch policy within the WebUI, and because I wanted to achieve parity with what’s being deployed through autopatch and what I put in a baseline, I found that when viewing the list of applicable patches in a patch policy, the browser is navigating to the following URL which outputs a list of applicable updates in JSON format.

https://{bigfix-server-fqdn}/autopatch/api/policy/2/preview/external?pagination=%7B%22page%22:%7B%22itemsPerPage%22:-1,%22offset%22:0%7D%7D&filter=%7B%22patchFilter%22:%7B%22applicable%22:true%7D%7D

I had to figure out how to login to the WebUI and present it with a workable session cookie within PowerShell, but I got the following working in my script.

$BaseURI = "{bigfix-server-fqdn}:52311/api"
$User = "{username}"
$Credential = Get-Credential $User 
$Password = ConvertFrom-SecureString $Credential.Password -AsPlainText
$URLEncodedPassword = [System.Web.HttpUtility]::URLEncode($Password)
$Auth = $User + ':' + $Password
$Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth)
$AuthInfo = [System.Convert]::ToBase64String($Encoded)

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("_csrf", "{csrf-value}", "/", "{bigfix-server-fqdn}")))
$session.Cookies.Add((New-Object System.Net.Cookie("XSRF-TOKEN", "{token-value}", "/", "{bigfix-server-fqdn}")))

Invoke-WebRequest -UseBasicParsing -Uri "{bigfix-server-fqdn}/login" -Method "POST" -WebSession $session -Body "username={username}&password=$URLEncodedPassword" -ContentType "application/x-www-form-urlencoded" | Out-Null

$Content = Invoke-WebRequest -UseBasicParsing -Uri "https://{bigfix-server-fqdn}/autopatch/api/policy/2/preview/external?pagination=%7B%22page%22:%7B%22itemsPerPage%22:-1,%22offset%22:0%7D%7D&filter=%7B%22patchFilter%22:%7B%22applicable%22:true%7D%7D" -WebSession $session 

$UpdateContent = $Content.Content | ConvertFrom-Json | Select-Object -ExpandProperty data
2 Likes

I was able to figure out a path forward. Here’s an example of the JSON output from my autopatch query.

"Category": "Security Update",
"ContentID": 365072093,
"CVE": "CVE-2023-33162; CVE-2023-33161; CVE-2023-33158; CVE-2023-35311; CVE-2023-33151; CVE-2023-33148; CVE-2023-33152; CVE-2023-33149; CVE-2023-33153; CVE-2023-33150",
"DownloadSize": null,
"ModificationTime": "2023-07-18T21:25:30.000Z",
"Name": "Office 365 Version 16.0.16529.20182 Available - Current Channel - Office 365 (English (United States))",
"OperatingSystem": "Office 365",
"SiteDisplayName": "Patches for Windows",
"SiteID": "2",
"SiteName": "Enterprise Security",
"SourceReleaseDate": "2023-07-11T00:00:00.000Z",
"SourceSeverity": "Important"

I was able to grab a list of sites and their respective GatherURLs through the REST API

Invoke-RestMethod -Method Get -Uri https://{bigfix-server-fqdn}:52311/api/sites

Example output:

Name                                          GatherURL
BES Support                                   http://sync.bigfix.com/cgi-bin/bfgather/bessupport
Enterprise Security                           http://sync.bigfix.com/cgi-bin/bfgather/bessecurity
Updates for Windows Applications Extended     http://sync.bigfix.com/cgi-bin/bfgather/updateforwinappextend
Advanced Patching                             http://sync.bigfix.com/cgi-bin/bfgather/advancedpatching
Patching Support                              http://sync.bigfix.com/cgi-bin/bfgather/patchingsupport

From here I was able to get the GatherURL based on the SiteName of my JSON output, and was able to dynamically create the baseline XML and upload the resulting file to BigFix. I would like to add, I wish the BigFix REST API handled everything in JSON. Working with XML is a bit painful.

1 Like

I created a baseline creation automation.

First I made a way to create baselines from a session relevance result of filtered fixlets: besapi/examples/baseline_by_relevance.py at master · jgstew/besapi · GitHub

Then I made a generic baseline plugin that uses a config file to populate one baseline per site with only applicable content: