Skip to content
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

Some 2.0 Observables can be versioned and revoked #394

Closed
maybe-sybr opened this issue May 18, 2020 · 1 comment · Fixed by #401
Closed

Some 2.0 Observables can be versioned and revoked #394

maybe-sybr opened this issue May 18, 2020 · 1 comment · Fixed by #401

Comments

@maybe-sybr
Copy link
Contributor

There's an interesting allowed behaviour at the moment where observables can have the new_version() and revoke() method called on them without raising an exception. Any v20 observable which has a modified property (specifically Directory, File and WindowsRegistryKey) will quite happily return a new or revoked version to the caller.

This is a kind of unfortunate result of the collision between the datestamping properties from 2.0 observables prior to the changes made in 2.1 when they became top level objects. The misbehaviour doesn't really manifest for observables from v21 because we actually validate the properties specified during instantiation. However, the exceptions which get raised are still not particularly helpful to the confused programmer who has misunderstood the spec (yours truly ;) ).

For a v20.File:

>>> import datetime, stix2
>>> now  = datetime.datetime.now(tz=datetime.timezone.utc)
>>> now
datetime.datetime(2020, 5, 18, 1, 24, 41, 837726, tzinfo=datetime.timezone.utc)
>>> f = stix2.v20.File(name="test", modified=now)
>>> f.new_version()
File(type='file', name='test', modified='2020-05-18T01:24:53.477617Z')
>>> f.revoke()
File(type='file', name='test', modified='2020-05-18T01:24:55.72256Z', revoked=True)

For a v21.File:

>>> import datetime, stix2
>>> now  = datetime.datetime.now(tz=datetime.timezone.utc)
>>> now
datetime.datetime(2020, 5, 18, 1, 26, 11, 66181, tzinfo=datetime.timezone.utc)
>>> try:
...   stix2.v21.File(name="test", modified=now)
... except stix2.exceptions.ExtraPropertiesError as exc:
...   print(exc)
...
Unexpected properties for File: (modified).
>>> f = stix2.v21.File(name="test")
>>> try:
...   f.new_version()
... except KeyError as exc:
...   print(exc)
...
'modified'
>>> try:
...   f.new_version()
... except KeyError as exc:
...   print(repr(exc))
...
KeyError('modified')
>>> try:
...   f.revoke()
... except KeyError as exc:
...   print(repr(exc))
...
KeyError('modified')

It would be nice if we could add an overriding method implementation to stix2.base._Observable to raise a NotImplementedError when these methods are called. I have a patch to do just that on my local copy, but haven't dug into what tests should be added to verify the behaviour. I'm happy to make the changes and make a PR but would also need to sign the CLA beforehand.

@maybe-sybr
Copy link
Contributor Author

maybe-sybr commented May 18, 2020

Having re-read section 3.6 of the 2.1 spec, I now see why the logic is generic enough to handle any object with a modified property. For the record:

In STIX 2.1, SCOs do not explicitly have those three versioning properties. Therefore, a SCO cannot be versioned unless custom properties (discussed in section 11.1) are used. Producers who do this SHOULD use the property names created_by_ref, revoked, created, and modified.

In any case, it would still be nice if the errors were more obvious. Perhaps a check for "modified" in self.object_properties in _Observable.new_version() (and "revoked" for .revoke())? That would still allow v20.Files and co to be versioned though...

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 a pull request may close this issue.

1 participant