CrowdStrike / crimson-falcon

A Shiny Ruby SDK of our Falcon API
https://rubygems.org/gems/crimson-falcon
MIT License
4 stars 1 forks source link

Falcon::DeviceControlPoliciesApi#get_device_control_policies raise ArgumentError when API returns 'action: BLOCK_EXECUTE' #33

Open hiboma opened 2 months ago

hiboma commented 2 months ago

Hello!

True to the title of the issue, I encountered Falcon::DeviceControlPoliciesApi#get_device_control_policies raising an ArgumentError exception when the API returns 'action: BLOCK_EXECUTE'.

How to reproduce

Version

Script

require "dotenv"
require "crimson-falcon"

Dotenv.load

Falcon.configure do |config|
  config.client_id     = ENV["FALCON_CLIENT_ID"]
  config.client_secret = ENV["FALCON_CLIENT_SECRET"]
  config.access_token  = ENV["FALCON_ACCESS_TOKEN"]
end

client = Falcon::DeviceControlPoliciesApi.new
client.get_device_control_policies("<ID>")

Exeception

/Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_usb_class_exceptions_response.rb:160:in `action=': invalid value for "action", must be one of ["FULL_ACCESS", "FULL_BLOCK", "READ_ONLY"]. (ArgumentError)

        fail ArgumentError, "invalid value for \"action\", must be one of #{validator.allowable_values}."
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_usb_class_exceptions_response.rb:210:in `block in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_usb_class_exceptions_response.rb:200:in `each_pair'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_usb_class_exceptions_response.rb:200:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_usb_class_exceptions_response.rb:191:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:292:in `_deserialize'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:243:in `block (2 levels) in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:243:in `map'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:243:in `block in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:236:in `each_pair'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:236:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_settings_resp_v1.rb:227:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_policy_v1.rb:390:in `_deserialize'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_policy_v1.rb:344:in `block in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_policy_v1.rb:334:in `each_pair'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_policy_v1.rb:334:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_policy_v1.rb:325:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:222:in `_deserialize'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:173:in `block (2 levels) in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:173:in `map'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:173:in `block in build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:166:in `each_pair'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:166:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/models/device_control_resp_v1.rb:157:in `build_from_hash'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/api_client.rb:441:in `convert_to_type'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/api_client.rb:401:in `deserialize'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/api_client.rb:91:in `call_api'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/api/device_control_policies_api.rb:277:in `get_device_control_policies_with_http_info'
    from /Users/***/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/crimson-falcon-0.4.1/lib/crimson-falcon/api/device_control_policies_api.rb:227:in `get_device_control_policies'
    from test.rb:13:in `<main>'

Debug Response

D, [2024-04-23T14:18:22.259091 #87072] DEBUG -- : HTTP response body ~BEGIN~
{
 "meta": {
  "query_time": 0.052826759,
  "trace_id": "f8ff7c6e-9c16-4149-aaed-84e246e1da9a"
 },
 "errors": [],
 "resources": [
  {
   "id": "MASKED",
   "cid": "MASKED",
   "name": "USB Mass Storage Allowed",
   "description": "MASKED",
   "platform_name": "Windows",
   "groups": [
    {
     "id": "MASKED",
     "group_type": "staticByID",
     "name": "USB Mass Storage Allowd Group -  Static by host ID ",
     "description": "",
     "assignment_rule": "device_id:['MASKED'],hostname:[]",
     "created_by": "MASKED",
     "created_timestamp": "2024-02-13T11:59:18.171836373Z",
     "modified_by": "MASKED",
     "modified_timestamp": "2024-02-13T12:04:30.72944966Z"
    },
    {
     "id": "MASKED",
     "group_type": "static",
     "name": "USB Mass Storage Allowed Group",
     "description": "MASKED",
     "assignment_rule": "device_id:[],hostname:['MASKED']
     "created_by": "MASKED",
     "created_timestamp": "2024-01-25T05:12:26.418209004Z",
     "modified_by": "api-client-id:9058e7050d534833b8f5a225999e3ca3",
     "modified_timestamp": "2024-03-21T10:16:50.512000481Z"
    }
   ],
   "enabled": true,
   "created_by": "MASKED",
   "created_timestamp": "2024-01-25T05:16:17.716153177Z",
   "modified_by": "MASKED",
   "modified_timestamp": "2024-02-13T11:59:46.149478732Z",
   "settings": {
    "enforcement_mode": "MONITOR_ENFORCE",
    "end_user_notification": "SILENT",
    "classes": [
     {
      "id": "ANY",
      "action": "FULL_ACCESS",
      "exceptions": []
     },
     {
      "id": "AUDIO_VIDEO",
      "action": "FULL_ACCESS",
      "exceptions": []
     },
     {
      "id": "IMAGING",
      "action": "FULL_ACCESS",
      "exceptions": []
     },
     {
      "id": "MASS_STORAGE",
      "action": "BLOCK_EXECUTE",
      "exceptions": []
     },
     {
      "id": "MOBILE",
      "action": "FULL_ACCESS",
      "exceptions": []
     },
     {
      "id": "PRINTER",
      "action": "FULL_ACCESS",
      "exceptions": []
     },
     {
      "id": "WIRELESS",
      "action": "FULL_ACCESS",
      "exceptions": []
     }
    ],
    "enhanced_file_metadata": false
   }
  }
 ]
}
~END~

My guess is that this can be solved if Falcon::DeviceControlPoliciesApi's validator.allowable_values contains BLOCK_EXECUTE.

     {
      "id": "MASS_STORAGE",
      "action": "BLOCK_EXECUTE", <<<<<<<<<<<<<<<<<
      "exceptions": []
     },

Regards.

hiboma commented 2 months ago

As a workaround for now, I created the following monkey patch to avoid the validation exception.

  class DeviceControlUSBClassExceptionsResponse
    def action=(action)
      validator = EnumAttributeValidator.new(
        "String",
        ["FULL_ACCESS", "FULL_BLOCK", "READ_ONLY", "BLOCK_EXECUTE"],
      )
      unless validator.valid?(action)
        raise ArgumentError, "invalid value for \"action\", must be one of #{validator.allowable_values}."
      end

      @action = action
    end
  end

Hopefully upstream will fix the problem!

carlosmmatos commented 2 months ago

@hiboma Thank you for opening up the issue. I will look into this for you soon!