As the year is coming to a close, we have a lot of exciting changes to share from our work this past month:
Chapters
Problem: Securing your business isn't just about the servers that your operations run on. It's also critical to safeguard the many SaaS services your teams rely on. How can you extend policies and security practices to protect this critical infrastructure?
Solution: We've expanded our SaaS security posture management (SSPM) capabilities by introducing resources, security policies, and incident response packs for Google Workspace, Okta, and Slack. These new policies let you codify and continuously apply security policies to these critical SaaS services.
The new okta MQL resource pack allows you to query the state of your Okta organization:
cnquery shell okta --organization <ORG_URL> --token <OKTA_TOKEN>
# display information about the org
okta.organization { * }
# display registered applications
okta.applications { * }
# display all users
okta.users { * }
# display policies
okta.policies.password { id name rules { * } }
The new slack MQL resources allow you to query the state of your Slack workspace.
cnquery shell slack --token <SLACK_TOKEN>
# display team info
slack.team { * }
# display members
slack.users.members { * }
# display bots
slack.users.bots { * }
# display all users
slack.users { * }
# list all users that have no MFA (members + bots)
slack.users.where( has2FA == false) { * }
# list all members that have no MFA
slack.users.members.where( has2FA == false) { * }
# list all conversations and their creators
slack.conversations { name id creator { id name } }
# display user groups (only on Slack paid plan)
slack.userGroups { * }
# display access logs (only on Slack paid plan)
slack.accessLogs { * }
The new googleworkspace MQL resource pack allows you to query the state of your Google Workspace:
cnquery scan googleworkspace --customer-id <CUSTOMER_ID> --impersonated-user-email <EMAIL
>
# list all domains
googleworkspace.domains { * }
# list all groups for your Google Workspace customer
googleworkspace.groups { * }
# find the group for a specific email
googleworkspace.groups.where( email == "myemail@example.com") { * }
# list all users for your Google Workspace customer
googleworkspace.users { * }
# search a specific user
googleworkspace.users.where ( primaryEmail == "myuser@example.com") { * }
# find all users that have Slack authorized
googleworkspace.users.where(tokens.one( displayText == "Slack") ) {
fullName
primaryEmail
}
# list all super admins
googleworkspace.report.users.where(security["isSuperAdmin"] == true) { userEmail }
# check that all users are enrolled with MFA
googleworkspace.report.users.all( security["isS2SvEnrolled"] == true )
Problem: Once you've set up a Kubernetes integration in Mondoo, it's difficult to see the status of the resources, including the version of the operator that's running.
Solution: Mondoo has a whole new Kubernetes integration page to help you understand what's running and what's been detected. This page includes essential status information such as the Kubernetes release, operator release, and the enabled scanning methods. It also includes a quick summary of everything that's been detected by the operator with a link to view operator-scanned assets in the fleet view.
Problem: The Mondoo GitHub Action can rapidly scan content in your CI pipelines, but is slow to install and setup Mondoo Client during each run.
Solution: We have refactored the Mondoo GitHub Action to use our new cnspec container image. Not only do you get our latest command line experience, but also there's no need to install Mondoo Client during your GitHub jobs. This can reduce the time it takes to run your job by 30 seconds to 1 minute, getting you results quicker in your CI pipelines.
Problem: In scan results, it can be hard to understand an asset's location or platform.
Solution: We redesigned the Mondoo asset pages to make finding details about your assets easier. We've combined multiple tabs into a new summarized main page that folds asset metadata into the main view.
We've updated the asset pages to better describe when assets were scanned and when they last checked into the Mondoo Platform. Previously we tracked only the update time, which showed the last time the asset had checked in either through a CLI scan or a non-scanning integration discovery. This led to confusion since some AWS assets looked as though they had just been scanned after the integration discovery ran. You now see both the scan time and the update time so you can better understand how old scan results are and when assets were last seen.
Problem: You have a repository full of Terraform configs or Kubernetes manifests you want to scan, but you don't want to scan them one command at a time.
Solution: Let Mondoo do the heavy lifting: Scan your IaC configs by directory. cnspec automatically finds all the relevant files to scan, even those nested deep in directories.
In this example, cnspec scans all of our Lunalectric repositories to find Kubernetes manifest files in the postgresql and frontend repositories, while ignoring other non-Kubernetes YAML files:
cnspec scan k8s dev/lunalectric/
→ loaded configuration from /Users/tsmith/.config/mondoo/mondoo.yml using source default
→ using service account credentials
→ discover related assets for 1 asset(s)
→ discovery option auto is used. This will detect the assets: cluster, jobs, cronjobs, pods, statefulsets, deployments, replicasets, daemonsets
→ resolved assets resolved-assets=5
→ connecting to asset K8s Manifest lunalectric (code)
██████████████████████████████████████ 100% K8s Manifest lunalectric
→ connecting to asset luna/postgres (k8s-object)
██████████████████████████████████████ 100% luna/postgres
→ connecting to asset luna/luna-frontend (k8s-object)
██████████████████████████████████████ 100% luna/luna-frontend
→ connecting to asset luna/postgres (k8s-object)
██████████████████████████████████████ 100% luna/postgres
→ connecting to asset luna/luna-frontend (k8s-object)
██████████████████████████████████████ 100% luna/luna-frontend
We've extended Mondoo's support for Terraform modules. We already supported any module users reference in Terraform out of the box. MQL now returns the full block for the module if it is included in the HCL files:
cnquery> terraform.modules { block key }
terraform.modules: [
0: {
key: "consul.consul_servers.security_group_rules"
block: null
}
1: {
key: "consul"
block: terraform.block id = terraform.block/modules.tf/1/1
}
2: {
key: "gke"
block: terraform.block id = terraform.block/gke.tf/10/1
}
...
Mondoo now includes a set of new VMware vCloud Director resources to help you secure your VMware infrastructure. Here are a few sample queries:
# display vCloud Director version
asset { platform version build }
asset: {
build: "20079017"
version: "10.4.0"
platform: "vcd"
}
# show all vCenter server
vcd.serverInstances { * }
# list all vCenter organizations
vcd.organizations
# list all external networks
vcd.externalNetworks
For additional use cases, see the VMware Cloud Director Resource Pack MQL documentation.
Problem: To secure your hosts, you want to find available software updates for all platforms.
Solution: Mondoo now exposes os.updates resource data for macOS and Windows hosts. You can now write cnspec policies to ensure systems are fully patched, or use cnquery to remotely identify unpatched systems.
os.updates: [
0: os.update name="MSU_UPDATE_21G217_patch_12.6.1"
1: os.update name="Command Line Tools beta 3 for Xcode"
2: os.update name="Command Line Tools for Xcode"
3: os.update name="Safari16.1MontereyAuto"
]
Problem: The packages installed on your Windows hosts are critical to their security. You want to write a policy that checks for specific packages and package versions.
Solution: Mondoo now includes support for querying MSI packages (and continues to support Appx packages). With cnspec, use the packages resource to write policies enforcing package versions. With cnquery, explore what's installed on hosts:
packages.list: [
0: package name="Python 3.10.4 pip Bootstrap (64-bit)" version="3.10.4150.0"
1: package name="Python 3.10.4 Core Interpreter (64-bit)" version="3.10.4150.0"
2: package name="VMware Tools" version="11.3.0.18090558"
3: package name="Python 3.10.4 Development Libraries (64-bit)" version="3.10.4150.0"
4: package name="Microsoft Visual C++ 2019 X64 Additional Runtime - 14.28.29913" version="14.28.29913"
…
]
Problem: When running cnquery it can be difficult to know which resources are available and what individual resources do.
Solution: We renamed several resources to better match the objects scanned (rather than the underlying technology). This makes it easier to discover resources and navigate your infrastructure with cnquery.
Updated resource names:
- msgraph.beta ⇒ microsoft (MS365 + Azure Active Directory)
- gcloud ⇒ gcp
- azurerm ⇒ azure
Don't worry though; the old resource names still work. You don't need to update policies before rolling out this new release.
Due to popular demand, we have made it easier to remove elements from any array with a very simple call:
> [1,2,3,3,4] - [3,4,5]
[1,2]
Any element in the deletion list—including duplicates—will be removed from the original array. If any array doesn't exist in the original list it is ignored. This covers the most common use case and makes it accessible without a complicated syntax.
The port resource now provides full access to tls information, if TLS is running on a given port. This is accomplished via a TLS handshake across different SSL and TLS configurations. To any users of MQL, accessing TLS on ports is now as simple as typing:
cnquery> ports.listening { port tls{*} }
ports.listening: [{
port: 8080
tls: {
socket: socket protocol="tcp" port=8080 address="127.0.0.1"
ciphers: [
0: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
1: "TLS_RSA_WITH_AES_256_CCM_8"
2: "TLS_RSA_WITH_AES_128_GCM_SHA256"
3: "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"
4: "TLS_CHACHA20_POLY1305_SHA256"
]
versions: [
0: "tls1.3"
1: "tls1.2"
]
…
Additionally, whenever it's used with IPv6, the address now displays correctly. We will add more fine-grained control to the address in the future.
Problem: MQL has erroneously treated empty arrays as "truthy," which led to some unwanted side effects. For example, whenever users typed queries like this:
users.where( name == "none" )
The result of this query, if it is an empty array, would be evaluated as a "pass" for all checks. However, users are most likely to have used this syntax in error to express "users should contain a user with the name 'none'."
Solution: Empty arrays are now evaluated as falsey. The above example, if used in a check, would result in a failure if there is no user with the name 'none'.
Generally we recommend to use assertions like contains, all or none in this case, which test if certain elements exist or don't exist in an array or map. However, if accidentally used with a where clause, MQL no longer causes unwanted side effects. Watch for built-in linting support to better cover these cases in the future.
Query results that return an array now include the array index in the results so you can more easily find flagged issues or dig deeper into specific results.
Mondoo now includes CIS Level 1 and 2 policies for Ubuntu 22.04 and Debian 11.
We rewrote much of the Linux Security policy to improve the reliability of scans when commands cannot run directly. This provides additional security context, particularly audited configuration context when scanning container images and side-scanning AWS instances using EBS volumes. As a bonus, it also reduces CPU and memory use during the scan.
We updated our CIS Linux policies to implement the following controls:
A few noteworthy highlights:
The Mondoo and cnspec CLIs include a new --asset-name flag that allows you to control the name of the asset when registering with the Mondoo Platform.
Mondoo now automatically cleans up service accounts that sit unused for 30 days. This reduces both clutter and the risk of account compromise.
Mondoo now includes packages for Ubuntu, SLES, and Red Hat running on IBM Z mainframes. You can find these packages in our releases repository at releases.mondoo.com.
More enhancements: