CrowdStrike / psfalcon

PowerShell for CrowdStrike's OAuth2 APIs
The Unlicense
370 stars 71 forks source link

[ BUG ] `Edit-FalconFirewallGroup` throws error `400: Provided data does not match expectedRuleGroupModifyRequestV1 format` #433

Open cso3026 opened 2 weeks ago

cso3026 commented 2 weeks ago

Using the basic examples from docu results in Provided data does not match expected \u0027RuleGroupModifyRequestV1\u0027 format

Create Rule group with New-FalconFirewallGroup and sample script works well. Altering the rule with any of the samples fails (enable / disable, rename, add rule to group)

(other issue: 2.2.7 seams to bring force casting of DiffOperation hastable to PSCustomObject issue back, 2.2.6 works without but also stops with Error 400 below)

Request-FalconToken -ClientId xxxxxxxxx -ClientSecret xxxxxxxxxxx  -Cloud eu-1 -Verbose
VERBOSE: 22:02:51 [Request-FalconToken] Set TLS 1.2 via [System.Net.Http.HttpClientHandler].
VERBOSE: 22:02:51 [Request-FalconToken] Loaded 'format.json'.
VERBOSE: 22:02:51 [ApiClient.Invoke] POST https://api.eu-1.crowdstrike.com/oauth2/token
VERBOSE: 22:02:51 [ApiClient.Invoke] ContentType=application/x-www-form-urlencoded, Accept=application/json
VERBOSE: 22:02:52 [ApiClient.Invoke] 201: Created
VERBOSE: 22:02:52 [ApiClient.Invoke] Connection=keep-alive, X-Cs-Region=eu-1, X-Cs-Traceid=995e9146-5bda-497b-8c1b-77388a3620a1, X-Ratelimit-Limit=300, X-Ratelimit-Remaining=299, Strict-Transport-Security=max-age=31536000; includeSubDomains, Date=Mon, 11 Nov 2024 21:02:52 GMT, Server=nginx
VERBOSE: 22:02:52 [Request-FalconToken] Authorized until: 11/11/2024 22:32:51

PS C:\Users\APIUser> $Group = Get-FalconFirewallGroup -Filter "name:'API Test rule group'" -Detailed
$Rule = Get-FalconFirewallRule -Id $Group.rule_ids
$Family = ($Rule | Where-Object { $_.name -eq 'Block IP' }).family
$Index = $Group.rule_ids.IndexOf($Family)

Edit-FalconFirewallGroup -Id $Group.id -DiffOperation @([PSCustomObject]@{ op = 'replace'; path = '/enabled'; value = $true }) -Validate -Verbose

