Skip to content

Validate against beats and integrations schemas #2524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 8, 2023

Conversation

Mikaayenson
Copy link
Contributor

@Mikaayenson Mikaayenson commented Feb 7, 2023

Issues

#1994

Summary

  • Follow up to [FR] Add Integration Schema Query Validation #2470 to always validate against ecs and then beats, followed by optionally validating against integration schemas vs prior which validated beats or integrations.
  • Small refactor for readability.
  • Only warns for unit tests.

Testing

During validation rules that have both integrations and beats indexes should validate against both the integration schema and the appropriate beats.

  • Run view-rule on several different integrations and try with multiple min_stack versions.
    • E.g. python -m detection_rules view-rule rules/integrations/google_workspace/collection_google_drive_ownership_transferred_via_google_workspace.toml
    • E.g. python -m detection_rules view-rule rules/integrations/aws/collection_cloudtrail_logging_created.toml
    • E.g. python -m detection_rules view-rule rules/integrations/azure/initial_access_consent_grant_attack_via_azure_registered_application.toml
    • E.g. python -m detection_rules view-rule rules/apm/apm_403_response_to_a_post.toml
  • Run show-latest-compatible to verify command shows latest compatible version.
    • E.g. python -m detection_rules dev integrations show-latest-compatible -p apm -s 8.2.0
  • Run the build-schemas and build-manifest commands to test rebuilding the schemas and manifest
    • E.g. python -m detection_rules dev integrations build-schemas -o
    • E.g. python -m detection_rules dev integrations build-manifests -o
  • Run make test to ensure all unit tests pass.

