{"id":32324,"date":"2021-03-12T17:22:50","date_gmt":"2021-03-13T00:22:50","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=32324"},"modified":"2023-01-13T10:50:26","modified_gmt":"2023-01-13T18:50:26","slug":"investigating-a-linux-cve-with-net-images","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/investigating-a-linux-cve-with-net-images\/","title":{"rendered":"Investigating a Linux CVE with .NET Images"},"content":{"rendered":"<p><strong>Update:<\/strong> We recently published <a href=\"https:\/\/github.com\/dotnet\/dotnet-docker\/blob\/main\/documentation\/vulnerability-reporting.md\">Container Vulnerability Workflow<\/a>. It is intended\u00a0to help guide you to the appropriate course of action when encountering reported vulnerabilities in the .NET container images<\/p>\n<p>We regularly get contacted for help in managing CVEs in Linux-based .NET images. In fact, we were contacted just this morning about <a href=\"https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2021-23840\">CVE-2021-23840<\/a> and <a href=\"https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2021-23841\">CVE-2021-23841<\/a>. I investigated the CVE for that customer to help them understand their options. It occurred to me that this information would be helpful to a broader audience. The following post is mostly just a re-printing of our conversation. It demonstrates what the customer wanted to learn and I what I did to answer their questions. I&#8217;m not using any special tools or security databases, but the exact same information that you have access to from your desktop.<\/p>\n<p>This post can be thought of as the practical companion to <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/staying-safe-with-dotnet-containers\/\">Staying safe with .NET Containers<\/a>. That post is more the theory of how to stay safe, but doesn&#8217;t include much on-the-ground guidance. I&#8217;m hoping that this post helps you if you are asked to do an investigation.<\/p>\n<p>The post includes a lot of <code>docker<\/code> commands. I&#8217;m using WSL2 for this. As a result, the exact syntax will work on Windows, macOS, and Linux.<\/p>\n<h2>Customer request<\/h2>\n<p>The following is the (massively paraphrased) request from the customer.<\/p>\n<p><em>Our CVE scan is showing unpatched vulnerabilities in .NET images, specifically in the runtime-deps layer. It relates to this <a href=\"https:\/\/lists.debian.org\/debian-security-announce\/2021\/msg00035.html\">openssl security update<\/a>.<\/em><\/p>\n<p><em>We are using this tag: <code>mcr.microsoft.com\/dotnet\/runtime-deps:3.1<\/code>. It has been a couple months since we last built our app with that image. We need your help on what to do next.<\/em><\/p>\n<h2>The investigation<\/h2>\n<p>The following is the investigation I did to help out this customer. It took ~30 mins to do that. I&#8217;m sharing that to give you a sense of what doing this work looks like when you have the skills for the task and have confidence in the techniques you are using.<\/p>\n<p>The first thing I wanted to do is to get some ground facts in place to work from.<\/p>\n<ul>\n<li>Which distro is the customer using?<\/li>\n<li>Does the latest patch of that distro have the fix?<\/li>\n<li>Or, is this issue in a package, such that we need to install an updated package?<\/li>\n<\/ul>\n<p>The customer said that they were using <code>mcr.microsoft.com\/dotnet\/runtime-deps:3.1<\/code>. That&#8217;s a Debian 10 image. I&#8217;ll show you how I know that, in two different ways.<\/p>\n<p>The first way is just asking the image itself.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1 cat \/etc\/os-release\r\nPRETTY_NAME=\"Debian GNU\/Linux 10 (buster)\"\r\nNAME=\"Debian GNU\/Linux\"\r\nVERSION_ID=\"10\"\r\nVERSION=\"10 (buster)\"\r\nVERSION_CODENAME=buster\r\nID=debian\r\nHOME_URL=\"https:\/\/www.debian.org\/\"\r\nSUPPORT_URL=\"https:\/\/www.debian.org\/support\"\r\nBUG_REPORT_URL=\"https:\/\/bugs.debian.org\/\"\r\n<\/code><\/pre>\n<p>The other way is by looking at the Dockerfile. You can get at that by looking at the <a href=\"https:\/\/hub.docker.com\/_\/microsoft-dotnet-runtime-deps\">runtime-deps repo<\/a>.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo.png\" alt=\".NET runtime-deps repo\" width=\"1388\" height=\"388\" \/><\/p>\n<p>The last line in image corresponds to the customer image. Notice the <code>3.1<\/code> tag. I realize now that I didn&#8217;t ask the customer if if they were using x64 or Arm images, but for this investigation, it is unlikely to matter. This isn&#8217;t an architecture-specific issue. If you click on the <code>Dockerfile<\/code> link for that image, you&#8217;ll end up at <a href=\"https:\/\/github.com\/dotnet\/dotnet-docker\/blob\/c0e8be8a44b47b1dcc2a5b4b2ebd92022087ac0b\/src\/runtime-deps\/3.1\/buster-slim\/amd64\/Dockerfile#L1\">dotnet-docker\/src\/runtime-deps\/3.1\/buster-slim\/amd64\/Dockerfile<\/a>. That shows you a Dockerfile that depends on <code>amd64\/debian:buster-slim<\/code>. That&#8217;s <a href=\"https:\/\/wiki.debian.org\/DebianReleases#Production_Releases\">Debian 10<\/a>.<\/p>\n<p>Let&#8217;s now take a look at the <a href=\"https:\/\/lists.debian.org\/debian-security-announce\/2021\/msg00035.html\">specific issue<\/a>. I&#8217;m going to ignore the actual CVE write-up and going to focus on remediation in that post:<\/p>\n<blockquote><p>For the stable distribution (buster), these problems have been fixed in version <code>1.1.1d-0+deb10u5<\/code>.<\/p><\/blockquote>\n<p>Now, I&#8217;ve got the decoder ring in hand &#8212; the patched OpenSSL version &#8212; and can look at which .NET images have that patched version and which do not.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1 apt list openssl\r\nListing...\r\nopenssl\/now 1.1.1d-0+deb10u5 amd64 [installed,local]\r\n<\/code><\/pre>\n<p>Nice. The latest version is patched. Now we need to find the first version that isn&#8217;t patched. This is a serious investigation, so I&#8217;m going to <code>docker pull<\/code> before every <code>docker run<\/code>. I&#8217;m not going to make any assumptions about the state of my machine (specifically the docker cache).<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1\r\n3.1: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:b1d57557026c11c1980853306cab07869e4786b78fecb65de5dd717cd0a24dc2\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1 apt list openssl\r\nListing...\r\nopenssl\/now 1.1.1d-0+deb10u5 amd64 [installed,local]\r\nrich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1.13\r\n3.1.13: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:b1d57557026c11c1980853306cab07869e4786b78fecb65de5dd717cd0a24dc2\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1.13\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1.13\r\n<\/code><\/pre>\n<p>I&#8217;m not going to run the <code>docker run<\/code> command on <code>3.1.13<\/code>. I can see that its digest matches with <code>3.1<\/code>. They are pointing to the exact same content, so there is no need to check the OpenSSL version again. Let&#8217;s move on to older tags.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12\r\n3.1.12: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:9be9f0624981bf3570e0abaa2daaa5857b116ff9f3a7d95a9626245b0e6f2920\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1.12\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12 apt list openssl\r\nListing...\r\nopenssl\/now 1.1.1d-0+deb10u4 amd64 [installed,local]\r\n<\/code><\/pre>\n<p>That didn&#8217;t take long. That tells us that <code>3.1.13<\/code> has the fix, and <code>3.1.12<\/code> and earlier images do not. You need to upgrade to <code>3.1.13<\/code> to get the fix. You can also manually update <code>3.1.12<\/code> images, but that&#8217;s not recommended and is a pain, so I&#8217;m not going to describe that workflow in this post.<\/p>\n<p>I shared this information with the customer, and they were happy, and had a fine set of next steps for remediation.<\/p>\n<p>In retrospect, I should have asked the customer for the exact .NET image digest that they had used to build their images. That would have been the best place to start the investigation. It would have been useful to determine the OpenSSL version that they were using and validate that it was vulnerable. I believe them, but it&#8217;s always a good idea to validate all assumptions, particularly related to security, that a customer shares with you.<\/p>\n<h2>Let&#8217;s take a look at Alpine<\/h2>\n<p>You know what they say about a job well done.<\/p>\n<p>&#8220;Hey, what if we had used Alpine?&#8221; &#8230; That&#8217;s what they asked next. I needed a break from publishing lengthy blog posts so I decided to re-play the investigation for another distro to satisfy the request.<\/p>\n<p>Let&#8217;s pretend the customer was using <code>mcr.microsoft.com\/dotnet\/runtime-deps:3.1-alpine3.13<\/code> and had the same question. We now need to determine the remediated OpenSSL version in the Alpine ecosystem.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1.png\"><img decoding=\"async\" class=\"aligncenter wp-image-32326 size-full\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1.png\" alt=\"Image runtime deps docker repo alpine\" width=\"1239\" height=\"444\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1.png 1239w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1-300x108.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1-1024x367.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/runtime-deps-docker-repo-alpine-1-768x275.png 768w\" sizes=\"(max-width: 1239px) 100vw, 1239px\" \/><\/a><\/p>\n<p>The Alpine tags we are going to look at are the ones in the last two rows listed in this image.<\/p>\n<p>I looked at that same <a href=\"https:\/\/lists.debian.org\/debian-security-announce\/2021\/msg00035.html\">openssl security update<\/a> for Debian and did some searches on the listed CVEs.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2021\/03\/search-alpinelinx-docker-alpine-repo.png\" alt=\"search docker-alpine repo\" \/><\/p>\n<p>This <a href=\"https:\/\/github.com\/alpinelinux\/docker-alpine\/issues?q=is%3Aissue+CVE-2021-23841\">search<\/a> led to me <a href=\"https:\/\/github.com\/alpinelinux\/docker-alpine\/issues\/154\">docker-alpine #154<\/a>. That tells me that <code>1.1.1j-r0<\/code> is the remediated version in Alpine Linux. <a href=\"https:\/\/github.com\/alpinelinux\/docker-alpine\/issues\/147\">docker-alpine #147<\/a> confirmed that information. You might want more information than that for your purposes, but I&#8217;m going to go with <code>1.1.1j-r0<\/code> as the good version. You can also just rely on your CVE scanners and see if they are happy with that answer.<\/p>\n<p>We now need to do the same exercise and see which Alpine-based .NET images have that OpenSSL package version. Alpine uses a different package manager, so the commands are slightly different.<\/p>\n<p>I&#8217;ll also say upfront that the Alpine-based .NET 3.1 tags are incredibly confusing. The current .NET Core 3.1 patch versions almost exactly match the current Alpine versions. That&#8217;s completely unintentional. We also just transitioned from Alpine 3.12 to Alpine 3.13, across the .NET 3.1.12 to .NET 3.1.13 updates, which is doubly confusing. For the tags you are about to see, it&#8217;s .NET versions on the left and Alpine versions on the right.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1-alpine3.13\r\n3.1-alpine3.13: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:9ee0ac4a369b3720e63a89d4403fed1808bd996bedfa5a67682769c5e161f8d9\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1-alpine3.13\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1-alpine3.13\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1-alpine3.13 apk list libssl1.1\r\nlibssl1.1-1.1.1j-r0 x86_64 {openssl} (OpenSSL) [installed]\r\nrich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1.13-alpine3.13\r\n3.1.13-alpine3.13: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:9ee0ac4a369b3720e63a89d4403fed1808bd996bedfa5a67682769c5e161f8d9\r\nStatus: Downloaded newer image for mcr.microsoft.com\/dotnet\/runtime-deps:3.1.13-alpine3.13\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1.13-alpine3.13\r\n<\/code><\/pre>\n<p>I&#8217;m not going to run the <code>docker run<\/code> command on <code>3.1.13-alpine3.13<\/code>. I can see that its digest matches with <code>3.1-alpine3.13<\/code>. They are pointing to the exact same content, so there is no need to check the OpenSSL version again. Let&#8217;s move on to older tags.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12-alpine3.12\r\n3.1.12-alpine3.12: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:4e05c1cbcf2a1592bb40c37fba0d3693a08afa117b978d849703d3f56762d09c\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12-alpine3.12\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1.12-alpine3.12\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1.12-alpine3.12 apk list libssl1.1\r\nlibssl1.1-1.1.1j-r0 x86_64 {openssl} (OpenSSL) [installed]\r\nrich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1.11-alpine3.12\r\n3.1.11-alpine3.12: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:58d7f8963a82b24e2eb906a0ecd52432a014297eae662a1bacf225c2182b99f4\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1.11-alpine3.12\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1.11-alpine3.12\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1.11-alpine3.12 apk list libssl1.1\r\nlibssl1.1-1.1.1i-r0 x86_64 {openssl} (OpenSSL) [installed]\r\n<\/code><\/pre>\n<p>This tells us that <code>3.1.11-alpine3.12<\/code> is vulnerable and that <code>3.1.12-alpine3.12<\/code> and newer tag versions are patched. If you are built your images with <code>3.1.12-alpine3.12<\/code>(including if you were using the <code>3.1<\/code> tag, before March Patch Tuesday), you should probably still rebuild your image. It&#8217;s likely that <code>3.1.12-alpine3.12<\/code> was rebuilt multiple times through the month (of mid February to mid March) and that it initially included the vulnerable OpenSSL and was rebuilt with the patched version later. You can perform the same test above, to see which OpenSSL version your images have, and then you will be sure.<\/p>\n<p>If you are already using the latest Alpine-based .NET image, then you don&#8217;t need to worry about this OpenSSL CVE. Otherwise, you should rebuild your image.<\/p>\n<h2>Let&#8217;s take a look at Ubuntu<\/h2>\n<p>I&#8217;ll also show you Ubuntu, with quicker treatment. I did some quick searches and found the same <a href=\"https:\/\/ubuntu.com\/security\/notices\/USN-4738-1\">security disclosure for Ubuntu<\/a>. Let&#8217;s look at the Ubuntu 20.04-based .NET 3.1 <code>runtime-deps<\/code> images. The disclosure tell us we should be looking for the <code>libssl1.1 - 1.1.1f-1ubuntu2.2<\/code> OpenSSL package version.<\/p>\n<p>First, I&#8217;ll show you that we&#8217;re looking at Ubuntu 20.04 images.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1-focal cat \/etc\/os-release\r\nNAME=\"Ubuntu\"\r\nVERSION=\"20.04.2 LTS (Focal Fossa)\"\r\nID=ubuntu\r\nID_LIKE=debian\r\nPRETTY_NAME=\"Ubuntu 20.04.2 LTS\"\r\nVERSION_ID=\"20.04\"\r\nHOME_URL=\"https:\/\/www.ubuntu.com\/\"\r\nSUPPORT_URL=\"https:\/\/help.ubuntu.com\/\"\r\nBUG_REPORT_URL=\"https:\/\/bugs.launchpad.net\/ubuntu\/\"\r\nPRIVACY_POLICY_URL=\"https:\/\/www.ubuntu.com\/legal\/terms-and-policies\/privacy-policy\"\r\nVERSION_CODENAME=focal\r\nUBUNTU_CODENAME=focal\r\n<\/code><\/pre>\n<p>Now let&#8217;s look at the latest version of <code>runtime-deps<\/code> for the combination of .NET Core 3.1 and Ubuntu 20.04.<\/p>\n<pre><code class=\"console\">rich@mazama:~$ docker pull mcr.microsoft.com\/dotnet\/runtime-deps:3.1-focal\r\n3.1-focal: Pulling from dotnet\/runtime-deps\r\nDigest: sha256:2cf45d51964425f22eb89769d7d718cf1a03f9f068d0fdea40837c70a1533843\r\nStatus: Image is up to date for mcr.microsoft.com\/dotnet\/runtime-deps:3.1-focal\r\nmcr.microsoft.com\/dotnet\/runtime-deps:3.1-focal\r\nrich@mazama:~$ docker run --rm mcr.microsoft.com\/dotnet\/runtime-deps:3.1-focal apt list openssl\r\nListing...\r\nopenssl\/now 1.1.1f-1ubuntu2.2 amd64 [installed,local]\r\n<\/code><\/pre>\n<p>We have a match. The latest Ubuntu 20.04-based .NET images are patched as well.<\/p>\n<h2>Closing<\/h2>\n<p>For this investigation, I focused on <a href=\"https:\/\/hub.docker.com\/_\/microsoft-dotnet-runtime-deps\">runtime-deps<\/a> images. The same findings apply to the other <a href=\"https:\/\/hub.docker.com\/_\/microsoft-dotnet\">dotnet images<\/a> since they are all built on top of runtime-deps.<\/p>\n<p>As I said in <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/staying-safe-with-dotnet-containers\/\">Staying safe with .NET Containers<\/a>, CVE management is a skill and one that organizations should invest in before the critical security event occurs. It&#8217;s a bit like earthquakes on the Pacific coast of the United States. It&#8217;s not an if, but when.<\/p>\n<p>The style of investigation I shared is not the only kind you need to be competent in to do CVE investigations. I shared this one because of how straightforward it was, and because I had just done it earlier today. It is intended to give you a sense of where information can be found, in security advisories, in GitHub repos (specifically the ones related to delivering container images) and in docker images themselves. It is also intended to demonstrate that we (the .NET Team) have a system in place that keeps images up to date. As you can see from this post, we had images ready for this customer to use, for Alpine, Debian, and Ubuntu.<\/p>\n<p>If there is more we can do to help, please tell us. We see supporting you in CVE management as part of our role in providing .NET images for you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We regularly help .NET developers manage Linux CVEs. This post is an example of how we helped a customer with CVE-2021-23840 and CVE-2021-23841.<\/p>\n","protected":false},"author":1312,"featured_media":21638,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,196,7237],"tags":[4],"class_list":["post-32324","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-dotnet-core","category-containers","tag-net"],"acf":[],"blog_post_summary":"<p>We regularly help .NET developers manage Linux CVEs. This post is an example of how we helped a customer with CVE-2021-23840 and CVE-2021-23841.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/32324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/1312"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=32324"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/32324\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/21638"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=32324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=32324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=32324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}