diff --git a/stix2/v21/observables.py b/stix2/v21/observables.py index 6011da9..5d8aedd 100644 --- a/stix2/v21/observables.py +++ b/stix2/v21/observables.py @@ -97,6 +97,10 @@ class ExtensionsProperty(DictionaryProperty): class Artifact(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'artifact' _properties = OrderedDict() @@ -116,6 +120,10 @@ class Artifact(_Observable): class AutonomousSystem(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'autonomous-system' _properties = OrderedDict() @@ -129,6 +137,10 @@ class AutonomousSystem(_Observable): class Directory(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'directory' _properties = OrderedDict() @@ -146,6 +158,10 @@ class Directory(_Observable): class DomainName(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'domain-name' _properties = OrderedDict() @@ -158,6 +174,10 @@ class DomainName(_Observable): class EmailAddress(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'email-addr' _properties = OrderedDict() @@ -171,6 +191,10 @@ class EmailAddress(_Observable): class EmailMIMEComponent(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _properties = OrderedDict() _properties.update([ @@ -186,6 +210,10 @@ class EmailMIMEComponent(_STIXBase): class EmailMessage(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'email-message' _properties = OrderedDict() @@ -217,6 +245,10 @@ class EmailMessage(_Observable): class ArchiveExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'archive-ext' _properties = OrderedDict() @@ -228,6 +260,10 @@ class ArchiveExt(_Extension): class AlternateDataStream(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _properties = OrderedDict() _properties.update([ @@ -238,6 +274,10 @@ class AlternateDataStream(_STIXBase): class NTFSExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'ntfs-ext' _properties = OrderedDict() @@ -248,6 +288,10 @@ class NTFSExt(_Extension): class PDFExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'pdf-ext' _properties = OrderedDict() @@ -261,6 +305,10 @@ class PDFExt(_Extension): class RasterImageExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'raster-image-ext' _properties = OrderedDict() @@ -274,6 +322,10 @@ class RasterImageExt(_Extension): class WindowsPEOptionalHeaderType(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _properties = OrderedDict() _properties.update([ @@ -316,6 +368,10 @@ class WindowsPEOptionalHeaderType(_STIXBase): class WindowsPESection(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _properties = OrderedDict() _properties.update([ @@ -327,6 +383,10 @@ class WindowsPESection(_STIXBase): class WindowsPEBinaryExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'windows-pebinary-ext' _properties = OrderedDict() @@ -347,6 +407,10 @@ class WindowsPEBinaryExt(_Extension): class File(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'file' _properties = OrderedDict() @@ -378,6 +442,10 @@ class File(_Observable): class IPv4Address(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'ipv4-addr' _properties = OrderedDict() @@ -391,6 +459,10 @@ class IPv4Address(_Observable): class IPv6Address(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'ipv6-addr' _properties = OrderedDict() @@ -404,6 +476,10 @@ class IPv6Address(_Observable): class MACAddress(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'mac-addr' _properties = OrderedDict() @@ -415,6 +491,10 @@ class MACAddress(_Observable): class Mutex(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'mutex' _properties = OrderedDict() @@ -426,6 +506,10 @@ class Mutex(_Observable): class HTTPRequestExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'http-request-ext' _properties = OrderedDict() @@ -440,6 +524,10 @@ class HTTPRequestExt(_Extension): class ICMPExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'icmp-ext' _properties = OrderedDict() @@ -450,6 +538,10 @@ class ICMPExt(_Extension): class SocketExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'socket-ext' _properties = OrderedDict() @@ -488,6 +580,10 @@ class SocketExt(_Extension): class TCPExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'tcp-ext' _properties = OrderedDict() @@ -498,6 +594,10 @@ class TCPExt(_Extension): class NetworkTraffic(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'network-traffic' _properties = OrderedDict() @@ -529,6 +629,10 @@ class NetworkTraffic(_Observable): class WindowsProcessExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'windows-process-ext' _properties = OrderedDict() @@ -543,6 +647,10 @@ class WindowsProcessExt(_Extension): class WindowsServiceExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'windows-service-ext' _properties = OrderedDict() @@ -578,6 +686,10 @@ class WindowsServiceExt(_Extension): class Process(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'process' _properties = OrderedDict() @@ -616,6 +728,10 @@ class Process(_Observable): class Software(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'software' _properties = OrderedDict() @@ -631,6 +747,10 @@ class Software(_Observable): class URL(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'url' _properties = OrderedDict() @@ -642,6 +762,10 @@ class URL(_Observable): class UNIXAccountExt(_Extension): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'unix-account-ext' _properties = OrderedDict() @@ -654,6 +778,10 @@ class UNIXAccountExt(_Extension): class UserAccount(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'user-account' _properties = OrderedDict() @@ -677,6 +805,10 @@ class UserAccount(_Observable): class WindowsRegistryValueType(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'windows-registry-value-type' _properties = OrderedDict() @@ -702,6 +834,10 @@ class WindowsRegistryValueType(_STIXBase): class WindowsRegistryKey(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'windows-registry-key' _properties = OrderedDict() @@ -723,6 +859,10 @@ class WindowsRegistryKey(_Observable): class X509V3ExtenstionsType(_STIXBase): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'x509-v3-extensions-type' _properties = OrderedDict() @@ -747,6 +887,10 @@ class X509V3ExtenstionsType(_STIXBase): class X509Certificate(_Observable): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'x509-certificate' _properties = OrderedDict() @@ -831,6 +975,11 @@ def parse_observable(data, _valid_refs=None, allow_custom=False): """ obj = _get_dict(data) + # get deep copy since we are going modify the dict and might + # modify the original dict as _get_dict() does not return new + # dict when passed a dict + obj = copy.deepcopy(obj) + obj['_valid_refs'] = _valid_refs or [] if 'type' not in obj: @@ -838,8 +987,12 @@ def parse_observable(data, _valid_refs=None, allow_custom=False): try: obj_class = OBJ_MAP_OBSERVABLE[obj['type']] except KeyError: - raise ParseError("Can't parse unknown observable type '%s'! For custom observables, " - "use the CustomObservable decorator." % obj['type']) + if allow_custom: + # flag allows for unknown custom objects too, but will not + # be parsed into STIX observable object, just returned as is + return obj + raise CustomContentError("Can't parse unknown observable type '%s'! For custom observables, " + "use the CustomObservable decorator." % obj['type']) if 'extensions' in obj and obj['type'] in EXT_MAP: for name, ext in obj['extensions'].items(): @@ -851,6 +1004,7 @@ def parse_observable(data, _valid_refs=None, allow_custom=False): "for observable type '%s'!" % (name, obj['type'])) else: # extension was found obj['extensions'][name] = ext_class(allow_custom=allow_custom, **obj['extensions'][name]) + return obj_class(allow_custom=allow_custom, **obj) @@ -963,9 +1117,7 @@ def CustomExtension(observable=None, type='x-custom-observable', properties=None raise ValueError("Invalid extension type name '%s': must be between 3 and 250 characters." % type) _type = type - _properties = { - 'extensions': ExtensionsProperty(enclosing_type=_type), - } + _properties = OrderedDict() if not properties or not isinstance(properties, list): raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]") diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 223410e..8df3dc3 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -1,6 +1,7 @@ """STIX 2.1 Domain Objects""" from collections import OrderedDict +import re import stix2 @@ -10,7 +11,7 @@ from ..properties import (BooleanProperty, EnumProperty, FloatProperty, IDProperty, IntegerProperty, ListProperty, PatternProperty, ReferenceProperty, StringProperty, TimestampProperty, TypeProperty) -from ..utils import NOW +from ..utils import NOW, TYPE_REGEX from .common import ExternalReference, GranularMarking, KillChainPhase from .observables import ObservableProperty @@ -20,6 +21,10 @@ class STIXDomainObject(_STIXBase, _MarkingsMixin): class AttackPattern(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'attack-pattern' _properties = OrderedDict() @@ -32,7 +37,7 @@ class AttackPattern(STIXDomainObject): ('name', StringProperty(required=True)), ('description', StringProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -43,6 +48,10 @@ class AttackPattern(STIXDomainObject): class Campaign(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'campaign' _properties = OrderedDict() @@ -58,7 +67,7 @@ class Campaign(STIXDomainObject): ('first_seen', TimestampProperty()), ('last_seen', TimestampProperty()), ('objective', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -69,6 +78,10 @@ class Campaign(STIXDomainObject): class CourseOfAction(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'course-of-action' _properties = OrderedDict() @@ -80,7 +93,7 @@ class CourseOfAction(STIXDomainObject): ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -91,6 +104,10 @@ class CourseOfAction(STIXDomainObject): class Identity(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'identity' _properties = OrderedDict() @@ -105,7 +122,7 @@ class Identity(STIXDomainObject): ('identity_class', StringProperty(required=True)), ('sectors', ListProperty(StringProperty)), ('contact_information', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -116,6 +133,10 @@ class Identity(STIXDomainObject): class Indicator(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'indicator' _properties = OrderedDict() @@ -131,7 +152,7 @@ class Indicator(STIXDomainObject): ('valid_from', TimestampProperty(default=lambda: NOW)), ('valid_until', TimestampProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -142,6 +163,10 @@ class Indicator(STIXDomainObject): class IntrusionSet(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'intrusion-set' _properties = OrderedDict() @@ -160,7 +185,7 @@ class IntrusionSet(STIXDomainObject): ('resource_level', StringProperty()), ('primary_motivation', StringProperty()), ('secondary_motivations', ListProperty(StringProperty)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -171,6 +196,10 @@ class IntrusionSet(STIXDomainObject): class Location(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'location' _properties = OrderedDict() @@ -190,7 +219,7 @@ class Location(STIXDomainObject): ('city', StringProperty()), ('street_address', StringProperty()), ('postal_code', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -201,6 +230,10 @@ class Location(STIXDomainObject): class Malware(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'malware' _properties = OrderedDict() @@ -213,7 +246,7 @@ class Malware(STIXDomainObject): ('name', StringProperty(required=True)), ('description', StringProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -224,6 +257,10 @@ class Malware(STIXDomainObject): class Note(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'note' _properties = OrderedDict() @@ -237,7 +274,7 @@ class Note(STIXDomainObject): ('description', StringProperty(required=True)), ('authors', ListProperty(StringProperty)), ('object_refs', ListProperty(ReferenceProperty, required=True)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -248,6 +285,10 @@ class Note(STIXDomainObject): class ObservedData(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'observed-data' _properties = OrderedDict() @@ -261,7 +302,7 @@ class ObservedData(STIXDomainObject): ('last_observed', TimestampProperty(required=True)), ('number_observed', IntegerProperty(required=True)), ('objects', ObservableProperty(required=True)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -270,8 +311,18 @@ class ObservedData(STIXDomainObject): ('granular_markings', ListProperty(GranularMarking)), ]) + def __init__(self, *args, **kwargs): + self.__allow_custom = kwargs.get('allow_custom', False) + self._properties['objects'].allow_custom = kwargs.get('allow_custom', False) + + super(ObservedData, self).__init__(*args, **kwargs) + class Opinion(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'opinion' _properties = OrderedDict() @@ -291,7 +342,7 @@ class Opinion(STIXDomainObject): 'agree', 'strongly-agree' ], required=True)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -302,6 +353,10 @@ class Opinion(STIXDomainObject): class Report(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'report' _properties = OrderedDict() @@ -315,7 +370,7 @@ class Report(STIXDomainObject): ('description', StringProperty()), ('published', TimestampProperty(required=True)), ('object_refs', ListProperty(ReferenceProperty, required=True)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -326,6 +381,10 @@ class Report(STIXDomainObject): class ThreatActor(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'threat-actor' _properties = OrderedDict() @@ -345,7 +404,7 @@ class ThreatActor(STIXDomainObject): ('primary_motivation', StringProperty()), ('secondary_motivations', ListProperty(StringProperty)), ('personal_motivations', ListProperty(StringProperty)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -356,6 +415,10 @@ class ThreatActor(STIXDomainObject): class Tool(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'tool' _properties = OrderedDict() @@ -369,7 +432,7 @@ class Tool(STIXDomainObject): ('description', StringProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), ('tool_version', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -380,6 +443,10 @@ class Tool(STIXDomainObject): class Vulnerability(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'vulnerability' _properties = OrderedDict() @@ -391,7 +458,7 @@ class Vulnerability(STIXDomainObject): ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -430,6 +497,12 @@ def CustomObject(type='x-custom-type', properties=None): class _Custom(cls, STIXDomainObject): + if not re.match(TYPE_REGEX, type): + raise ValueError("Invalid type name '%s': must only contain the " + "characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type) + elif len(type) < 3 or len(type) > 250: + raise ValueError("Invalid type name '%s': must be between 3 and 250 characters." % type) + _type = type _properties = OrderedDict() _properties.update([ @@ -447,7 +520,7 @@ def CustomObject(type='x-custom-type', properties=None): # This is to follow the general properties structure. _properties.update([ - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), diff --git a/stix2/v21/sro.py b/stix2/v21/sro.py index 03f08b7..0a184aa 100644 --- a/stix2/v21/sro.py +++ b/stix2/v21/sro.py @@ -16,6 +16,10 @@ class STIXRelationshipObject(_STIXBase, _MarkingsMixin): class Relationship(STIXRelationshipObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'relationship' _properties = OrderedDict() @@ -29,7 +33,7 @@ class Relationship(STIXRelationshipObject): ('description', StringProperty()), ('source_ref', ReferenceProperty(required=True)), ('target_ref', ReferenceProperty(required=True)), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), @@ -53,6 +57,10 @@ class Relationship(STIXRelationshipObject): class Sighting(STIXRelationshipObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ _type = 'sighting' _properties = OrderedDict() @@ -69,7 +77,7 @@ class Sighting(STIXRelationshipObject): ('observed_data_refs', ListProperty(ReferenceProperty(type="observed-data"))), ('where_sighted_refs', ListProperty(ReferenceProperty(type="identity"))), ('summary', BooleanProperty()), - ('revoked', BooleanProperty()), + ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()),