@@ -223,17 +232,11 @@ def validate_integration(self, data: QueryRuleData, meta: RuleMeta, package_inte
f"{stack_version=}, {ecs_version=}"
)
error_fields[field] = {"error": exc, "trailer": trailer}
print(f"\nWarning: `{field}` in `{data.name}` not found in schema. {trailer}")
if data.get("notify", False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does notify get into data?

Copy link
Contributor Author

@Mikaayenson Mikaayenson Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does notify get into data?

It's a property (set by environment var) similar to how we skip note validation.

Copy link
Contributor

@terrancedejesus terrancedejesus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly beats, ECS and non-ECS will be used for field validation AND if package_integrations is identified, validate with the integrations schemas.

✅ Run view-rule on several different integrations and try with multiple min_stack versions.
✅ Run show-latest-compatible to verify command shows latest compatible version.
✅ Run the build-schemas and build-manifest commands to test rebuilding the schemas and manifest
✅ Run make test to ensure all unit tests pass.

@eric-forte-elastic
Copy link
Contributor

LGTM after manual review and testing.

Tested:
✅ Run view-rule on several different integrations and try with multiple min_stack versions.
✅ Run show-latest-compatible to verify command shows latest compatible version.
✅ Run the build-schemas and build-manifest commands to test rebuilding the schemas and manifest
✅ Run make test to ensure all unit tests pass.

Functional Testing Output
detection-rules on  1994-validate-beats-and-integrations is  v0.1.0 via   on  eric.forte source env/detection-rules-build/bin/activate.fish
> python -m detection_rules view-rule rules/integrations/google_workspace/collection_google_drive_ownership_transferred_via_google_workspace.toml

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

{
  "author": [
    "Elastic"
  ],
  "description": "Drive and Docs is a Google Workspace service that allows users to leverage Google Drive and Google Docs. Access to files is based on inherited permissions from the child organizational unit the user belongs to which is scoped by administrators. Typically if a user is removed, their files can be transferred to another user by the administrator. This service can also be abused by adversaries to transfer files to an adversary account for potential exfiltration.",
  "false_positives": [
    "Administrators may transfer file ownership during employee leave or absence to ensure continued operations by a new or existing employee."
  ],
  "from": "now-130m",
  "index": [
    "filebeat-*",
    "logs-google_workspace*"
  ],
  "interval": "10m",
  "language": "kuery",
  "license": "Elastic License v2",
  "name": "Google Drive Ownership Transferred via Google Workspace",
  "note": "### Important Information Regarding Google Workspace Event Lag Times\n- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.\n- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.\n- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.\n- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).\n- See the following references for further information:\n  - https://support.google.com/a/answer/7061566\n  - https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-google_workspace.html",
  "query": "event.dataset:\"google_workspace.admin\" and event.action:\"CREATE_DATA_TRANSFER_REQUEST\"\n  and event.category:\"iam\" and google_workspace.admin.application.name:Drive*\n",
  "references": [
    "https://support.google.com/a/answer/1247799?hl=en"
  ],
  "related_integrations": [
    {
      "package": "google_workspace",
      "version": "^2.0.0"
    }
  ],
  "required_fields": [
    {
      "ecs": true,
      "name": "event.action",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.category",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.dataset",
      "type": "keyword"
    },
    {
      "ecs": false,
      "name": "google_workspace.admin.application.name",
      "type": "keyword"
    }
  ],
  "risk_score": 47,
  "rule_id": "07b5f85a-240f-11ed-b3d9-f661ea17fbce",
  "setup": "The Google Workspace Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.",
  "severity": "medium",
  "tags": [
    "Elastic",
    "Cloud",
    "Google Workspace",
    "Continuous Monitoring",
    "SecOps",
    "Collection"
  ],
  "threat": [
    {
      "framework": "MITRE ATT&CK",
      "tactic": {
        "id": "TA0009",
        "name": "Collection",
        "reference": "https://attack.mitre.org/tactics/TA0009/"
      },
      "technique": [
        {
          "id": "T1074",
          "name": "Data Staged",
          "reference": "https://attack.mitre.org/techniques/T1074/",
          "subtechnique": [
            {
              "id": "T1074.002",
              "name": "Remote Data Staging",
              "reference": "https://attack.mitre.org/techniques/T1074/002/"
            }
          ]
        }
      ]
    }
  ],
  "timestamp_override": "event.ingested",
  "type": "query",
  "version": 104
}
> python -m detection_rules view-rule rules/integrations/aws/collection_cloudtrail_logging_created.toml

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

{
  "author": [
    "Elastic"
  ],
  "description": "Identifies the creation of an AWS log trail that specifies the settings for delivery of log data.",
  "false_positives": [
    "Trail creations may be made by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Trail creations by unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule."
  ],
  "from": "now-60m",
  "index": [
    "filebeat-*",
    "logs-aws*"
  ],
  "interval": "10m",
  "language": "kuery",
  "license": "Elastic License v2",
  "name": "AWS CloudTrail Log Created",
  "note": "",
  "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:CreateTrail and event.outcome:success\n",
  "references": [
    "https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_CreateTrail.html",
    "https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/create-trail.html"
  ],
  "related_integrations": [
    {
      "integration": "cloudtrail",
      "package": "aws",
      "version": "^1.5.0"
    }
  ],
  "required_fields": [
    {
      "ecs": true,
      "name": "event.action",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.dataset",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.outcome",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.provider",
      "type": "keyword"
    }
  ],
  "risk_score": 21,
  "rule_id": "594e0cbf-86cc-45aa-9ff7-ff27db27d3ed",
  "setup": "The AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.",
  "severity": "low",
  "tags": [
    "Elastic",
    "Cloud",
    "AWS",
    "Continuous Monitoring",
    "SecOps",
    "Log Auditing"
  ],
  "threat": [
    {
      "framework": "MITRE ATT&CK",
      "tactic": {
        "id": "TA0009",
        "name": "Collection",
        "reference": "https://attack.mitre.org/tactics/TA0009/"
      },
      "technique": [
        {
          "id": "T1530",
          "name": "Data from Cloud Storage",
          "reference": "https://attack.mitre.org/techniques/T1530/"
        }
      ]
    }
  ],
  "timestamp_override": "event.ingested",
  "type": "query",
  "version": 102
}
> python -m detection_rules view-rule rules/integrations/azure/initial_access_consent_grant_attack_via_azure_registered_application.toml

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

{
  "author": [
    "Elastic"
  ],
  "description": "Detects when a user grants permissions to an Azure-registered application or when an administrator grants tenant-wide permissions to an application. An adversary may create an Azure-registered application that requests access to data such as contact information, email, or documents.",
  "from": "now-25m",
  "index": [
    "filebeat-*",
    "logs-azure*",
    "logs-o365*"
  ],
  "language": "kuery",
  "license": "Elastic License v2",
  "name": "Possible Consent Grant Attack via Azure-Registered Application",
  "note": "## Triage and analysis\n\n### Investigating Possible Consent Grant Attack via Azure-Registered Application\n\nIn an illicit consent grant attack, the attacker creates an Azure-registered application that requests access to data such as contact information, email, or documents. The attacker then tricks an end user into granting that application consent to access their data either through a phishing attack, or by injecting illicit code into a trusted website. After the illicit application has been granted consent, it has account-level access to data without the need for an organizational account. Normal remediation steps like resetting passwords for breached accounts or requiring multi-factor authentication (MFA) on accounts are not effective against this type of attack, since these are third-party applications and are external to the organization.\n\nOfficial Microsoft guidance for detecting and remediating this attack can be found [here](https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants).\n\n#### Possible investigation steps\n\n- From the Azure AD portal, Review the application that was granted permissions:\n  - Click on the `Review permissions` button on the `Permissions` blade of the application.\n  - An app should require only permissions related to the app's purpose. If that's not the case, the app might be risky.\n  - Apps that require high privileges or admin consent are more likely to be risky.\n- Investigate the app and the publisher. The following characteristics can indicate suspicious apps:\n  -  A low number of downloads.\n  -  Low rating or score or bad comments.\n  -  Apps with a suspicious publisher or website.\n  -  Apps whose last update is not recent. This might indicate an app that is no longer supported.\n- Export and examine the [Oauth app auditing](https://docs.microsoft.com/en-us/defender-cloud-apps/manage-app-permissions#oauth-app-auditing) to identify users affected.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Malicious applications abuse the same workflow used by legitimate apps. Thus, analysts must review each app consent to ensure that only desired apps are granted access.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:\n    - Identify the account role in the cloud environment.\n    - Assess the criticality of affected services and servers.\n    - Work with your IT team to identify and minimize the impact on users.\n    - Identify if the attacker is moving laterally and compromising other accounts, servers, or services.\n    - Identify any regulatory or legal ramifications related to this activity.\n- Disable the malicious application to stop user access and the application access to your data.\n- Revoke the application Oauth consent grant. The `Remove-AzureADOAuth2PermissionGrant` cmdlet can be used to complete this task.\n- Remove the service principal application role assignment. The `Remove-AzureADServiceAppRoleAssignment` cmdlet can be used to complete this task.\n- Revoke the refresh token for all users assigned to the application. Azure provides a [playbook](https://github.com/Azure/Azure-Sentinel/tree/master/Playbooks/Revoke-AADSignInSessions) for this task.\n- [Report](https://docs.microsoft.com/en-us/defender-cloud-apps/manage-app-permissions#send-feedback) the application as malicious to Microsoft.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.\n- Investigate the potential for data compromise from the user's email and file sharing services. Activate your Data Loss incident response playbook.\n- Disable the permission for a user to set consent permission on their behalf.\n  - Enable the [Admin consent request](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-admin-consent-workflow) feature.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).",
  "query": "event.dataset:(azure.activitylogs or azure.auditlogs or o365.audit) and\n  (\n    azure.activitylogs.operation_name:\"Consent to application\" or\n    azure.auditlogs.operation_name:\"Consent to application\" or\n    o365.audit.Operation:\"Consent to application.\"\n  ) and\n  event.outcome:(Success or success)\n",
  "references": [
    "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants?view=o365-worldwide",
    "https://www.cloud-architekt.net/detection-and-mitigation-consent-grant-attacks-azuread/",
    "https://docs.microsoft.com/en-us/defender-cloud-apps/investigate-risky-oauth#how-to-detect-risky-oauth-apps"
  ],
  "related_integrations": [
    {
      "integration": "activitylogs",
      "package": "azure",
      "version": "^1.0.0"
    },
    {
      "package": "azure",
      "version": "^1.0.0"
    },
    {
      "package": "o365",
      "version": "^1.3.0"
    }
  ],
  "required_fields": [
    {
      "ecs": false,
      "name": "azure.activitylogs.operation_name",
      "type": "keyword"
    },
    {
      "ecs": false,
      "name": "azure.auditlogs.operation_name",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.dataset",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "event.outcome",
      "type": "keyword"
    },
    {
      "ecs": false,
      "name": "o365.audit.Operation",
      "type": "keyword"
    }
  ],
  "risk_score": 47,
  "rule_id": "1c6a8c7a-5cb6-4a82-ba27-d5a5b8a40a38",
  "setup": "The Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.",
  "severity": "medium",
  "tags": [
    "Elastic",
    "Cloud",
    "Azure",
    "Continuous Monitoring",
    "Microsoft 365",
    "SecOps",
    "Identity and Access",
    "Investigation Guide"
  ],
  "threat": [
    {
      "framework": "MITRE ATT&CK",
      "tactic": {
        "id": "TA0001",
        "name": "Initial Access",
        "reference": "https://attack.mitre.org/tactics/TA0001/"
      },
      "technique": [
        {
          "id": "T1566",
          "name": "Phishing",
          "reference": "https://attack.mitre.org/techniques/T1566/",
          "subtechnique": [
            {
              "id": "T1566.002",
              "name": "Spearphishing Link",
              "reference": "https://attack.mitre.org/techniques/T1566/002/"
            }
          ]
        }
      ]
    },
    {
      "framework": "MITRE ATT&CK",
      "tactic": {
        "id": "TA0006",
        "name": "Credential Access",
        "reference": "https://attack.mitre.org/tactics/TA0006/"
      },
      "technique": [
        {
          "id": "T1528",
          "name": "Steal Application Access Token",
          "reference": "https://attack.mitre.org/techniques/T1528/"
        }
      ]
    }
  ],
  "timestamp_override": "event.ingested",
  "type": "query",
  "version": 105
}
> python -m detection_rules view-rule rules/apm/apm_403_response_to_a_post.toml

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

{
  "author": [
    "Elastic"
  ],
  "description": "A POST request to a web application returned a 403 response, which indicates the web application declined to process the request because the action requested was not allowed.",
  "false_positives": [
    "Security scans and tests may result in these errors. Misconfigured or buggy applications may produce large numbers of these errors. If the source is unexpected, the user unauthorized, or the request unusual, these may indicate suspicious or malicious activity."
  ],
  "index": [
    "apm-*-transaction*",
    "traces-apm*"
  ],
  "language": "kuery",
  "license": "Elastic License v2",
  "name": "Web Application Suspicious Activity: POST Request Declined",
  "query": "http.response.status_code:403 and http.request.method:post\n",
  "references": [
    "https://en.wikipedia.org/wiki/HTTP_403"
  ],
  "related_integrations": [
    {
      "package": "apm",
      "version": "^8.0.0"
    }
  ],
  "required_fields": [
    {
      "ecs": true,
      "name": "http.request.method",
      "type": "keyword"
    },
    {
      "ecs": true,
      "name": "http.response.status_code",
      "type": "long"
    }
  ],
  "risk_score": 47,
  "rule_id": "a87a4e42-1d82-44bd-b0bf-d9b7f91fb89e",
  "severity": "medium",
  "tags": [
    "Elastic",
    "APM"
  ],
  "timestamp_override": "event.ingested",
  "type": "query",
  "version": 101
}
> python -m detection_rules dev integrations show-latest-compatible -p apm -s 8.2.0

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

Compatible integration version=('8.4.2', ('There is a new integration apm version 8.4.2 available!', 'Update the rule min_stack version from 8.2.0 to 8.4.0 if using new features in this latest version.'))
> python -m detection_rules dev integrations build-schemas -o

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

Building integration schemas...
processing windows
processing gcp


processing okta
processing cyberarkpas
processing system
processing endpoint
processing aws
Unit Test Output
LINTING
./env/detection-rules-build/bin/python -m flake8 tests detection_rules --ignore D203 --max-line-length 120
./env/detection-rules-build/bin/python -m detection_rules test

█▀▀▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄   ▄      █▀▀▄ ▄  ▄ ▄   ▄▄▄ ▄▄▄
█  █ █▄▄  █  █▄▄ █    █   █  █ █ █▀▄ █      █▄▄▀ █  █ █   █▄▄ █▄▄
█▄▄▀ █▄▄  █  █▄▄ █▄▄  █  ▄█▄ █▄█ █ ▀▄█      █ ▀▄ █▄▄█ █▄▄ █▄▄ ▄▄█

=================================================== test session starts ===================================================
platform linux -- Python 3.8.10, pytest-7.2.1, pluggy-1.0.0 -- /tmp/detection-rules/env/detection-rules-build/bin/python
cachedir: .pytest_cache
rootdir: /tmp/detection-rules, configfile: pyproject.toml
plugins: typeguard-2.13.3
collected 117 items                                                                                                       

tests/test_all_rules.py::TestValidRules::test_all_rule_queries_optimized ^TPASSED                                     [  0%]
tests/test_all_rules.py::TestValidRules::test_duplicate_file_names PASSED                                           [  1%]
tests/test_all_rules.py::TestValidRules::test_file_names PASSED                                                     [  2%]
tests/test_all_rules.py::TestValidRules::test_production_rules_have_rta PASSED                                      [  3%]
tests/test_all_rules.py::TestValidRules::test_rule_type_changes PASSED                                              [  4%]
tests/test_all_rules.py::TestValidRules::test_schema_and_dupes PASSED                                               [  5%]
tests/test_all_rules.py::TestThreatMappings::test_duplicated_tactics PASSED                                         [  5%]
tests/test_all_rules.py::TestThreatMappings::test_tactic_to_technique_correlations PASSED                           [  6%]
tests/test_all_rules.py::TestThreatMappings::test_technique_deprecations PASSED                                     [  7%]
tests/test_all_rules.py::TestRuleTags::test_casing_and_spacing PASSED                                               [  8%]
tests/test_all_rules.py::TestRuleTags::test_primary_tactic_as_tag PASSED                                            [  9%]
tests/test_all_rules.py::TestRuleTags::test_required_tags PASSED                                                    [ 10%]
tests/test_all_rules.py::TestRuleTimelines::test_timeline_has_title PASSED                                          [ 11%]
tests/test_all_rules.py::TestRuleFiles::test_rule_file_name_tactic PASSED                                           [ 11%]
tests/test_all_rules.py::TestRuleMetadata::test_deprecated_rules PASSED                                             [ 12%]
tests/test_all_rules.py::TestRuleMetadata::test_integration_tag PASSED                                              [ 13%]
tests/test_all_rules.py::TestRuleMetadata::test_updated_date_newer_than_creation PASSED                             [ 14%]
tests/test_all_rules.py::TestIntegrationRules::test_all_min_stack_rules_have_comment PASSED                         [ 15%]
tests/test_all_rules.py::TestIntegrationRules::test_integration_guide SKIPPED (8.3+ Stacks Have Related Integra...) [ 16%]
tests/test_all_rules.py::TestIntegrationRules::test_rule_demotions PASSED                                           [ 17%]
tests/test_all_rules.py::TestRuleTiming::test_eql_interval_to_maxspan PASSED                                        [ 17%]
tests/test_all_rules.py::TestRuleTiming::test_eql_lookback PASSED                                                   [ 18%]
tests/test_all_rules.py::TestRuleTiming::test_event_override PASSED                                                 [ 19%]
tests/test_all_rules.py::TestRuleTiming::test_required_lookback PASSED                                              [ 20%]
tests/test_all_rules.py::TestLicense::test_elastic_license_only_v2 PASSED                                           [ 21%]
tests/test_all_rules.py::TestIncompatibleFields::test_rule_backports_for_restricted_fields PASSED                   [ 22%]
tests/test_all_rules.py::TestBuildTimeFields::test_build_fields_min_stack PASSED                                    [ 23%]
tests/test_all_rules.py::TestRiskScoreMismatch::test_rule_risk_score_severity_mismatch PASSED                       [ 23%]
tests/test_all_rules.py::TestOsqueryPluginNote::test_note_guide PASSED                                              [ 24%]
tests/test_gh_workflows.py::TestWorkflows::test_matrix_to_lock_version_defaults PASSED                              [ 25%]
tests/test_mappings.py::TestMappings::test_false_positives PASSED                                                   [ 26%]
tests/test_mappings.py::TestMappings::test_true_positives PASSED                                                    [ 27%]
tests/test_mappings.py::TestRTAs::test_rtas_with_triggered_rules_have_uuid PASSED                                   [ 28%]
tests/test_packages.py::TestPackages::test_package_loader_default_configs PASSED                                    [ 29%]
tests/test_packages.py::TestPackages::test_package_loader_production_config PASSED                                  [ 29%]
tests/test_packages.py::TestPackages::test_package_summary PASSED                                                   [ 30%]
tests/test_packages.py::TestPackages::test_rule_versioning PASSED                                                   [ 31%]
tests/test_packages.py::TestRegistryPackage::test_registry_package_config PASSED                                    [ 32%]
tests/test_schemas.py::TestSchemas::test_eql_validation PASSED                                                      [ 33%]
tests/test_schemas.py::TestSchemas::test_query_downgrade_7_x PASSED                                                 [ 34%]
tests/test_schemas.py::TestSchemas::test_query_downgrade_8_x PASSED                                                 [ 35%]
tests/test_schemas.py::TestSchemas::test_threshold_downgrade_7_x PASSED                                             [ 35%]
tests/test_schemas.py::TestSchemas::test_threshold_downgrade_8_x PASSED                                             [ 36%]
tests/test_schemas.py::TestSchemas::test_versioned_downgrade_7_x PASSED                                             [ 37%]
tests/test_schemas.py::TestSchemas::test_versioned_downgrade_8_x PASSED                                             [ 38%]
tests/test_schemas.py::TestVersionLockSchema::test_version_lock_has_nested_previous PASSED                          [ 39%]
tests/test_schemas.py::TestVersionLockSchema::test_version_lock_no_previous PASSED                                  [ 40%]
tests/test_schemas.py::TestVersions::test_stack_schema_map PASSED                                                   [ 41%]
tests/test_toml_formatter.py::TestRuleTomlFormatter::test_formatter_deep PASSED                                     [ 41%]
tests/test_toml_formatter.py::TestRuleTomlFormatter::test_formatter_rule PASSED                                     [ 42%]
tests/test_toml_formatter.py::TestRuleTomlFormatter::test_normalization PASSED                                      [ 43%]
tests/test_utils.py::TestTimeUtils::test_caching PASSED                                                             [ 44%]
tests/test_utils.py::TestTimeUtils::test_event_class_normalization PASSED                                           [ 45%]
tests/test_utils.py::TestTimeUtils::test_schema_multifields PASSED                                                  [ 46%]
tests/test_utils.py::TestTimeUtils::test_time_normalize PASSED                                                      [ 47%]
tests/test_version_locking.py::TestVersionLock::test_previous_entries_gte_current_min_stack PASSED                  [ 47%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_and_query PASSED                                                        [ 48%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_field_exists PASSED                                                     [ 49%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_field_inequality PASSED                                                 [ 50%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_field_match PASSED                                                      [ 51%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_not_query PASSED                                                        [ 52%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_optimizations PASSED                                                    [ 52%]
tests/kuery/test_dsl.py::TestKQLtoDSL::test_or_query PASSED                                                         [ 53%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_and_query PASSED                                                     [ 54%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_boolean_precedence PASSED                                            [ 55%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_field_equals PASSED                                                  [ 56%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_field_inequality PASSED                                              [ 57%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_ip_checks PASSED                                                     [ 58%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_list_of_values PASSED                                                [ 58%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_not_query PASSED                                                     [ 59%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_or_query PASSED                                                      [ 60%]
tests/kuery/test_eql2kql.py::TestEql2Kql::test_wildcard_field PASSED                                                [ 61%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_and_expr PASSED                                                 [ 62%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_and_values PASSED                                               [ 63%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_cidr_match PASSED                                               [ 64%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_field_exists PASSED                                             [ 64%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_flattening PASSED                                               [ 65%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_list_value PASSED                                               [ 66%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_not_value PASSED                                                [ 67%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_or_expr PASSED                                                  [ 68%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_or_values PASSED                                                [ 69%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_quoted_wildcard PASSED                                          [ 70%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_range PASSED                                                    [ 70%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_single_value PASSED                                             [ 71%]
tests/kuery/test_evaluator.py::EvaluatorTests::test_wildcard PASSED                                                 [ 72%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_and_query PASSED                                                     [ 73%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_boolean_precedence PASSED                                            [ 74%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_field_equals PASSED                                                  [ 75%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_field_inequality PASSED                                              [ 76%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_list_of_values PASSED                                                [ 76%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_lone_value PASSED                                                    [ 77%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_nested_query PASSED                                                  [ 78%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_not_query PASSED                                                     [ 79%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_or_query PASSED                                                      [ 80%]
tests/kuery/test_kql2eql.py::TestKql2Eql::test_schema PASSED                                                        [ 81%]
tests/kuery/test_lint.py::LintTests::test_and_not PASSED                                                            [ 82%]
tests/kuery/test_lint.py::LintTests::test_compound PASSED                                                           [ 82%]
tests/kuery/test_lint.py::LintTests::test_double_negate PASSED                                                      [ 83%]
tests/kuery/test_lint.py::LintTests::test_extract_not PASSED                                                        [ 84%]
tests/kuery/test_lint.py::LintTests::test_ip PASSED                                                                 [ 85%]
tests/kuery/test_lint.py::LintTests::test_lint_field PASSED                                                         [ 86%]
tests/kuery/test_lint.py::LintTests::test_lint_precedence PASSED                                                    [ 87%]
tests/kuery/test_lint.py::LintTests::test_merge_fields PASSED                                                       [ 88%]
tests/kuery/test_lint.py::LintTests::test_mixed_demorgans PASSED                                                    [ 88%]
tests/kuery/test_lint.py::LintTests::test_not_demorgans PASSED                                                      [ 89%]
tests/kuery/test_lint.py::LintTests::test_not_or PASSED                                                             [ 90%]
tests/kuery/test_lint.py::LintTests::test_upper_tokens PASSED                                                       [ 91%]
tests/kuery/test_parser.py::ParserTests::test_conversion PASSED                                                     [ 92%]
tests/kuery/test_parser.py::ParserTests::test_date PASSED                                                           [ 93%]
tests/kuery/test_parser.py::ParserTests::test_keyword PASSED                                                        [ 94%]
tests/kuery/test_parser.py::ParserTests::test_list_equals PASSED                                                    [ 94%]
tests/kuery/test_parser.py::ParserTests::test_multiple_types_fail PASSED                                            [ 95%]
tests/kuery/test_parser.py::ParserTests::test_multiple_types_success PASSED                                         [ 96%]
tests/kuery/test_parser.py::ParserTests::test_number_exists PASSED                                                  [ 97%]
tests/kuery/test_parser.py::ParserTests::test_number_wildcard_fail PASSED                                           [ 98%]
tests/kuery/test_parser.py::ParserTests::test_type_family_fail PASSED                                               [ 99%]
tests/kuery/test_parser.py::ParserTests::test_type_family_success PASSED                                            [100%]

==================================================== warnings summary =====================================================
env/detection-rules-build/lib/python3.8/site-packages/_pytest/config/__init__.py:1171
  /tmp/detection-rules/env/detection-rules-build/lib/python3.8/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: typeguard
    self._mark_plugins_for_rewrite(hook)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================= 116 passed, 1 skipped, 1 warning in 26.95s ========================================

@Mikaayenson Mikaayenson merged commit 6011544 into main Feb 8, 2023
@Mikaayenson Mikaayenson deleted the 1994-validate-beats-and-integrations branch February 8, 2023 17:01
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
protectionsmachine pushed a commit that referenced this pull request Feb 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport: auto python Internal python for the repository schema v8.7.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants