From f79b3c98766b5e330fb0ef1c29e27eca6e5c9f23 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 10 May 2019 10:22:45 -0400 Subject: [PATCH 1/4] Add functionality to _valid_refs to accept actual cyber observable objects instead of just strings with their types --- stix2/base.py | 5 ++++- stix2/test/v21/test_observed_data.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 9fcdf56..a9a801e 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -308,7 +308,10 @@ class _Observable(_STIXBase): allowed_types = prop.valid_types try: - ref_type = self._STIXBase__valid_refs[ref] + try: + ref_type = self._STIXBase__valid_refs[ref].type + except AttributeError: + ref_type = self._STIXBase__valid_refs[ref] except TypeError: raise ValueError("'%s' must be created with _valid_refs as a dict, not a list." % self.__class__.__name__) diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 5d0f9b1..864dd7a 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -940,6 +940,24 @@ def test_ip4_address_example(): assert ip4.resolves_to_refs == ["4", "5"] +def test_ip4_address_valid_refs(): + mac1 = stix2.v21.MACAddress( + value="a1:b2:c3:d4:e5:f6", + ) + mac2 = stix2.v21.MACAddress( + value="a7:b8:c9:d0:e1:f2", + ) + + ip4 = stix2.v21.IPv4Address( + _valid_refs={"1": mac1, "2": mac2}, + value="177.60.40.7", + resolves_to_refs=["1", "2"], + ) + + assert ip4.value == "177.60.40.7" + assert ip4.resolves_to_refs == ["1", "2"] + + def test_ip4_address_example_cidr(): ip4 = stix2.v21.IPv4Address(value="198.51.100.0/24") From 989f17e6732a6ac2e1a9c921977d38c19a152f94 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Fri, 10 May 2019 11:54:59 -0400 Subject: [PATCH 2/4] Add documentation for _valid_refs --- docs/guide/creating.ipynb | 213 ++++++++++++++++++++++++++++++++------ 1 file changed, 182 insertions(+), 31 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 83efb56..b1f92a8 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "created": "2018-04-05T18:32:24.193Z",\n",
-       "    "modified": "2018-04-05T18:32:24.193Z",\n",
+       "    "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "created": "2019-05-10T15:28:49.358Z",\n",
+       "    "modified": "2019-05-10T15:28:49.358Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2018-04-05T18:32:24.193659Z",\n",
+       "    "valid_from": "2019-05-10T15:28:49.358947Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429",\n",
-       "    "created": "2018-04-05T18:32:46.584Z",\n",
-       "    "modified": "2018-04-05T18:32:46.584Z",\n",
+       "    "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
+       "    "created": "2019-05-10T15:29:37.208Z",\n",
+       "    "modified": "2019-05-10T15:29:37.208Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--34ddc7b4-4965-4615-b286-1c8bbaa1e7db",\n",
-       "    "created": "2018-04-05T18:32:49.474Z",\n",
-       "    "modified": "2018-04-05T18:32:49.474Z",\n",
+       "    "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
+       "    "created": "2019-05-10T15:29:44.848Z",\n",
+       "    "modified": "2019-05-10T15:29:44.848Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--0a646403-f7e7-4cfd-b945-cab5cde05857",\n",
-       "    "created": "2018-04-05T18:32:51.417Z",\n",
-       "    "modified": "2018-04-05T18:32:51.417Z",\n",
+       "    "id": "relationship--de00dd44-7685-46b5-bf01-04003a2ee496",\n",
+       "    "created": "2019-05-10T15:29:47.422Z",\n",
+       "    "modified": "2019-05-10T15:29:47.422Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--f83477e5-f853-47e1-a267-43f3aa1bd5b0",\n",
+       "    "id": "bundle--026ce7aa-1a14-4dc3-8dd3-8c2cd4eeaa66",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "            "created": "2018-04-05T18:32:24.193Z",\n",
-       "            "modified": "2018-04-05T18:32:24.193Z",\n",
+       "            "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "            "created": "2019-05-10T15:28:49.358Z",\n",
+       "            "modified": "2019-05-10T15:28:49.358Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2018-04-05T18:32:24.193659Z",\n",
+       "            "valid_from": "2019-05-10T15:28:49.358947Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429",\n",
-       "            "created": "2018-04-05T18:32:46.584Z",\n",
-       "            "modified": "2018-04-05T18:32:46.584Z",\n",
+       "            "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
+       "            "created": "2019-05-10T15:29:37.208Z",\n",
+       "            "modified": "2019-05-10T15:29:37.208Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--34ddc7b4-4965-4615-b286-1c8bbaa1e7db",\n",
-       "            "created": "2018-04-05T18:32:49.474Z",\n",
-       "            "modified": "2018-04-05T18:32:49.474Z",\n",
+       "            "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
+       "            "created": "2019-05-10T15:29:44.848Z",\n",
+       "            "modified": "2019-05-10T15:29:44.848Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "            "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "            "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "            "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -863,6 +863,157 @@
     "bundle = Bundle(indicator, malware, relationship)\n",
     "print(bundle)"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Creating Cyber Observable References\n",
