Skip to content

Conversation

@SYNchroACK
Copy link

@SYNchroACK SYNchroACK commented Oct 13, 2024

Problem: the existing ObjectFactory when initialized with the default values like created_by_ref, does not handle properly the creation of SCOs, which does not have these default properties (created, created_by_ref, external_references) accordingly to the standard.

image

Test snippet.py:

from stix2.environment import ObjectFactory
from stix2.v21 import DomainName, Identity, Malware

identity = Identity(name="Test", description="Test")

factory = ObjectFactory(created_by_ref=identity.id)

malware = factory.create(Malware, name="dridex", is_family=True)
domain = factory.create(DomainName, value="test.com")

print("Malware: ", malware.name)
print("Domain: ", domain.value)

Without the changes proposed in this pull request:

$ python snippet.py 
Traceback (most recent call last):
  File "/openstix-python/src/stix2/snippet.py", line 9, in <module>
    domain = factory.create(DomainName, value="test.com")
  File "/openstix-python/src/stix2/stix2/environment.py", line 104, in create
    return cls(**properties)
  File "/openstix-python/src/stix2/stix2/v21/base.py", line 15, in __init__
    super(_Observable, self).__init__(**kwargs)
  File "/openstix-python/src/stix2/stix2/base.py", line 381, in __init__
    super(_Observable, self).__init__(**kwargs)
  File "/openstix-python/src/stix2/stix2/base.py", line 157, in __init__
    raise ExtraPropertiesError(cls, custom_kwargs)
stix2.exceptions.ExtraPropertiesError: Unexpected properties for DomainName: (created_by_ref).

With the changes proposed in this pull request:

$ python snippet.py 
Malware:  dridex
Domain:  test.com

@SYNchroACK SYNchroACK changed the title Multiple small/relevant issues Skip unallowed common properties provided by ObjectFactory Oct 15, 2024
@CLAassistant
Copy link

CLAassistant commented Jul 31, 2025

CLA assistant check
All committers have signed the CLA.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where the ObjectFactory class was incorrectly applying default properties (created, created_by_ref, external_references) to STIX Cyber-observable Objects (SCOs), which do not support these properties according to the STIX specification. The fix adds logic to detect when an observable is being created and removes these incompatible properties before instantiation.

Changes:

  • Added property filtering logic in ObjectFactory.create() to remove SCO-incompatible properties
  • Detects observables by checking if "observables" is in the class module name
  • Removes created, created_by_ref, and external_references properties for observable objects

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

properties = copy.deepcopy(self._defaults)

# SCOs do not have these common properties provided by the factory
if "observables" in cls.__module__:
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The module name checking approach using string matching is fragile and could break if module structure changes. Consider using a more robust approach like checking if the class is a subclass of _Observable. You would need to import _Observable from .base and then use: issubclass(cls, _Observable) instead of "observables" in cls.__module__.

Copilot uses AI. Check for mistakes.
if "observables" in cls.__module__:
properties.pop("created", None)
properties.pop("created_by_ref", None)
properties.pop("external_references", None)
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The modified property is also set by the factory's set_default_created() method (see line 61) and should be removed for SCOs since they don't have this property. Add properties.pop("modified", None) to ensure the modified property is also removed for observables.

Suggested change
properties.pop("external_references", None)
properties.pop("external_references", None)
properties.pop("modified", None)

Copilot uses AI. Check for mistakes.
Comment on lines +87 to +92
# SCOs do not have these common properties provided by the factory
if "observables" in cls.__module__:
properties.pop("created", None)
properties.pop("created_by_ref", None)
properties.pop("external_references", None)

Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new functionality for filtering out properties when creating observables lacks test coverage. Consider adding a test that creates an observable (like DomainName) using an ObjectFactory initialized with created_by_ref or created properties to ensure these properties are correctly filtered out.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants