cti-python-stix2 icon indicating copy to clipboard operation
cti-python-stix2 copied to clipboard

Extension decorators and registry don't support extensions with multiple 'extension_types'

Open greedy opened this issue 3 years ago • 1 comments

I tried to use the extension decorators to reproduce the extension example from the standard: Adding two new STIX objects and properties to an existing STIX object instance.

The code is as follows:

from stix2.v21 import CustomExtension, CustomObject, CustomObservable, ExtensionDefinition
from stix2.properties import StringProperty, IntegerProperty

EXAMPLE_EXTENSION_ID = 'extension-definition--c5333451-c08c-4c48-be5e-9ad4c947776a'

EXAMPLE_EXTENSION_DEFINITION = ExtensionDefinition(id = EXAMPLE_EXTENSION_ID,
                                                   name = 'Extension My Favorite SDO and Sub-Comp',
                                                   description = 'This schema adds a new object my-favorite-sdo and some sub-component to existing objects',
                                                   created = '2014-02-20T09:16:08.989000Z',
                                                   modified = '2014-02-20T09:16:08.989000Z',
                                                   created_by_ref = 'identity--c1694394-c150-4f80-a69a-59ca5e850df4',
                                                   schema = 'https://www.example.com/schema-newobj-subcomp/v1/schema.json',
                                                   version = '1.2.1',
                                                   extension_types = ['new-sdo','new-sco','property-extension'])

@CustomExtension(
        EXAMPLE_EXTENSION_ID,
        [
            ('rank', IntegerProperty(required=True)),
            ('toxicity', IntegerProperty(required=True)),
        ]
)
class ExamplePropertyExtension:
    extension_type = 'property-extension'

@CustomObject('my-favorite-sdo',
              [
                  ('some_field', StringProperty(required=True)),
                  ],
              extension_name = EXAMPLE_EXTENSION_ID
)
class MyFavoriteSdo:
    pass

@CustomObject('my-favorite-sco',
              [
                  ('some_network_protocol_field', StringProperty(required=True)),
                  ],
              extension_name = EXAMPLE_EXTENSION_ID
)
class MyFavoriteSco:
    pass

sdo = MyFavoriteSdo(id = 'my-favorite-sdo--a5461d2e-7ba9-43ef-9b3e-11471d1ad8da',
                    created = '2014-02-20T09:16:08.989000Z',
                    modified = '2014-02-20T09:16:08.989000Z',
                    name = 'This is the name of my favorite',
                    some_field = 'value')

print(sdo.serialize(pretty=True))

However, the library's extension registry does not support using the same extension id for multiple purposes and throws an exception stix2.exceptions.DuplicateRegistrationError: A(n) Extension with type 'extension-definition--c5333451-c08c-4c48-be5e-9ad4c947776a' already exists and cannot be registered again.

I tried a few alternative approaches that also did not work:

  1. Omitting extension_name for CustomObject and CustomObservable and referencing the extension in the class using with_extension.

    This results in an exception building the SDO: MissingPropertiesError: No values for required properties for ExamplePropertyExtension: (rank, toxicity).

  2. Omitting extension_name and with_extension while using __init__ to populate the extension_type as new-sdo or new-sco, as appropriate. This results in an exception building the SDO: InvalidValueError: Invalid value for ExamplePropertyExtension 'extension_type': must equal 'property-extension'.

As far as I have been able to discern, it is not possible to create these objects using any public API of the library.

greedy avatar Nov 14 '22 17:11 greedy

Just an acknowledgement: yeah, the library doesn't currently support "hybrid" extensions. I think it was just a design oversight. For now, I don't know of an effort to fix/extend the design to cover that type of extension.

chisholm avatar Nov 15 '22 00:11 chisholm