+    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. There are two cases."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Case 1: Specifying the type of the Cyber Observable Objects being referenced\n",
+    "In the following example, the IPv4Address object has its ``resolves_to_refs`` property specified. As per the spec, this property's value must be a list of reference(s) to MACAddress objects. In this case, those references are strings that state the type of the Cyber Observable Object being referenced, and are provided in ``_valid_refs``."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
{\n",
+       "    "type": "ipv4-addr",\n",
+       "    "value": "177.60.40.7",\n",
+       "    "resolves_to_refs": [\n",
+       "        "1",\n",
+       "        "2"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import IPv4Address\n", + "\n", + "ip4 = IPv4Address(\n", + " _valid_refs={\"1\": \"mac-addr\", \"2\": \"mac-addr\"},\n", + " value=\"177.60.40.7\",\n", + " resolves_to_refs=[\"1\", \"2\"]\n", + ")\n", + "\n", + "print(ip4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Case 2: Specifying the name of the Cyber Observable Objects being referenced\n", + "The following example is just like the one provided in Case 1 above, with one key difference: instead of using strings to specify the type of the Cyber Observable Objects being referenced in ``_valid_refs``, the referenced Cyber Observable Objects are created beforehand and then their names are provided in ``_valid_refs``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from stix2 import MACAddress\n", + "\n", + "mac_addr_a = MACAddress(value=\"a1:b2:c3:d4:e5:f6\")\n", + "mac_addr_b = MACAddress(value=\"a7:b8:c9:d0:e1:f2\")\n", + "\n", + "ip4_valid_refs = IPv4Address(\n", + " _valid_refs={\"1\": mac_addr_a, \"2\": mac_addr_b},\n", + " value=\"177.60.40.7\",\n", + " resolves_to_refs=[\"1\", \"2\"]\n", + ")\n", + "\n", + "print(ip4_valid_refs)" + ] } ], "metadata": { @@ -881,7 +1032,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.6.7" } }, "nbformat": 4, From 894630852702b2b3409911489050dc29ccd93829 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Fri, 10 May 2019 12:30:52 -0400 Subject: [PATCH 3/4] Updated documentation for _valid_refs --- docs/guide/creating.ipynb | 154 ++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 32 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index b1f92a8..5be60ed 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "created": "2019-05-10T15:28:49.358Z",\n",
-       "    "modified": "2019-05-10T15:28:49.358Z",\n",
+       "    "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "created": "2019-05-10T16:25:11.193Z",\n",
+       "    "modified": "2019-05-10T16:25:11.193Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2019-05-10T15:28:49.358947Z",\n",
+       "    "valid_from": "2019-05-10T16:25:11.193329Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
-       "    "created": "2019-05-10T15:29:37.208Z",\n",
-       "    "modified": "2019-05-10T15:29:37.208Z",\n",
+       "    "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
+       "    "created": "2019-05-10T16:25:29.127Z",\n",
+       "    "modified": "2019-05-10T16:25:29.127Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
-       "    "created": "2019-05-10T15:29:44.848Z",\n",
-       "    "modified": "2019-05-10T15:29:44.848Z",\n",
+       "    "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
+       "    "created": "2019-05-10T16:25:32.644Z",\n",
+       "    "modified": "2019-05-10T16:25:32.644Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--de00dd44-7685-46b5-bf01-04003a2ee496",\n",
-       "    "created": "2019-05-10T15:29:47.422Z",\n",
-       "    "modified": "2019-05-10T15:29:47.422Z",\n",
+       "    "id": "relationship--d0d3ff20-d0f4-4807-b4dd-692724801ce3",\n",
+       "    "created": "2019-05-10T16:25:34.989Z",\n",
+       "    "modified": "2019-05-10T16:25:34.989Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--026ce7aa-1a14-4dc3-8dd3-8c2cd4eeaa66",\n",
+       "    "id": "bundle--feaf8f9f-3342-4613-954b-ae22235f8d0b",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "            "created": "2019-05-10T15:28:49.358Z",\n",
-       "            "modified": "2019-05-10T15:28:49.358Z",\n",
+       "            "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "            "created": "2019-05-10T16:25:11.193Z",\n",
+       "            "modified": "2019-05-10T16:25:11.193Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2019-05-10T15:28:49.358947Z",\n",
+       "            "valid_from": "2019-05-10T16:25:11.193329Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
-       "            "created": "2019-05-10T15:29:37.208Z",\n",
-       "            "modified": "2019-05-10T15:29:37.208Z",\n",
+       "            "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
+       "            "created": "2019-05-10T16:25:29.127Z",\n",
+       "            "modified": "2019-05-10T16:25:29.127Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
-       "            "created": "2019-05-10T15:29:44.848Z",\n",
-       "            "modified": "2019-05-10T15:29:44.848Z",\n",
+       "            "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
+       "            "created": "2019-05-10T16:25:32.644Z",\n",
+       "            "modified": "2019-05-10T16:25:32.644Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "            "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "            "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "            "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -997,9 +997,99 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 17,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
{\n",
+       "    "type": "ipv4-addr",\n",
+       "    "value": "177.60.40.7",\n",
+       "    "resolves_to_refs": [\n",
+       "        "1",\n",
+       "        "2"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from stix2 import MACAddress\n", "\n", From 1bf12221a002f5b30542c3070ccf160651c0daf0 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Mon, 13 May 2019 09:18:50 -0400 Subject: [PATCH 4/4] Update _valid_refs doc and add test to v20 test suite --- docs/guide/creating.ipynb | 64 ++++++++++++++-------------- stix2/test/v20/test_observed_data.py | 18 ++++++++ 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 5be60ed..92a3336 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "created": "2019-05-10T16:25:11.193Z",\n",
-       "    "modified": "2019-05-10T16:25:11.193Z",\n",
+       "    "id": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "created": "2019-05-13T13:14:48.509Z",\n",
+       "    "modified": "2019-05-13T13:14:48.509Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2019-05-10T16:25:11.193329Z",\n",
+       "    "valid_from": "2019-05-13T13:14:48.509629Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
-       "    "created": "2019-05-10T16:25:29.127Z",\n",
-       "    "modified": "2019-05-10T16:25:29.127Z",\n",
+       "    "id": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
+       "    "created": "2019-05-13T13:15:04.698Z",\n",
+       "    "modified": "2019-05-13T13:15:04.698Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
-       "    "created": "2019-05-10T16:25:32.644Z",\n",
-       "    "modified": "2019-05-10T16:25:32.644Z",\n",
+       "    "id": "relationship--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
+       "    "created": "2019-05-13T13:15:13.152Z",\n",
+       "    "modified": "2019-05-13T13:15:13.152Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--d0d3ff20-d0f4-4807-b4dd-692724801ce3",\n",
-       "    "created": "2019-05-10T16:25:34.989Z",\n",
-       "    "modified": "2019-05-10T16:25:34.989Z",\n",
+       "    "id": "relationship--47395d23-dedd-45d4-8db1-c9ffaf44493d",\n",
+       "    "created": "2019-05-13T13:15:16.566Z",\n",
+       "    "modified": "2019-05-13T13:15:16.566Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--feaf8f9f-3342-4613-954b-ae22235f8d0b",\n",
+       "    "id": "bundle--388c9b2c-936c-420a-baa5-04f48d682a01",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "            "created": "2019-05-10T16:25:11.193Z",\n",
-       "            "modified": "2019-05-10T16:25:11.193Z",\n",
+       "            "id": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "            "created": "2019-05-13T13:14:48.509Z",\n",
+       "            "modified": "2019-05-13T13:14:48.509Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2019-05-10T16:25:11.193329Z",\n",
+       "            "valid_from": "2019-05-13T13:14:48.509629Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
-       "            "created": "2019-05-10T16:25:29.127Z",\n",
-       "            "modified": "2019-05-10T16:25:29.127Z",\n",
+       "            "id": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
+       "            "created": "2019-05-13T13:15:04.698Z",\n",
+       "            "modified": "2019-05-13T13:15:04.698Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
-       "            "created": "2019-05-10T16:25:32.644Z",\n",
-       "            "modified": "2019-05-10T16:25:32.644Z",\n",
+       "            "id": "relationship--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
+       "            "created": "2019-05-13T13:15:13.152Z",\n",
+       "            "modified": "2019-05-13T13:15:13.152Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "            "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "            "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "            "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -869,7 +869,9 @@
    "metadata": {},
    "source": [
     "### Creating Cyber Observable References\n",
-    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. There are two cases."
+    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. It should be noted that ``_valid_refs`` is necessary when creating references to Cyber Observable Objects since some embedded references can only point to certain types, and ``_valid_refs`` helps ensure consistency. \n",
+    "\n",
+    "There are two cases."
    ]
   },
   {
diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py
index 84cdf72..95daf22 100644
--- a/stix2/test/v20/test_observed_data.py
+++ b/stix2/test/v20/test_observed_data.py
@@ -960,6 +960,24 @@ def test_ip4_address_example():
     assert ip4.resolves_to_refs == ["4", "5"]
 
 
+def test_ip4_address_valid_refs():
+    mac1 = stix2.v20.MACAddress(
+        value="a1:b2:c3:d4:e5:f6",
+    )
+    mac2 = stix2.v20.MACAddress(
+        value="a7:b8:c9:d0:e1:f2",
+    )
+
+    ip4 = stix2.v20.IPv4Address(
+        _valid_refs={"1": mac1, "2": mac2},
+        value="177.60.40.7",
+        resolves_to_refs=["1", "2"],
+    )
+
+    assert ip4.value == "177.60.40.7"
+    assert ip4.resolves_to_refs == ["1", "2"]
+
+
 def test_ip4_address_example_cidr():
     ip4 = stix2.v20.IPv4Address(value="198.51.100.0/24")