VERBOSE: Performing the operation "Get-FalconFirewallGroup" on target "Edit-FalconFirewallGroup".
VERBOSE: 22:02:59 [Get-FalconFirewallRule] /fwmgr/entities/rules/v1:get
VERBOSE: 22:02:59 [ApiClient.Invoke] GET https://api.eu-1.crowdstrike.com/fwmgr/entities/rules/v1?ids=ff958de78a584ab1ba0f3a8740b0b04f
VERBOSE: 22:02:59 [ApiClient.Invoke] Accept=application/json
VERBOSE: 22:02:59 [ApiClient.Invoke] 200: OK
VERBOSE: 22:02:59 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=64ba7bbb-d972-4770-b21a-ab8a544d4bba, X-Ratelimit-Limit=6000, X-Ratelimit-Remaining=5996, Date=Mon, 11 Nov 2024 21:02:59 GMT, Server=nginx
VERBOSE: 22:02:59 [Write-Result] query_time=0.026042453, powered_by=svc-firewallmanager, trace_id=64ba7bbb-d972-4770-b21a-ab8a544d4bba
VERBOSE: 22:02:59 [Edit-FalconFirewallGroup] /fwmgr/entities/rule-groups/validation/v1:patch
VERBOSE: 22:02:59 [ApiClient.Invoke] PATCH https://api.eu-1.crowdstrike.com/fwmgr/entities/rule-groups/validation/v1
VERBOSE: 22:02:59 [ApiClient.Invoke] ContentType=application/json, Accept=application/json
VERBOSE: 22:02:59 [ApiClient.Invoke] {"id":"4610fdc0f39140b39a157bc468b50d66","rule_versions":0,"diff_type":"application/json-patch+json","tracking":"NjI1MzQ6NDM=","rule_ids":"ff958de78a584ab1ba0f3a8740b0b04f","diff_operations":[{"from":null,"op":"replace","path":"/enabled","value":true}]}
VERBOSE: 22:03:00 [ApiClient.Invoke] 400: BadRequest
VERBOSE: 22:03:00 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=5f727035-105e-4397-9813-860530437373, X-Ratelimit-Limit=6000, X-Ratelimit-Remaining=5995, Date=Mon, 11 Nov 2024 21:03:00 GMT, Server=nginx
VERBOSE: 22:03:00 [Write-Result] query_time=0.000715515, writes=, powered_by=svc-firewallmanager, trace_id=5f727035-105e-4397-9813-860530437373
Write-Result : {"code":400,"message":"Provided data does not match expected \u0027RuleGroupModifyRequestV1\u0027 
format"}
At C:\Program Files\WindowsPowerShell\Modules\PSFalcon\2.2.7\private\Private.ps1:687 char:9
+         Write-Result $Object
+         ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (@{resources=Sys...ystem.Object[]}:PSObject) [Write-Result], Exception
    + FullyQualifiedErrorId : Write-Result
Write-Result : {"code":400,"message":"Provided data does not match expected \u0027RuleGroupModifyRequestV1\u0027 format"}
bk-cs commented 1 week ago

Thank you for the report!

I ran into a few different issues that ended up causing the expectedRuleGroupModifyRequestV1 format error, so I've made a few changes to Edit-FalconFirewallGroup to compensate. These changes will be part of the next PSFalcon release.

If you'd like to update your local module before release, you can replace public\fwmgr.ps1 using the steps outlined below.

* EXAMPLE REMOVED PENDING FURTHER FIX *

Please ensure that you close and re-open PowerShell and re-import PSFalcon before testing, and let me know if this does not solve your issue.

cso3026 commented 1 week ago

The fix works for the basic operations like rename and enable/disable, but only when casting the diffoperation parameter (Bug #246)

Edit-FalconFirewallGroup -Id $Group.id -DiffOperation @([PSCustomObject]@{ op = 'replace'; path = '/name'; value = 'API Test Rule Group Renamed' })

Unfortunately adding a rule to a groupit still not work. I tried the copy & paste from the samples and also altered it wth PSCustomObject but it still throws the 400 RuleGroupModifyRequestV1:

    @{
        op = 'add'
        path = '/rules/0'
        value = @{
            temp_id = '1'
            name = 'First rule in a group'
            description = 'Example'
            platform_ids = @('0')
            enabled = $false
            action = 'ALLOW'
            direction = 'IN'
            address_family = 'NONE'
            protocol = '6'
            fields = @(
                @{
                    name = 'network_location'
                    type = 'set'
                    values = @( 'ANY' )
                }
            )
            local_address = @(@{ address = '*'; netmask = 0 })
            remote_address = @(@{ address = '*'; netmask = 0 })
        }
    }
)

Edit-FalconFirewallGroup -Id $Group.id -DiffOperation $DiffOperation -RuleId $RuleId  -RuleVersion $RuleVersion -Verbose -Validate

VERBOSE: Performing the operation "Get-FalconFirewallGroup" on target "Edit-FalconFirewallGroup".
VERBOSE: 10:43:48 [Get-FalconFirewallGroup] /fwmgr/entities/rule-groups/v1:get
VERBOSE: 10:43:48 [ApiClient.Invoke] GET https://api.eu-1.crowdstrike.com/fwmgr/entities/rule-groups/v1?ids=4610fdc0f39140b39a157bc468b50d66
VERBOSE: 10:43:48 [ApiClient.Invoke] Accept=application/json
VERBOSE: 10:43:48 [ApiClient.Invoke] 200: OK
VERBOSE: 10:43:48 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=7647da29-8765-4193-9f5e-97069fc71287, X-Ratelimit-Limit=6000, X-Ratelimit-Remaini
ng=5999, Date=Wed, 13 Nov 2024 09:43:48 GMT, Server=nginx
VERBOSE: 10:43:48 [Write-Result] query_time=0.001778889, powered_by=svc-firewallmanager, trace_id=7647da29-8765-4193-9f5e-97069fc71287
VERBOSE: 10:43:48 [Edit-FalconFirewallGroup] /fwmgr/entities/rule-groups/validation/v1:patch
VERBOSE: 10:43:48 [ApiClient.Invoke] PATCH https://api.eu-1.crowdstrike.com/fwmgr/entities/rule-groups/validation/v1
VERBOSE: 10:43:48 [ApiClient.Invoke] ContentType=application/json, Accept=application/json
VERBOSE: 10:43:48 [ApiClient.Invoke] {"id":"4610fdc0f39140b39a157bc468b50d66","rule_versions":[null,"5"],"diff_type":"application/json-patch+json","tracking":"NjM3OTY6NDM=","rule_ids":["1","ff958de78a584ab1ba0f3a8740b0b04f"],"diff_operations":[{"from":null,"op":null,"path
":null,"value":null}]}
VERBOSE: 10:43:48 [ApiClient.Invoke] 400: BadRequest
VERBOSE: 10:43:48 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=bb919676-e93f-4b06-9da6-bcb8f8e2612d, X-Ratelimit-Limit=6000, X-Ratelimit-Remaini
ng=5998, Date=Wed, 13 Nov 2024 09:43:48 GMT, Server=nginx
VERBOSE: 10:43:48 [Write-Result] query_time=0.000598922, writes=, powered_by=svc-firewallmanager, trace_id=bb919676-e93f-4b06-9da6-bcb8f8e2612d
Write-Result : {"code":400,"message":"Provided data does not match expected \u0027RuleGroupModifyRequestV1\u0027 format"}
At C:\Program Files\WindowsPowerShell\Modules\PSFalcon\2.2.7\private\Private.ps1:687 char:9
+         Write-Result $Object
+         ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (@{resources=Sys...ystem.Object[]}:PSObject) [Write-Result], Exception
    + FullyQualifiedErrorId : Write-Result

$DiffOperation = @(
     @([PSCustomObject]@{
        op = 'add'
        path = '/rules/0'
        value = @{
            temp_id = '1'
            name = 'First rule in a group'
            description = 'Example'
            platform_ids = @('0')
            enabled = $false
            action = 'ALLOW'
            direction = 'IN'
            address_family = 'NONE'
            protocol = '6'
            fields = @(
                @{
                    name = 'network_location'
                    type = 'set'
                    values = @( 'ANY' )
                }
            )
            local_address = @(@{ address = '*'; netmask = 0 })
            remote_address = @(@{ address = '*'; netmask = 0 })
        }
    })
)
$Group = Get-FalconFirewallGroup -Filter "name:'API Test Rule Group Renamed'" -Detailed 
$Rule = Get-FalconFirewallRule -Id $Group.rule_ids
$RuleId = @('1') + $Group.rule_ids
$RuleVersion = @('null') + $Rule.version

Edit-FalconFirewallGroup -Id $Group.id -DiffOperation $DiffOperation -RuleId $RuleId  -RuleVersion $RuleVersion -Verbose -Validate

VERBOSE: Performing the operation "Get-FalconFirewallGroup" on target "Edit-FalconFirewallGroup".
VERBOSE: 10:44:25 [Get-FalconFirewallGroup] /fwmgr/entities/rule-groups/v1:get
VERBOSE: 10:44:25 [ApiClient.Invoke] GET https://api.eu-1.crowdstrike.com/fwmgr/entities/rule-groups/v1?ids=4610fdc0f39140b39a157bc468b50d66
VERBOSE: 10:44:25 [ApiClient.Invoke] Accept=application/json
VERBOSE: 10:44:25 [ApiClient.Invoke] 200: OK
VERBOSE: 10:44:25 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=1ca9321b-6755-4221-bdad-80018efa3757, X-Ratelimit-Limit=6000, X-Ratelimit-Remaini
ng=5994, Date=Wed, 13 Nov 2024 09:44:25 GMT, Server=nginx
VERBOSE: 10:44:25 [Write-Result] query_time=0.00175222, powered_by=svc-firewallmanager, trace_id=1ca9321b-6755-4221-bdad-80018efa3757
VERBOSE: 10:44:25 [Edit-FalconFirewallGroup] /fwmgr/entities/rule-groups/validation/v1:patch
VERBOSE: 10:44:25 [ApiClient.Invoke] PATCH https://api.eu-1.crowdstrike.com/fwmgr/entities/rule-groups/validation/v1
VERBOSE: 10:44:25 [ApiClient.Invoke] ContentType=application/json, Accept=application/json
VERBOSE: 10:44:25 [ApiClient.Invoke] {"id":"4610fdc0f39140b39a157bc468b50d66","rule_versions":[null,"5"],"diff_type":"application/json-patch+json","tracking":"NjM3OTY6NDM=","rule_ids":["1","ff958de78a584ab1ba0f3a8740b0b04f"],"diff_operations":[{"from":null,"op":"add","pat
h":"/rules/0","value":{"temp_id":"1","platform_ids":["0"],"description":"Example","enabled":false,"remote_address":[{"netmask":0,"address":"*"}],"direction":"IN","local_address":[{"netmask":0,"address":"*"}],"name":"First rule in a group","fields":[{"values":["ANY"],"name
":"network_location","type":"set"}],"address_family":"NONE","action":"ALLOW","protocol":"6"}}]}
VERBOSE: 10:44:26 [ApiClient.Invoke] 400: BadRequest
VERBOSE: 10:44:26 [ApiClient.Invoke] Connection=keep-alive, Strict-Transport-Security=max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains, X-Cs-Region=eu-1, X-Cs-Traceid=d1b3b46e-8b0a-4374-b673-13a68327a49e, X-Ratelimit-Limit=6000, X-Ratelimit-Remaini
ng=5993, Date=Wed, 13 Nov 2024 09:44:26 GMT, Server=nginx
VERBOSE: 10:44:26 [Write-Result] query_time=0.0004903, writes=, powered_by=svc-firewallmanager, trace_id=d1b3b46e-8b0a-4374-b673-13a68327a49e
Write-Result : {"code":400,"message":"Provided data does not match expected \u0027RuleGroupModifyRequestV1\u0027 format"}
At C:\Program Files\WindowsPowerShell\Modules\PSFalcon\2.2.7\private\Private.ps1:687 char:9
+         Write-Result $Object
+         ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (@{resources=Sys...ystem.Object[]}:PSObject) [Write-Result], Exception
    + FullyQualifiedErrorId : Write-Result
bk-cs commented 1 week ago

Thank you! I should have tested that.

I can see from your submission that it was failing because it was sending rule_versions as string values when they should have been integers.

I've prepared an updated Edit-FalconFirewallGroup that works with the "create a new rule" and "enable group" examples. I also modified the evaluation of diff_operations to help with the [hashtable] versus [PSCustomObject] issue.

To test this change, please replace public\fwmgr.ps1 using the steps outlined below. Please ensure that you close and re-open PowerShell and re-import PSFalcon before testing.

Import-Module -Name PSFalcon
$ModulePath = (Show-FalconModule).ModulePath
(Invoke-WebRequest -Uri https://raw.githubusercontent.com/CrowdStrike/psfalcon/03b5bc59d85c15fb06b21aebf3035c64149647df/public/fwmgr.ps1 -UseBasicParsing).Content > (Join-Path (Join-Path $ModulePath public) fwmgr.ps1)

If that works for you, please let me know! If it does, I will leave this issue open for other users to apply this fix before the next release.

cso3026 commented 1 week ago

Awesome, all samples works instandly without further ado. Thanks a lot for the fast and complete fix!