diff --git a/CHANGELOG b/CHANGELOG index 9c2e65f..6fb4c06 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,41 @@ CHANGELOG ========= -2.1.0 - 2020-11-20 +3.0.0 2021-07-13 + +This version aligns with the STIX 2.1 CS 03 (WD12) document, also know as the "OASIS Standard". + +Main Changes +#509 Add Sighting.summary default value +#503 Revamp how STIX content customization is detected and enforced enhancement +#500 fp write for STIX Objects +#492 Drop 'six' dependency (backwards breaking) +#490 Change canonicalization to normalization +#489 Fix observation expression DNF transformer to preserve FOLLOWEDBY order. +#485 Update CustomObservable decorator +#483 add is_sdo() et al functions +#481 Refactor stix2.parsing into more focused modules +#480 Support Pagination in TAXII DataStore +#476 FileSystemsSink.add creates an additional level of directory hierarchy +#458 Versioning refinements +#468 Extensions Support + +Changes for CS03: +#517 Update links in code to current specification +#515 Add new infrastructure-type-ov entries +#514 Update Network Traffic for CS03 +#504 Fix sighting.last_seen check + +Semantic Similarity +#499 Update incident weights for semantic similarity +#496 Similarity/Equivalence Changes +#493 Update the semantic equivalence user guide page +#491 Graph Equivalence Changes + +Testing, etc +#482 Migrate test to GitHub Actions, update test & check configuration + +2.1.0 2020-11-20 * #337 Switches fuzzywuzzy dependency for rapidfuzz (@maxbachmann) * #430 Adds ability to mix single objects and lists in the Bundle constructor @@ -27,15 +61,15 @@ CHANGELOG * #474 Fixes order of object properties when serialized to match examples from the STIX specification -2.0.2 - 2020-07-07 +2.0.2 2020-07-07 * #423 Fixes issue with six dependency. -2.0.1 - 2020-07-06 +2.0.1 2020-07-06 * Fixes issue with PyPI. -2.0.0 - 2020-07-06 +2.0.0 2020-07-06 * #418 Drops support for Python versions older than 3.5 * #397 Drops python-dateutil dependency to just use built-in datetime instead @@ -48,13 +82,13 @@ CHANGELOG * #401 Fixes bug where some objects can be versioned and revoked that shouldn't * #417 Improves efficiency of ListProperty -1.4.0 - 2020-04-03 +1.4.0 2020-04-03 * #347, #355, #356, #357, #358, #360, #362, #369, #370, #379, #374, #384 Updates STIX 2.1 support to CS01 * #376 Fixes bug where registering object of same name would overwrite it; will now raise an error -1.3.1 - 2020-03-06 +1.3.1 2020-03-06 * #322 Adds encoding option FileSystemSource and MemorySource * #354 Adds ability to specify id-contributing properties on custom SCOs @@ -67,7 +101,7 @@ CHANGELOG * #348 Fixes bug with generating deterministic IDs for SCOs * #344 Fixes bug with propagating errors from the pattern validator -1.3.0 - 2020-01-04 +1.3.0 2020-01-04 * #305 Updates support of STIX 2.1 to WD06 * #304 Updates semantic equivalence to latest draft, and allows programmatic @@ -79,13 +113,13 @@ CHANGELOG * #316 Fix socket extension key checking * #317 Fixes checking of Indicator's pattern property based on pattern_version -1.2.1 - 2019-10-16 +1.2.1 2019-10-16 * #301 Adds more detailed debugging semantic equivalence output * #301 Updates semantic equivalence errors * #300 Fixes bug with deterministic IDs for SCOs containing unicode -1.2.0 - 2019-09-25 +1.2.0 2019-09-25 * #268, #271, #273, #275, #283, #285, #290 Changes support of STIX 2.1 to WD05 (CSD02), for all object types * #269 Updates id properties to take a spec_version parameter @@ -94,7 +128,7 @@ CHANGELOG * #286 Fixes handling of custom observable extensions * #287 Fixes bug with timestamp precision preservation in MarkingDefinition objects -1.1.3 - 2019-08-12 +1.1.3 2019-08-12 * #258 Ignores empty values for optional fields * #259 Adds support for lang granular markings @@ -103,32 +137,32 @@ CHANGELOG * #264 Supports accessing objects in bundles via STIX Object IDs * #274 Fixes bug parsing bundle containing custom objects -1.1.2 - 2019-02-13 +1.1.2 2019-02-13 * #86 Adds helper function to Location objects to generate a URL to the location in an online map engine. -1.1.1 - 2019-01-11 +1.1.1 2019-01-11 * #234 Update documentation structure to better navigate between v20/v21 objects * #232 FileSystemStore now raises an exception if you attempt to overwrite an existing file * #236 Fix a serialization problem with the WindowsRegistryKey observable object * #238 Fix a problem with the LanguageContent object not allowing its creation with an empty dictionary -1.1.0 - 2018-12-11 +1.1.0 2018-12-11 -- Most (if not all) STIX 2.1 SDOs/SROs and core objects have been implemented according to the latest CSD/WD document -- There is an implementation for the conversion scales -- #196, #193 Removing duplicate code for: properties, registering objects, parsing objects, custom objects -- #80, #197 Most (if not all) tests created for v20 are also implemented for v21 -- #189 Added extra checks for the pre-commit tool -- #202 It is now possible to pass a Bundle into add() method in Memory datastores +Most (if not all) STIX 2.1 SDOs/SROs and core objects have been implemented according to the latest CSD/WD document +There is an implementation for the conversion scales +#196, #193 Removing duplicate code for: properties, registering objects, parsing objects, custom objects +#80, #197 Most (if not all) tests created for v20 are also implemented for v21 +#189 Added extra checks for the pre-commit tool +#202 It is now possible to pass a Bundle into add() method in Memory datastores -1.0.4 - 2018-11-15 +1.0.4 2018-11-15 * #225 MemorySource fix to support custom objects * #212 More consistency in Observable extensions behavior/error messages -1.0.3 - 2018-10-31 +1.0.3 2018-10-31 * #187 Pickle proof objects * #181 Improvements to error handling for datastores @@ -140,16 +174,16 @@ CHANGELOG * #213 Python 3.7 support * #214 Support for multiple object versions in MemoryStore -1.0.2 - 2018-05-18 +1.0.2 2018-05-18 * Fixes bugs when using allow_custom (#176, #179). -1.0.1 - 2018-04-27 +1.0.1 2018-04-27 * Fixes bug with incorrect TAXII parameters (#169). * Fixes bug with constructing patterns (#171). -1.0.0 - 2018-04-16 +1.0.0 2018-04-16 * Adds the Workbench layer API. * Adds checks to ensure valid type names are provided. @@ -166,11 +200,11 @@ CHANGELOG * Changes `get_dict` to a private function. * `taxii2-client` is now an optional dependency. -0.5.1 - 2018-03-06 +0.5.1 2018-03-06 * Fixes issue with PyPI. -0.5.0 - 2018-03-06 +0.5.0 2018-03-06 * Adds functions to dereference relationships. * Adds a function to get an object's type from its ID. @@ -179,7 +213,7 @@ CHANGELOG with custom properties, and a missing IntrusionSet property. * Drops Python 3.3 support. -0.4.0 - 2017-11-13 +0.4.0 2017-11-13 * Adds `creator_of` function to easily get the Identity that created an object, and a `serialize` function for fast serialization without sorting properties. @@ -188,7 +222,7 @@ CHANGELOG * Includes internal changes to make it easier to support multiple versions of the STIX specification. -0.3.0 - 2017-10-06 +0.3.0 2017-10-06 * Adds data stores, object factory, and the environment layer. * Supports pattern expressions and data markings. @@ -196,17 +230,17 @@ CHANGELOG * Includes support for custom object types, custom properties, custom observable objects, and custom observable extensions. -0.2.0 - 2017-05-31 +0.2.0 2017-05-31 * Adds a TAXII data source. -0.1.0 - 2017-05-22 +0.1.0 2017-05-22 * Include support for serializing/deserializing all STIX objects and Cyber Observable objects. * Markings are supported but not validated. -0.0.1 - 2017-02-24 +0.0.1 2017-02-24 * First packaged version * Supports all SDOs, Relationships, Bundle (not Sightings). diff --git a/README.rst b/README.rst index 662e020..6bc68d4 100644 --- a/README.rst +++ b/README.rst @@ -39,7 +39,7 @@ be set automatically if not provided as keyword arguments. pattern_type="stix", pattern="[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']") -To parse a STIX JSON string into a Python STIX object, use ``parse()``: +To parse a STIX JSON string into a Python STIX object, use ``parse()``. To serialize a STIX object, use ``serialize()``: .. code-block:: python @@ -61,15 +61,15 @@ To parse a STIX JSON string into a Python STIX object, use ``parse()``: "valid_from": "2017-09-26T23:33:39.829952Z" }""") - print(indicator) + print(indicator.serialize(pretty=True)) For more in-depth documentation, please see `https://stix2.readthedocs.io/ `__. STIX 2 Technical Specification Support -------------------------------------- -This version of cti-python-stix2 brings support to `STIX Version 2.1 `__ -published on 20 March 2020 currently at the Committee Specification (CS) level. +This version of cti-python-stix2 brings support to `STIX Version 2.1 `__ +published on 25 January 2021 currently at the Committee Specification (CS) 02 level. The stix2 Python library supports multiple versions of the STIX 2 Technical Specification. The library will be updated to support new Committee @@ -138,9 +138,11 @@ select additional or substitute Maintainers, per `consensus agreements - `Chris Lenk `__; GitHub ID: https://github.com/clenk/; WWW: `MITRE Corporation `__ -- `Emmanuelle Vargas-Gonzalez `__; GitHub ID: - https://github.com/emmanvg/; WWW: `MITRE - Corporation `__ +- `Rich Piazza `__; GitHub ID: + https://github.com/rpiazza/; WWW: `MITRE Corporation `__ + +- `Andy Chisholm `__; GitHub ID: + https://github.com/chisholm/; WWW: `MITRE Corporation `__ - `Jason Keirstead `__; GitHub ID: https://github.com/JasonKeirstead; WWW: `IBM `__ diff --git a/docs/contributing.rst b/docs/contributing.rst index 20cab3a..c676311 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -27,7 +27,7 @@ the repository on GitHub and clone your fork instead of the main repo: git clone https://github.com/yourusername/cti-python-stix2.git -2. Install develoment-related dependencies: +2. Install development-related dependencies: .. prompt:: bash @@ -107,7 +107,7 @@ run: then look at the resulting report in ``htmlcov/index.html``. All commits pushed to the ``master`` branch or submitted as a pull request are -tested with `Travis-CI `_ +tested with `GitHub Actions `_ automatically. Adding a dependency diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 4919452..d390875 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -173,7 +173,7 @@ "indicator = Indicator(name=\"File hash for malware variant\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", " pattern_type=\"stix\")\n", - "print(indicator)" + "print(indicator.serialize(pretty=True))" ] }, { @@ -503,7 +503,7 @@ "\n", "malware = Malware(name=\"Poison Ivy\",\n", " is_family=False)\n", - "print(malware)" + "print(malware.serialize(pretty=True))" ] }, { @@ -627,7 +627,7 @@ "relationship = Relationship(relationship_type='indicates',\n", " source_ref=indicator.id,\n", " target_ref=malware.id)\n", - "print(relationship)" + "print(relationship.serialize(pretty=True))" ] }, { @@ -736,7 +736,7 @@ ], "source": [ "relationship2 = Relationship(indicator, 'indicates', malware)\n", - "print(relationship2)" + "print(relationship2.serialize(pretty=True))" ] }, { @@ -876,7 +876,7 @@ "from stix2 import Bundle\n", "\n", "bundle = Bundle(indicator, malware, relationship)\n", - "print(bundle)" + "print(bundle.serialize(pretty=True))" ] }, { @@ -993,7 +993,7 @@ " resolves_to_refs=[\"mac-addr--43f380fd-37c6-476d-8643-60849bf9240e\"]\n", ")\n", "\n", - "print(ip4)" + "print(ip4.serialize(pretty=True))" ] }, { @@ -1111,7 +1111,7 @@ " resolves_to_refs=[mac_addr_a.id, mac_addr_b.id]\n", ")\n", "\n", - "print(ip4_valid_refs)" + "print(ip4_valid_refs.serialize(pretty=True))" ] } ], diff --git a/docs/guide/custom.ipynb b/docs/guide/custom.ipynb index 8a4ab10..c31e204 100644 --- a/docs/guide/custom.ipynb +++ b/docs/guide/custom.ipynb @@ -201,7 +201,7 @@ " custom_properties={\n", " \"x_foo\": \"bar\"\n", " })\n", - "print(identity)" + "print(identity.serialize(pretty=True))" ] }, { @@ -313,7 +313,7 @@ " identity_class=\"individual\",\n", " x_foo=\"bar\",\n", " allow_custom=True)\n", - "print(identity2)" + "print(identity2.serialize(pretty=True))" ] }, { @@ -533,7 +533,7 @@ ], "source": [ "identity4 = identity3.new_version(x_foo=None)\n", - "print(identity4)" + "print(identity4.serialize(pretty=True))" ] }, { @@ -671,7 +671,7 @@ "source": [ "animal = Animal(species=\"lion\",\n", " animal_class=\"mammal\")\n", - "print(animal)" + "print(animal.serialize(pretty=True))" ] }, { @@ -956,7 +956,7 @@ "\n", "new_observable = NewObservable(a_property=\"something\",\n", " property_2=10)\n", - "print(new_observable)" + "print(new_observable.serialize(pretty=True))" ] }, { @@ -1458,13 +1458,13 @@ " pass\n", "\n", "new_observable_a = NewObservable2(a_property=\"A property\", property_2=2000)\n", - "print(new_observable_a)\n", + "print(new_observable_a.serialize(pretty=True))\n", "\n", "new_observable_b = NewObservable2(a_property=\"A property\", property_2=3000)\n", - "print(new_observable_b)\n", + "print(new_observable_b.serialize(pretty=True))\n", "\n", "new_observable_c = NewObservable2(a_property=\"A different property\", property_2=3000)\n", - "print(new_observable_c)" + "print(new_observable_c.serialize(pretty=True))" ] }, { @@ -1577,9 +1577,9 @@ } ], "source": [ - "from stix2 import File, CustomExtension\n", + "from stix2 import CustomExtension\n", "\n", - "@CustomExtension(File, 'x-new-ext', [\n", + "@CustomExtension('x-new-ext', [\n", " ('property1', properties.StringProperty(required=True)),\n", " ('property2', properties.IntegerProperty()),\n", "])\n", @@ -1588,7 +1588,7 @@ "\n", "new_ext = NewExtension(property1=\"something\",\n", " property2=10)\n", - "print(new_ext)" + "print(new_ext.serialize(pretty=True))" ] }, { @@ -1803,7 +1803,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -1817,7 +1817,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.0a6" + "version": "3.8.1" } }, "nbformat": 4, diff --git a/docs/guide/datastore.ipynb b/docs/guide/datastore.ipynb index 9f8e310..6cad628 100644 --- a/docs/guide/datastore.ipynb +++ b/docs/guide/datastore.ipynb @@ -332,11 +332,11 @@ "\n", "# get an object that is only in the filesystem\n", "intrusion_set = cs.get('intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a')\n", - "print(intrusion_set)\n", + "print(intrusion_set.serialize(pretty=True))\n", "\n", "# get an object that is only in the TAXII collection\n", "ind = cs.get('indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7')\n", - "print(ind)" + "print(ind.serialize(pretty=True))" ] }, { @@ -593,7 +593,7 @@ } ], "source": [ - "print(mem.creator_of(mal))" + "print(mem.creator_of(mal).serialize(pretty=True))" ] }, { diff --git a/docs/guide/environment.ipynb b/docs/guide/environment.ipynb index a3417b5..deb8e71 100644 --- a/docs/guide/environment.ipynb +++ b/docs/guide/environment.ipynb @@ -225,7 +225,7 @@ } ], "source": [ - "print(env.get(\"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7\"))" + "print(env.get(\"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7\").serialize(pretty=True))" ] }, { @@ -360,7 +360,7 @@ "ind = factory.create(Indicator,\n", " pattern_type=\"stix\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n", - "print(ind)" + "print(ind.serialize(pretty=True))" ] }, { @@ -486,7 +486,7 @@ " created_by_ref=None,\n", " pattern_type=\"stix\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n", - "print(ind2)" + "print(ind2.serialize(pretty=True))" ] }, { @@ -593,7 +593,7 @@ " created_by_ref=\"identity--962cabe5-f7f3-438a-9169-585a8c971d12\",\n", " pattern_type=\"stix\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n", - "print(ind3)" + "print(ind3.serialize(pretty=True))" ] }, { @@ -712,7 +712,7 @@ " pattern_type=\"stix\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n", "environ.add(i)\n", - "print(environ.get(i.id))" + "print(environ.get(i.id).serialize(pretty=True))" ] } ], diff --git a/docs/guide/extensions.ipynb b/docs/guide/extensions.ipynb new file mode 100644 index 0000000..9a7505c --- /dev/null +++ b/docs/guide/extensions.ipynb @@ -0,0 +1,808 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "# Delete this cell to re-enable tracebacks\n", + "import sys\n", + "ipython = get_ipython()\n", + "\n", + "def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,\n", + " exception_only=False, running_compiled_code=False):\n", + " etype, value, tb = sys.exc_info()\n", + " value.__cause__ = None # suppress chained exceptions\n", + " return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))\n", + "\n", + "ipython.showtraceback = hide_traceback" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "# JSON output syntax highlighting\n", + "from __future__ import print_function\n", + "from pygments import highlight\n", + "from pygments.lexers import JsonLexer, TextLexer\n", + "from pygments.formatters import HtmlFormatter\n", + "from IPython.display import display, HTML\n", + "from IPython.core.interactiveshell import InteractiveShell\n", + "\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "def json_print(inpt):\n", + " string = str(inpt)\n", + " formatter = HtmlFormatter()\n", + " if string[0] == '{':\n", + " lexer = JsonLexer()\n", + " else:\n", + " lexer = TextLexer()\n", + " return HTML('{}'.format(\n", + " formatter.get_style_defs('.highlight'),\n", + " highlight(string, lexer, formatter)))\n", + "\n", + "globals()['print'] = json_print" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## STIX Extensions\n", + "\n", + "This page is specific for the STIX Extensions mechanism defined in STIX 2.1 CS 03. For the deprecated STIX Customization mechanisms see the [Custom](custom.ipynb) section.\n", + "\n", + "### Top Level Property Extensions\n", + "\n", + "The example below shows how to create an `indicator` object with a `toplevel-property-extension`. Because an unregistered toplevel property extension is present, any unrecognized toplevel properties are assumed to be extension properties. So the library lets them pass. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c",\n",
+       "    "created": "2014-02-20T09:16:08.989Z",\n",
+       "    "modified": "2014-02-20T09:16:08.989Z",\n",
+       "    "name": "File hash for Poison Ivy variant",\n",
+       "    "description": "This file hash indicates that a sample of Poison Ivy is present.",\n",
+       "    "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",\n",
+       "    "pattern_type": "stix",\n",
+       "    "pattern_version": "2.1",\n",
+       "    "valid_from": "2014-02-20T09:00:00Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "extensions": {\n",
+       "        "extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8": {\n",
+       "            "extension_type": "toplevel-property-extension"\n",
+       "        }\n",
+       "    },\n",
+       "    "rank": 5,\n",
+       "    "toxicity": 8\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import stix2\n", + "\n", + "indicator = stix2.v21.Indicator(\n", + " id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n", + " created='2014-02-20T09:16:08.989000Z',\n", + " modified='2014-02-20T09:16:08.989000Z',\n", + " name='File hash for Poison Ivy variant',\n", + " description='This file hash indicates that a sample of Poison Ivy is present.',\n", + " labels=[\n", + " 'malicious-activity',\n", + " ],\n", + " rank=5,\n", + " toxicity=8,\n", + " pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n", + " pattern_type='stix',\n", + " valid_from='2014-02-20T09:00:00.000000Z',\n", + " extensions={\n", + " \"extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8\" : {\n", + " 'extension_type': 'toplevel-property-extension',\n", + " },\n", + " }\n", + ")\n", + "\n", + "print(indicator.serialize(pretty=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using CustomExtension decorator\n", + "\n", + "However, in order to define which properties are actually included with an extension, the `@CustomExtension` decorator can be used to register an extension type and its properties with stix2. Use the `extension_type` class variable to define what kind of extension it is. Then its id can be passed into objects that use this extension." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c",\n",
+       "    "created": "2014-02-20T09:16:08.989Z",\n",
+       "    "modified": "2014-02-20T09:16:08.989Z",\n",
+       "    "name": "File hash for Poison Ivy variant",\n",
+       "    "description": "This file hash indicates that a sample of Poison Ivy is present.",\n",
+       "    "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",\n",
+       "    "pattern_type": "stix",\n",
+       "    "pattern_version": "2.1",\n",
+       "    "valid_from": "2014-02-20T09:00:00Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "extensions": {\n",
+       "        "extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8": {\n",
+       "            "extension_type": "toplevel-property-extension"\n",
+       "        }\n",
+       "    },\n",
+       "    "rank": 5,\n",
+       "    "toxicity": 8\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TOPLEVEL_EXTENSION_DEFINITION_ID = 'extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8'\n", + "\n", + "@stix2.v21.CustomExtension(\n", + " TOPLEVEL_EXTENSION_DEFINITION_ID, [\n", + " ('rank', stix2.properties.IntegerProperty(required=True)),\n", + " ('toxicity', stix2.properties.IntegerProperty(required=True)),\n", + " ],\n", + ")\n", + "class ExtensionTopLevel:\n", + " extension_type = 'toplevel-property-extension'\n", + "\n", + "indicator = stix2.v21.Indicator(\n", + " id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n", + " created='2014-02-20T09:16:08.989000Z',\n", + " modified='2014-02-20T09:16:08.989000Z',\n", + " name='File hash for Poison Ivy variant',\n", + " description='This file hash indicates that a sample of Poison Ivy is present.',\n", + " labels=[\n", + " 'malicious-activity',\n", + " ],\n", + " rank=5,\n", + " toxicity=8,\n", + " pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n", + " pattern_type='stix',\n", + " valid_from='2014-02-20T09:00:00.000000Z',\n", + " extensions={\n", + " TOPLEVEL_EXTENSION_DEFINITION_ID : {\n", + " 'extension_type': 'toplevel-property-extension',\n", + " },\n", + " }\n", + ")\n", + "\n", + "print(indicator.serialize(pretty=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using CustomObservable for Extension Definition\n", + "\n", + "Similarly, when registering new objects via `@CustomObservable` you can pass the `extension-definition` id that defines this new SCO. \n", + "\n", + "---\n", + "**Note:**\n", + "Creating an instance of an extension object **does not** mean it is registered in the library. Please use the appropriate decorator for this step: `@CustomExtension`, `@CustomObject`, `@CustomObservable`, `@CustomMarking`\n", + "\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "my-favorite-sco",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874",\n",
+       "    "name": "This is the name of my favorite SCO",\n",
+       "    "some_network_protocol_field": "value",\n",
+       "    "extensions": {\n",
+       "        "extension-definition--150c1738-28c9-44d0-802d-70523218240b": {\n",
+       "            "extension_type": "new-sco"\n",
+       "        }\n",
+       "    }\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@stix2.v21.CustomObservable(\n", + " 'my-favorite-sco', [\n", + " ('name', stix2.properties.StringProperty(required=True)),\n", + " ('some_network_protocol_field', stix2.properties.StringProperty(required=True)),\n", + " ], ['name', 'some_network_protocol_field'], 'extension-definition--150c1738-28c9-44d0-802d-70523218240b',\n", + ")\n", + "class MyFavSCO:\n", + " pass\n", + "\n", + "my_favorite_sco = MyFavSCO(\n", + " id='my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',\n", + " name='This is the name of my favorite SCO',\n", + " some_network_protocol_field='value',\n", + ")\n", + "\n", + "print(my_favorite_sco.serialize(pretty=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Custom Markings\n", + "\n", + "The example below show how to create a user-defined marking based on an extension. The STIX `marking-definition` object is essentially a base upon which you build the particulars of your marking, via an extension. This is done in the same way as any other extension. Marking definitions are no different in this regard. The below example illustrates an alternative to building the extension entirely as a dictionary: it can also be built by instantiating the registered class." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "marking-definition",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "marking-definition--9155f07c-dd4c-4320-be6a-0701311c3b84",\n",
+       "    "created": "2021-07-12T00:56:31.47566Z",\n",
+       "    "name": "This is the name of my favorite Marking",\n",
+       "    "extensions": {\n",
+       "        "extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff": {\n",
+       "            "extension_type": "property-extension",\n",
+       "            "some_marking_field": "value"\n",
+       "        }\n",
+       "    }\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import stix2\n", + "import stix2.properties\n", + "\n", + "MARKING_EXTENSION_ID = 'extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff'\n", + "\n", + "@stix2.CustomExtension(MARKING_EXTENSION_ID, [\n", + " ('some_marking_field', stix2.properties.StringProperty(required=True))\n", + "])\n", + "class MyFavMarking:\n", + " extension_type = 'property-extension'\n", + "\n", + "my_favorite_marking = stix2.MarkingDefinition(\n", + " name='This is the name of my favorite Marking',\n", + " extensions={\n", + " MARKING_EXTENSION_ID: MyFavMarking(\n", + " some_marking_field='value'\n", + " )\n", + " }\n", + ")\n", + "\n", + "print(my_favorite_marking.serialize(pretty=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using CustomObject for Extension Definition\n", + "\n", + "Similar to the examples above, the same can be done for SDOs and SROs." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "my-favorite-sro",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "my-favorite-sro--d6306d62-c08d-4d78-baf7-11e7a4c9bc36",\n",
+       "    "created": "2021-03-31T22:43:42.807698Z",\n",
+       "    "modified": "2021-03-31T22:43:42.807698Z",\n",
+       "    "name": "My First SRO",\n",
+       "    "some_source_ref": "identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d",\n",
+       "    "some_target_ref": "identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685",\n",
+       "    "extensions": {\n",
+       "        "extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce": {\n",
+       "            "extension_type": "new-sro"\n",
+       "        }\n",
+       "    }\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "invalid_refs = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting', 'foobar']\n", + "\n", + "@stix2.v21.CustomObject(\n", + " 'my-favorite-sro', [\n", + " ('name', stix2.properties.StringProperty(required=False)),\n", + " ('some_source_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n", + " ('some_target_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n", + " ], extension_name='extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', is_sdo=False,\n", + ")\n", + "class MyFavSRO:\n", + " pass\n", + "\n", + "\n", + "my_favorite_sro = MyFavSRO(\n", + " name=\"My First SRO\",\n", + " some_source_ref=\"identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d\",\n", + " some_target_ref=\"identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685\",\n", + ")\n", + "\n", + "print(my_favorite_sro.serialize(pretty=True))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.0a6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/guide/filesystem.ipynb b/docs/guide/filesystem.ipynb index ec09422..a4aa4d0 100644 --- a/docs/guide/filesystem.ipynb +++ b/docs/guide/filesystem.ipynb @@ -262,7 +262,7 @@ "mal = fs.get(\"malware--92ec0cbd-2c30-44a2-b270-73f4ec949841\")\n", "\n", "# for visual purposes\n", - "print(mal)" + "print(mal.serialize(pretty=True))" ] }, { diff --git a/docs/guide/markings.ipynb b/docs/guide/markings.ipynb index 1e1609c..5bc1215 100644 --- a/docs/guide/markings.ipynb +++ b/docs/guide/markings.ipynb @@ -77,8 +77,13 @@ { "data": { "text/html": [ - "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--46498844-7689-4e7b-be25-b119d8401159",\n",
-       "    "created": "2020-06-24T20:55:56.088861Z",\n",
-       "    "modified": "2020-06-24T20:55:56.088861Z",\n",
+       "    "id": "indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1",\n",
+       "    "created": "2021-04-09T13:59:48.911595Z",\n",
+       "    "modified": "2021-04-09T13:59:48.911595Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:55:56.088861Z",\n",
+       "    "valid_from": "2021-04-09T13:59:48.911595Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ]\n",
@@ -176,7 +181,7 @@
     "indicator = Indicator(pattern_type=\"stix\",\n",
     "                      pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
     "                      object_marking_refs=TLP_AMBER)\n",
-    "print(indicator)"
+    "print(indicator.serialize(pretty=True))"
    ]
   },
   {
@@ -194,8 +199,13 @@
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "marking-definition",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44",\n",
-       "    "created": "2020-06-24T20:56:06.779241Z",\n",
+       "    "id": "marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d",\n",
+       "    "created": "2021-04-09T13:59:50.587649Z",\n",
        "    "definition_type": "statement",\n",
        "    "definition": {\n",
        "        "statement": "Copyright 2017, Example Corp"\n",
@@ -290,7 +300,7 @@
     "    definition_type=\"statement\",                                            \n",
     "    definition=StatementMarking(statement=\"Copyright 2017, Example Corp\")\n",
     ")\n",
-    "print(marking_definition)"
+    "print(marking_definition.serialize(pretty=True))"
    ]
   },
   {
@@ -308,8 +318,13 @@
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--75d66696-9960-4229-ba89-2caac50891b3",\n",
-       "    "created": "2020-06-24T20:56:29.80259Z",\n",
-       "    "modified": "2020-06-24T20:56:29.80259Z",\n",
+       "    "id": "indicator--91ed23a6-c5f0-4b16-8369-64cf39f974bf",\n",
+       "    "created": "2021-04-09T13:59:52.602254Z",\n",
+       "    "modified": "2021-04-09T13:59:52.602254Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:56:29.80259Z",\n",
+       "    "valid_from": "2021-04-09T13:59:52.602254Z",\n",
        "    "object_marking_refs": [\n",
-       "        "marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44"\n",
+       "        "marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d"\n",
        "    ]\n",
        "}\n",
        "
\n" @@ -405,7 +420,7 @@ "indicator2 = Indicator(pattern_type=\"stix\",\n", " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", " object_marking_refs=marking_definition)\n", - "print(indicator2)" + "print(indicator2.serialize(pretty=True))" ] }, { @@ -416,8 +431,13 @@ { "data": { "text/html": [ - "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--757ea853-138c-44e2-bb00-e78eebfaa378",\n",
-       "    "created": "2020-06-24T20:56:43.703563Z",\n",
-       "    "modified": "2020-06-24T20:56:43.703563Z",\n",
+       "    "id": "indicator--42ae262e-4839-4c1a-a50a-3a6690623a9d",\n",
+       "    "created": "2021-04-09T13:59:54.207797Z",\n",
+       "    "modified": "2021-04-09T13:59:54.207797Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:56:43.703563Z",\n",
+       "    "valid_from": "2021-04-09T13:59:54.207797Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ]\n",
@@ -513,7 +533,7 @@
     "indicator3 = Indicator(pattern_type=\"stix\",\n",
     "                       pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
     "                       object_marking_refs=\"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\")\n",
-    "print(indicator3)"
+    "print(indicator3.serialize(pretty=True))"
    ]
   },
   {
@@ -525,14 +545,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "malware",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "malware--1752bbec-765a-4711-a304-f0e92ca902ae",\n",
-       "    "created": "2020-06-24T21:21:07.148194Z",\n",
-       "    "modified": "2020-06-24T21:21:07.148194Z",\n",
+       "    "id": "malware--2658ac6a-44e9-44ea-8c8a-d67abae4d0d5",\n",
+       "    "created": "2021-04-09T13:59:56.556801Z",\n",
+       "    "modified": "2021-04-09T13:59:56.556801Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "description": "A ransomware related to ...",\n",
        "    "is_family": false,\n",
        "    "granular_markings": [\n",
        "        {\n",
-       "            "marking_ref": "marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44",\n",
+       "            "marking_ref": "marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d",\n",
        "            "selectors": [\n",
        "                "description"\n",
        "            ]\n",
@@ -629,7 +654,7 @@
        ""
       ]
      },
-     "execution_count": 8,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -650,7 +675,7 @@
     "                          \"marking_ref\": TLP_WHITE\n",
     "                      }\n",
     "                  ])\n",
-    "print(malware)"
+    "print(malware.serialize(pretty=True))"
    ]
   },
   {
@@ -662,7 +687,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [
     {
@@ -706,14 +731,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--46498844-7689-4e7b-be25-b119d8401159",\n",
-       "    "created": "2020-06-24T20:55:56.088861Z",\n",
-       "    "modified": "2020-06-24T21:21:39.898475Z",\n",
+       "    "id": "indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1",\n",
+       "    "created": "2021-04-09T13:59:48.911595Z",\n",
+       "    "modified": "2021-04-09T14:00:01.165749Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:55:56.088861Z",\n",
+       "    "valid_from": "2021-04-09T13:59:48.911595Z",\n",
        "    "object_marking_refs": [\n",
-       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",\n",
-       "        "marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44"\n",
+       "        "marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d",\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator4 = indicator.add_markings(marking_definition)\n", + "print(indicator4.serialize(pretty=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also remove specific markings from STIX objects. This will also create a new version of the object." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "spec_version": "2.1",\n",
+       "    "id": "indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1",\n",
+       "    "created": "2021-04-09T13:59:48.911595Z",\n",
+       "    "modified": "2021-04-09T14:00:03.00911Z",\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "pattern_type": "stix",\n",
+       "    "pattern_version": "2.1",\n",
+       "    "valid_from": "2021-04-09T13:59:48.911595Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ]\n",
        "}\n",
        "
\n" @@ -807,15 +955,15 @@ } ], "source": [ - "indicator4 = indicator.add_markings(marking_definition)\n", - "print(indicator4)" + "indicator5 = indicator4.remove_markings(marking_definition)\n", + "print(indicator5.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "You can also remove specific markings from STIX objects. This will also create a new version of the object." + "The markings on an object can be replaced with a different set of markings:" ] }, { @@ -826,8 +974,13 @@ { "data": { "text/html": [ - "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--46498844-7689-4e7b-be25-b119d8401159",\n",
-       "    "created": "2020-06-24T20:55:56.088861Z",\n",
-       "    "modified": "2020-06-24T21:21:43.529702Z",\n",
+       "    "id": "indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1",\n",
+       "    "created": "2021-04-09T13:59:48.911595Z",\n",
+       "    "modified": "2021-04-09T14:00:04.531083Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:55:56.088861Z",\n",
+       "    "valid_from": "2021-04-09T13:59:48.911595Z",\n",
        "    "object_marking_refs": [\n",
-       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
+       "        "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",\n",
+       "        "marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d"\n",
        "    ]\n",
        "}\n",
        "
\n" @@ -920,15 +1074,17 @@ } ], "source": [ - "indicator5 = indicator4.remove_markings(marking_definition)\n", - "print(indicator5)" + "from stix2 import TLP_GREEN\n", + "\n", + "indicator6 = indicator5.set_markings([TLP_GREEN, marking_definition])\n", + "print(indicator6.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The markings on an object can be replaced with a different set of markings:" + "STIX objects can also be cleared of all markings with [clear_markings()](../api/stix2.markings.rst#stix2.markings.clear_markings):" ] }, { @@ -939,8 +1095,13 @@ { "data": { "text/html": [ - "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--46498844-7689-4e7b-be25-b119d8401159",\n",
-       "    "created": "2020-06-24T20:55:56.088861Z",\n",
-       "    "modified": "2020-06-24T21:21:47.703212Z",\n",
+       "    "id": "indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1",\n",
+       "    "created": "2021-04-09T13:59:48.911595Z",\n",
+       "    "modified": "2021-04-09T14:00:06.512465Z",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:55:56.088861Z",\n",
-       "    "object_marking_refs": [\n",
-       "        "marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44",\n",
-       "        "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da"\n",
-       "    ]\n",
+       "    "valid_from": "2021-04-09T13:59:48.911595Z"\n",
        "}\n",
        "
\n" ], @@ -1033,121 +1190,9 @@ "output_type": "execute_result" } ], - "source": [ - "from stix2 import TLP_GREEN\n", - "\n", - "indicator6 = indicator5.set_markings([TLP_GREEN, marking_definition])\n", - "print(indicator6)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "STIX objects can also be cleared of all markings with [clear_markings()](../api/stix2.markings.rst#stix2.markings.clear_markings):" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
{\n",
-       "    "type": "indicator",\n",
-       "    "spec_version": "2.1",\n",
-       "    "id": "indicator--46498844-7689-4e7b-be25-b119d8401159",\n",
-       "    "created": "2020-06-24T20:55:56.088861Z",\n",
-       "    "modified": "2020-06-24T21:21:53.287178Z",\n",
-       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "pattern_type": "stix",\n",
-       "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T20:55:56.088861Z"\n",
-       "}\n",
-       "
\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ "indicator7 = indicator5.clear_markings()\n", - "print(indicator7)" + "print(indicator7.serialize(pretty=True))" ] }, { @@ -1168,17 +1213,17 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44',\n", - " 'marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da']" + "['marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da',\n", + " 'marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d']" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -1196,7 +1241,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -1205,7 +1250,7 @@ "['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']" ] }, - "execution_count": 15, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -1225,7 +1270,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -1234,7 +1279,7 @@ "['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']" ] }, - "execution_count": 16, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -1250,6 +1295,26 @@ "Finally, you may also check if an object is marked by a specific markings. Again, for granular markings, pass in the selector or list of selectors." ] }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator.is_marked(TLP_AMBER.id)" + ] + }, { "cell_type": "code", "execution_count": 17, @@ -1266,33 +1331,13 @@ "output_type": "execute_result" } ], - "source": [ - "indicator.is_marked(TLP_AMBER.id)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ "malware.is_marked(TLP_WHITE.id, 'name')" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": { "scrolled": true }, @@ -1303,7 +1348,7 @@ "False" ] }, - "execution_count": 19, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -1323,14 +1368,19 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09",\n",
-       "    "created": "2020-06-24T21:35:08.630228Z",\n",
-       "    "modified": "2020-06-24T21:35:08.630228Z",\n",
+       "    "id": "indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15",\n",
+       "    "created": "2021-04-09T14:02:31.991141Z",\n",
+       "    "modified": "2021-04-09T14:02:31.991141Z",\n",
        "    "description": "Una descripcion sobre este indicador",\n",
        "    "indicator_types": [\n",
        "        "malware"\n",
@@ -1410,7 +1460,7 @@
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T21:35:08.630228Z",\n",
+       "    "valid_from": "2021-04-09T14:02:31.991141Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ],\n",
@@ -1435,15 +1485,20 @@
        ""
       ]
      },
-     "execution_count": 20,
+     "execution_count": 19,
      "metadata": {},
      "output_type": "execute_result"
     },
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09",\n",
-       "    "created": "2020-06-24T21:35:08.630228Z",\n",
-       "    "modified": "2020-06-24T21:35:14.54482Z",\n",
+       "    "id": "indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15",\n",
+       "    "created": "2021-04-09T14:02:31.991141Z",\n",
+       "    "modified": "2021-04-09T14:03:11.817032Z",\n",
        "    "description": "Una descripcion sobre este indicador",\n",
        "    "indicator_types": [\n",
        "        "malware"\n",
@@ -1814,7 +1884,7 @@
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T21:35:08.630228Z",\n",
+       "    "valid_from": "2021-04-09T14:02:31.991141Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ]\n",
@@ -1831,7 +1901,8 @@
     }
    ],
    "source": [
-    "print(v21_indicator.clear_markings(\"description\"))  # By default, both types of markings will be removed"
+    "# By default, both types of markings will be removed\n",
+    "print(v21_indicator.clear_markings(\"description\").serialize(pretty=True))"
    ]
   },
   {
@@ -1842,8 +1913,13 @@
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09",\n",
-       "    "created": "2020-06-24T21:35:08.630228Z",\n",
-       "    "modified": "2020-06-24T21:35:39.298138Z",\n",
+       "    "id": "indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15",\n",
+       "    "created": "2021-04-09T14:02:31.991141Z",\n",
+       "    "modified": "2021-04-09T14:03:24.701927Z",\n",
        "    "description": "Una descripcion sobre este indicador",\n",
        "    "indicator_types": [\n",
        "        "malware"\n",
@@ -1923,7 +1999,7 @@
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T21:35:08.630228Z",\n",
+       "    "valid_from": "2021-04-09T14:02:31.991141Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ],\n",
@@ -1949,7 +2025,7 @@
    ],
    "source": [
     "# If lang is False, no lang markings will be removed\n",
-    "print(v21_indicator.clear_markings(\"description\", lang=False))"
+    "print(v21_indicator.clear_markings(\"description\", lang=False).serialize(pretty=True))"
    ]
   },
   {
@@ -1960,8 +2036,13 @@
     {
      "data": {
       "text/html": [
-       "
{\n",
        "    "type": "indicator",\n",
        "    "spec_version": "2.1",\n",
-       "    "id": "indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09",\n",
-       "    "created": "2020-06-24T21:35:08.630228Z",\n",
-       "    "modified": "2020-06-24T21:35:42.684794Z",\n",
+       "    "id": "indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15",\n",
+       "    "created": "2021-04-09T14:02:31.991141Z",\n",
+       "    "modified": "2021-04-09T14:03:29.751985Z",\n",
        "    "description": "Una descripcion sobre este indicador",\n",
        "    "indicator_types": [\n",
        "        "malware"\n",
@@ -2041,7 +2122,7 @@
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
        "    "pattern_type": "stix",\n",
        "    "pattern_version": "2.1",\n",
-       "    "valid_from": "2020-06-24T21:35:08.630228Z",\n",
+       "    "valid_from": "2021-04-09T14:02:31.991141Z",\n",
        "    "object_marking_refs": [\n",
        "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
        "    ],\n",
@@ -2067,7 +2148,7 @@
    ],
    "source": [
     "# If marking_ref is False, no marking-definition markings will be removed\n",
-    "print(v21_indicator.clear_markings(\"description\", marking_ref=False))"
+    "print(v21_indicator.clear_markings(\"description\", marking_ref=False).serialize(pretty=True))"
    ]
   }
  ],
@@ -2087,7 +2168,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.0a6"
+   "version": "3.9.2"
   }
  },
  "nbformat": 4,
diff --git a/docs/guide/memory.ipynb b/docs/guide/memory.ipynb
index d8a7000..cf9f035 100644
--- a/docs/guide/memory.ipynb
+++ b/docs/guide/memory.ipynb
@@ -187,7 +187,7 @@
     "mem.add(ind)\n",
     "\n",
     "# for visual purposes\n",
-    "print(mem.get(ind.id))\n"
+    "print(mem.get(ind.id).serialize(pretty=True))\n"
    ]
   },
   {
@@ -304,7 +304,7 @@
     "mem.add([ind2,ind3, mal])\n",
     "\n",
     "# for visual purposes\n",
-    "print(mem.get(ind3.id))"
+    "print(mem.get(ind3.id).serialize(pretty=True))"
    ]
   },
   {
@@ -412,7 +412,7 @@
     "from stix2 import Filter\n",
     "\n",
     "mal = mem.query([Filter(\"malware_types\",\"=\", \"rootkit\")])[0]\n",
-    "print(mal)"
+    "print(mal.serialize(pretty=True))"
    ]
   },
   {
@@ -533,7 +533,7 @@
     "report = mem_2.get(\"malware--6cee28b8-4d42-4e72-bd77-ea47897672c0\")\n",
     "\n",
     "# for visual purposes\n",
-    "print(report)"
+    "print(report.serialize(pretty=True))"
    ]
   }
  ],
diff --git a/docs/guide/parsing.ipynb b/docs/guide/parsing.ipynb
index 5fd9499..fe4df7d 100644
--- a/docs/guide/parsing.ipynb
+++ b/docs/guide/parsing.ipynb
@@ -64,7 +64,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Parsing STIX content is as easy as calling the [parse()](../api/stix2.parsing.rst#stix2.parsing.parse) function on a JSON string, dictionary, or file-like object. It will automatically determine the type of the object. The STIX objects within `bundle` objects, and any cyber observables contained within `observed-data` objects will be parsed as well.\n",
+    "Parsing STIX content is as easy as calling the [parse()](../api/stix2.parsing.rst#stix2.parsing.parse) function on a JSON string, dictionary, or file-like object. It will automatically determine the type of the object. The STIX objects within `bundle` objects will be parsed as well.\n",
     "\n",
     "**Parsing a string**"
    ]
@@ -77,8 +77,13 @@
     {
      "data": {
       "text/html": [
-       "