{"id":1148,"date":"2020-08-22T19:08:48","date_gmt":"2020-08-23T02:08:48","guid":{"rendered":"http:\/\/breanneboland.com\/blog\/?p=1148"},"modified":"2020-08-31T20:48:44","modified_gmt":"2020-09-01T03:48:44","slug":"bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews","status":"publish","type":"post","link":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/","title":{"rendered":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>This is the blog counterpart of my 22 August 2020 talk for Bugcrowd&#8217;s event, <a rel=\"noreferrer noopener\" href=\"https:\/\/levelup.bugcrowd.com\/\" target=\"_blank\">LevelUp<\/a> 0x07.<\/em><\/p>\n\n\n\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/hmNNPUicpuY\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n\n\n\n<p class=\"wp-block-paragraph\">A year ago right now, I was an SRE, and my only thoughts of Chrome extensions were that they were 1. something that existed, and 2. useful but also prone to news-making security problems. This year, though, <a href=\"https:\/\/breanneboland.com\/blog\/2020\/01\/27\/how-an-sre-became-an-application-security-engineer-and-you-can-too\/\" data-type=\"post\" data-id=\"1125\">I moved to an appsec engineer role<\/a>, and suddenly they\u2019re a pretty big part of my professional life.\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since <a href=\"https:\/\/breanneboland.com\/blog\/2017\/01\/11\/11-lessons-first-year-software-engineering\/\" data-type=\"post\" data-id=\"1031\">I became an engineer<\/a>, I\u2019ve been fascinated by the kinds of threats that live in places people are less prone to suspect &#8211; or even to consider. Once I learned that my current team sometimes review extensions, in addition to the third-party vendor testing that\u2019s a more central part of our responsibilities, I realized I\u2019d found another one of those somewhat neglected areas of security review. Challenge: accepted. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So that\u2019s why <em>I <\/em>like Chrome extension reviews, the process of which I\u2019ll lead you through in just a few paragraphs, I promise. But why should <em>you<\/em> care about this? You as an appsec enthusiast or engineer, you as a bug bounty hunter, you as someone else with an interest in the strange corners of the internet that vulnerabilities can hide in.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Ok, but <em>why<\/em> do these reviews?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Extensions open up a really interesting attack surface. They\u2019re part of the browser, so embedded in the client, which can let them sidestep some of the protections an unaltered browser might offer. Beyond that, people often have alert fatigue and don\u2019t think that much of a warning like \u201cthis extension can read and change your data on every website you visit.\u201d It <em>should<\/em> be alarming, but that warning applies to so many extensions that it\u2019s easy for people to ignore.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">They also update themselves automatically, on a timetable determined by the browser using the update path that has to be part of any extension listed in the Chrome Web Store. So you have third-party code nestled right in where the business happens, AND said third-party code can change with no warning at a cadence that isn&#8217;t set by the end user.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Last year, <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wired.com\/story\/google-chrome-extensions-security-changes\/\" target=\"_blank\">Google made some moves<\/a> to bolster user security, <a rel=\"noreferrer noopener\" href=\"https:\/\/cloud.google.com\/blog\/products\/identity-security\/enhancing-security-controls-for-google-drive-third-party-apps\" target=\"_blank\">making permission scopes around Gmail and Google Drive more granular<\/a>, while requiring developers using these scopes to use the smallest access to information possible. Useful; not a panacea. Alas, the <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/api_index\" target=\"_blank\">Chrome API<\/a> permission scopes are still fairly broad. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Google has done <a rel=\"noreferrer noopener\" href=\"https:\/\/www.zdnet.com\/article\/google-removes-106-chrome-extensions-for-collecting-sensitive-user-data\/\" target=\"_blank\">some mass culls of extensions<\/a>, and the team behind CRXcavator (which we\u2019ll get to shortly) has uncovered a lot of, uh, <a rel=\"noreferrer noopener\" href=\"https:\/\/duo.com\/labs\/research\/crxcavator-malvertising-2020\" target=\"_blank\">interesting extension functionality<\/a> too.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the automatic updates still leave even polished products open to strange second and third acts. <a href=\"https:\/\/www.reddit.com\/r\/IAmA\/comments\/1vjj51\/i_am_one_of_the_developers_of_a_popular_chrome\/\" target=\"_blank\" rel=\"noreferrer noopener\">Bad actors buy popular extensions<\/a>, which then give them a direct line to thousands and thousands of browsers, which are used by folks who generally aren\u2019t extremely vigilant about monitoring their installed extensions. By which I mean: just people, in general. Most of us don\u2019t do a monthly extensions check, which is understandable &#8211; but it does leave the door open to some interesting things.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Including, happily, bug bounties.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to review Chrome extensions: tl;dr edition<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When I review a Chrome extension, I start by building a story about the extension I\u2019ve been assigned. I research the proposed use case, read the extension\u2019s Chrome Web Store page and other online descriptions, and do a cursory review of the code and try to learn these things:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>What does this extension say it wants to do?<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>What does it actually do? Is that answer different?<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>What permissions does it need to have to accomplish its stated mission?&nbsp;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Do the permissions or code make anything possible outside of the extension\u2019s stated mission?<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is where I figure out where to focus. Most extensions, like most people, are on the up and up. But &#8211; and sit down for this one &#8211; sometimes developers get sloppy when they\u2019re writing extensions. I wouldn\u2019t even call this the developers\u2019 fault a lot of the time, because <a href=\"https:\/\/developer.chrome.com\/extensions\/declare_permissions\" target=\"_blank\" rel=\"noreferrer noopener\">Chrome API permissions<\/a> are broad, and most devs are strapped for time. It\u2019s a recipe that makes for some messy stuff ending up in extensions.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to review Chrome extensions: in depth<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Once I\u2019ve got a sense of what the extension is <em>supposed<\/em> to do and what it <em>actually<\/em> seems to be doing, I work through the code in three steps.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, I paste the extension\u2019s Web Store ID (long, all lowercase letters, part of the URL of its Web Store page) into <a rel=\"noreferrer noopener\" href=\"https:\/\/duo.com\/blog\/crxcavator\" target=\"_blank\">CRXcavator<\/a>. CRXcavator gives you an aggregated risk score for the extension, based on several metrics. The most relevant to our needs are the <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CSP\" target=\"_blank\">content security policy<\/a> and Chrome API permissions. (Others include externally hosted Javascript libraries and its Chrome Web Store Score.) Here&#8217;s CRXcavator&#8217;s score for one of its associated extensions.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"711\" src=\"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\" alt=\"\" class=\"wp-image-1165\" srcset=\"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png 1024w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-300x208.png 300w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-768x533.png 768w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1536x1066.png 1536w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM.png 1858w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019re going to focus more on other parts of the manifest for the purposes of this post, but content security policy can also make a lot of good, weird stuff possible that perhaps shouldn&#8217;t be. Like I said, this setting can literally override the settings of individual websites, so it\u2019s worth spending some time looking at the CSP of an extension as part of your broader exploration. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">CRXcavator gives me an early indicator of where risk might live. You can also read through the code on their site, or you can do what I do and use an extension like <a rel=\"noreferrer noopener\" href=\"https:\/\/chrome.google.com\/webstore\/detail\/crx-extractordownloader\/ajkhmmldknmfjnmeedkbkkojgobmljda\/related?hl=en-US\" target=\"_blank\">CRX Extractor\/Downloader<\/a> to get it locally and explore in your text editor.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once I have the code in front of me, I read the <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/manifest\" target=\"_blank\">manifest.json<\/a> file. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"883\" src=\"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM-1024x883.png\" alt=\"A text editor showing a sample manifest.json file\" class=\"wp-image-1164\" srcset=\"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM-1024x883.png 1024w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM-300x259.png 300w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM-768x662.png 768w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM-1536x1324.png 1536w, https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-15-at-1.24.19-AM.png 1684w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is where I spend a lot of my time, because it tells me a lot about what\u2019s possible. These files can get long and intricate: there are 56 different fields that can be included. However, most of the extensions I see don\u2019t use a ton of those. Only three are required, and only four are marked in the docs as recommended. That excludes <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/content_scripts\" target=\"_blank\">content_scripts<\/a>, though, so pretty much all extensions have to go a bit beyond the minimum in order to be able to actually do much.\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In manifest.json, I look most closely at the permissions listed, both the Chrome API permissions included and the URLs cited. From there, I read through the different Javascript files being used and what they\u2019re going to be allowed to do.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, I read the code. I\u2019m looking for weird uses of permissions (<a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/apps\/identity\" target=\"_blank\">chrome.identity<\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/cookies\" target=\"_blank\">chrome.cookies<\/a> are fun, but I look up all uses of any permission methods used), any connections to third-party servers, and anything else that seems overly ambitious.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Assessing the risks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Permissions are the sketch of what can happen; the code shows what will actually happen with them. Because of that, I spend a fair amount of time on those permitted Chrome API operations. The permissions don\u2019t encompass all the possible risk in an extension, but they cover a lot.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s what I\u2019m looking for across all of the extension code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Is it sending data? If so, to where?<\/strong> I want to see innocuous and clearly described changes to the appearance and contents of the <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Document_Object_Model\/Introduction\" target=\"_blank\">DOM<\/a>. I do <em>not<\/em> want to see data being collected or sent. If I <em>do<\/em> see data being collected or sent, I have found the new primary focus of my time for the duration of my testing. There are legitimate reasons to do this, of course, but they need to be safely done and well justified.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Is it storing anything unsafely in your browser?<\/strong> I don\u2019t want to see plaintext secrets stored in the browser, not in session storage and especially not in local storage. This is something I touch on early because of my job&#8217;s context; it may be less important to you, but it&#8217;s still worth looking into. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Do the scopes of the Chrome API permissions let the extension snoop on everything we\u2019re doing?<\/strong> We don\u2019t like that much either.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Is the extension snooping on everything you\u2019re doing and then sending it somewhere else?<\/strong> Oh dear.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Again, there\u2019s opt-in functionality that can justify all of this. But it <em>does<\/em> need to be justified (from my point of view as a reviewer of risk), and then it needs to be done safely.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This second part is where the bug bounty hunter can have a lot of fun.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Anatomy of an extension<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s start with manifest.json, since it\u2019s where I spend most of my time and it most concisely shows a lot of the weird possibilities in a given extension. The key parts I look at are the general <em>permissions<\/em> of the extension and then <em>content_scripts<\/em> and their associated permissions&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Seeking bounties? manifest.json is more likely to be a hint at what will lie in the rest of the Javascript, which is where you\u2019ll find what you\u2019re actually looking for. The really interesting stuff will be in the code, of course. Some extensions have a single fairly simple JS file; others can have files upon files. The official size limit for a <a rel=\"noreferrer noopener\" href=\"https:\/\/fileinfo.com\/extension\/crx\" target=\"_blank\">CRX file<\/a>, which is the zip-formatted file format for a Chrome extension, is 2 GB. That\u2019s a lot of room for function and also just utter mayhem.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most extensions also have an HTML component, often for creating a customized menu for the extension. If you see popup.html, it\u2019s likely this. These are subject to the same vulnerabilities as any webpage, so it\u2019s worth testing for XSS and anything else you\u2019d try to find in a front-end.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Permissions and their risks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Permissions for an extension come in two forms: <a href=\"https:\/\/developer.chrome.com\/extensions\/match_patterns\" target=\"_blank\" rel=\"noreferrer noopener\">URLs<\/a> (specific ones or patterns) and Chrome API permissions. These cover all kinds of possible interactions: alerts, accessing and altering browser storage, accessing bookmarks and tabs, among many others.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There\u2019s a safe use for every permission, but there are also permissions that, if included, are a great place to start when reviewing an extension to make sure it\u2019s safe for the user. Problems arise when the dev needs to invoke a permission or a manifest.json field, like web_accessible_resources, that is necessary for some perfectly ordinary extension function, like access packaged resources to use in the context of a web page. Unfortunately, that same permission can be used to execute remote scripts. Like most anything involving Javascript, there are risks that come with using the tools at hand.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Google has <a rel=\"noreferrer noopener\" href=\"https:\/\/bit.ly\/whitepaperpermissionrisk\" target=\"_blank\">a great guide<\/a> where they list the permissions they think are most dangerous, with surprisingly high specificity. Removing the escape key\u2019s ability to exit full-screen? Spying on the user with their own camera or microphone? Nightmares! But all are possible with the correct, terrible combination of host and API permissions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at a few of these permissions, now that I\u2019ve spent some time broadly demonizing them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">URLs and pattern matching<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For an extension to access a site, its URL must either be specified or <a href=\"https:\/\/developer.chrome.com\/extensions\/match_patterns\" target=\"_blank\" rel=\"noreferrer noopener\">match a pattern<\/a>. Conveniently for devs, there are patterns that make matching easy. Conveniently for bug bounty hunters, this means that lots of devs leave the doors more open than is ideal because they\u2019re trying to futureproof their extension (or, less commonly, because it\u2019s something that has any business doing something on every site you visit). manifest.json can include and exclude URLs based on these patterns, but including is <em>much<\/em> more common.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The patterns and matches I\u2019m most wary of are *:\/\/*\/* and &lt;all_urls&gt;, with a close second anything that matches a common host (google.com, for instance) with asterisks before or after. *:\/\/*\/* and &lt;all_urls&gt;, however, match <em>the entire internet<\/em>, so long as the address being visited is a permitted protocol (http, https, ftp, or file). These permissions give an extension carte blanche to work on any website you visit. Your email, your bank, your employer\u2019s web portal when everyone\u2019s working at home\u2026 I find this permission hard to justify. It isn\u2019t that <em>no<\/em> extensions should use it, but it should be relatively few. Google themselves declares wide-open wildcard patterns to be the highest-risk type of permission, with &lt;all_urls&gt; the next most dangerous.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">URL permissions can be at the top level permissions in an extension\u2019s <a href=\"https:\/\/developer.chrome.com\/extensions\/manifest\" target=\"_blank\" rel=\"noreferrer noopener\">manifest.json<\/a> or a match connected to a particular content_script.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On top of allowing an extension free access to all of the user\u2019s browsing, including those wide-open permissions also allows cross-origin requests with none of the usual barriers your browser would present. It also allows Javascript injection on any site the user visits. Fun!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That said, one reason people do this (for non-nefarious reasons) is precisely to <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/xhr#requesting-permission\" target=\"_blank\">avoid CORS errors<\/a>. However, I promise this can be done effectively and more securely &#8211; it just requires a little more work to narrow down exactly what URL or pattern needs to be put into place. Beware asterisks; especially beware asterisks with only a host or no host at all. On the plus side, it opens up a lot of interesting territory for the bug bounty hunter. Silver lining, I guess?&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">webRequest<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/developer.chrome.com\/extensions\/webRequest\" target=\"_blank\" rel=\"noreferrer noopener\">webRequest<\/a> lets the extension change and add HTTP headers. It also lets it add listeners and change behavior upon receiving the first byte of a response, at the initiation of a redirect, when a request is completed, and anywhere else in the lifecycle of a web request. This can, of course, be used totally legitimately. However, it\u2019s also been used to <a href=\"https:\/\/medium.com\/@gilfink\/adding-web-interception-abilities-to-your-chrome-extension-fb42366df425\" target=\"_blank\" rel=\"noreferrer noopener\">intercept<\/a> and forward user traffic, so if it shows up in the manifest, it\u2019s worth looking at every one of its methods that\u2019s used in the code. Another check on this behavior is that this permission also has to be paired with an appropriate host permission to be able to do anything.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This permission is likely to be in flux in the future, but for now it\u2019s still here and still weird enough that even <a rel=\"noreferrer noopener\" href=\"https:\/\/www.eff.org\/deeplinks\/2019\/07\/googles-plans-chrome-extensions-wont-really-help-security\" target=\"_blank\">the EFF has weighed in on its present and future<\/a>.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">cookies<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.chrome.com\/extensions\/cookies\" target=\"_blank\">cookies<\/a> permission offers methods around getting, setting, and removing cookies. This can result in a lot of weird possibilities, particularly when paired with gleaning data and sending it elsewhere. Fortunately, the solution for this is the same as for XSS: set that HttpOnly flag on your cookie so it isn\u2019t accessible via the Javascript of a content_script. However, if people faithfully set that flag, my job might not need to exist, so it\u2019s worth mentioning. This also requires appropriate host permissions to be able to do anything.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The code, more generally<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The manifest.json file can point to a few different uses for Javascript files. The <a href=\"https:\/\/developer.chrome.com\/extensions\/background_pages\" target=\"_blank\" rel=\"noreferrer noopener\">background<\/a> section of the file, which is optional, includes code that is loaded when needed, including when a content script sends a message, when certain events happen, or when the extension is first installed or updated. In contract, <a href=\"https:\/\/developer.chrome.com\/extensions\/content_scripts\" target=\"_blank\" rel=\"noreferrer noopener\">content_scripts<\/a> (which, as I mentioned, have their own permissions) run in the context of webpages.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When I read these Javascript files, the things I watch for are shaped by the particular concerns of my team at my very large company. My primary concerns, however, are pretty universal: how the extension might be accessing, storing, and sending information. I watch for any input text being saved or otherwise manipulated. I find out what is being collected, if the collection and handling of that information supports the story I\u2019ve put together about the extension through my research, and, if not, where the two diverge. After <em>that<\/em>, I check for http requests. If I find them, I look at what they\u2019re doing. What\u2019s being stored and sent? How is it being sent, and where is it going? Is it something the user of the extension will have opted into via an account, or is this being done more quietly?&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I also watch for tells like the use of <a href=\"https:\/\/gomakethings.com\/preventing-cross-site-scripting-attacks-when-using-innerhtml-in-vanilla-javascript\/\" target=\"_blank\" rel=\"noreferrer noopener\">innerHtml<\/a> &#8211; basically, if it\u2019s something you\u2019d watch for when reviewing webapp code, it\u2019s worth trying on the menus and other popups that are part of an extension.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Good news for bug bounty hunters<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Companies\u2019 official Chrome extensions can create weird and surprising vulnerabilities for their customers. Think about the permissions involved in an extension that alters text typed into a field. It can read what you type, store it, and send it to be judged by an algorithm across the internet, with the goal of furnishing, say, spelling corrections in a way that reads as nearly instant. We type a lot of sensitive things into text fields &#8211; passwords, credit card numbers, questions to our insurance companies &#8211; and I personally don\u2019t trust an extension to have fine enough control to not at least process the text written in fields other than the ones it\u2019s supposed to be targeting.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let me tell you: even well-funded companies have too-loose permissions and other weird stuff happening in their extensions. It\u2019s the nature of this very particular medium. Let me also tell you: there are bounties for reporting extension issues, both from Google and sometimes from the companies that make them.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because extensions are both everywhere and, in my experience, undervalued as a bug bounty target, I think the world of extensions in particular would benefit from your attention. Beyond what the permissions and code can yield the first time you look at an extension, the particular opportunity of how extensions are updated offers a lot of possibilities for repeated investigation. The releases for extensions, unlike those for websites, are numbered. You <em>know<\/em> if something changed, enough that Chrome has <a href=\"https:\/\/chrome.google.com\/webstore\/category\/collection\/new_noteworthy_extensions\" target=\"_blank\" rel=\"noreferrer noopener\">a page<\/a> for it. Chrome also has its <a href=\"https:\/\/www.google.com\/about\/appsecurity\/reward-program\/\" target=\"_blank\" rel=\"noreferrer noopener\">own program<\/a>, in addition to extensions being in scope for many companies with existing bug bounty programs. <a href=\"https:\/\/hackerone.com\/reports\/435618\" target=\"_blank\" rel=\"noreferrer noopener\">People<\/a> <a href=\"https:\/\/hackerone.com\/reports\/470519\" target=\"_blank\" rel=\"noreferrer noopener\">get<\/a> <a href=\"https:\/\/hackerone.com\/reports\/378805\" target=\"_blank\" rel=\"noreferrer noopener\">paid<\/a> <a href=\"https:\/\/hackerone.com\/reports\/232432\" target=\"_blank\" rel=\"noreferrer noopener\">for<\/a> <a href=\"https:\/\/hackerone.com\/reports\/378809\" target=\"_blank\" rel=\"noreferrer noopener\">extension<\/a> <a href=\"https:\/\/hackerone.com\/reports\/299460\" target=\"_blank\" rel=\"noreferrer noopener\">findings<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Extensions have depths that can contain a lot of, let us say, interesting things. I hope they\u2019re inviting enough for you to dive in and start finding vulnerabilities that make this a safer ecosystem.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Want to learn more?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">If the dazzling galaxy of links throughout this post wasn\u2019t enough, I\u2019d suggest two more. <a href=\"https:\/\/www.maketecheasier.com\/create-chrome-extension\/\" target=\"_blank\" rel=\"noreferrer noopener\">This tutorial<\/a> is how I created my first extension to install locally to better understand the process. This <a href=\"https:\/\/www.youtube.com\/watch?v=pR4HwDOFacY\" target=\"_blank\" rel=\"noreferrer noopener\">2016 DEF CON talk<\/a> isn\u2019t completely applicable to the capabilities of extension today, but it\u2019s an excellent guide to how good and weird it has been possible to get with extensions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the blog counterpart of my 22 August 2020 talk for Bugcrowd&#8217;s event, LevelUp 0x07. A year ago right now, I was an SRE, and my only thoughts of Chrome extensions were that they were 1. something that existed, and 2. useful but also prone to news-making security problems. This year, though, I moved &hellip; <a href=\"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[214],"tags":[255,256,257,259,258],"class_list":["post-1148","post","type-post","status-publish","format-standard","hentry","category-code-shit","tag-chrome","tag-chrome-extensions","tag-code-review","tag-google-things","tag-javascript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland\" \/>\n<meta property=\"og:description\" content=\"This is the blog counterpart of my 22 August 2020 talk for Bugcrowd&#8217;s event, LevelUp 0x07. A year ago right now, I was an SRE, and my only thoughts of Chrome extensions were that they were 1. something that existed, and 2. useful but also prone to news-making security problems. This year, though, I moved &hellip; Continue reading Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews\" \/>\n<meta property=\"og:url\" content=\"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/\" \/>\n<meta property=\"og:site_name\" content=\"Breanne Boland\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-23T02:08:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-09-01T03:48:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#\\\/schema\\\/person\\\/7b8ba109de56e2b80e0773753109c1ce\"},\"headline\":\"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews\",\"datePublished\":\"2020-08-23T02:08:48+00:00\",\"dateModified\":\"2020-09-01T03:48:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/\"},\"wordCount\":3149,\"publisher\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#\\\/schema\\\/person\\\/7b8ba109de56e2b80e0773753109c1ce\"},\"image\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/breanneboland.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\",\"keywords\":[\"chrome\",\"chrome extensions\",\"code review\",\"google things\",\"javascript\"],\"articleSection\":[\"Code shit\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/\",\"url\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/\",\"name\":\"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/breanneboland.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\",\"datePublished\":\"2020-08-23T02:08:48+00:00\",\"dateModified\":\"2020-09-01T03:48:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#primaryimage\",\"url\":\"https:\\\/\\\/breanneboland.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\",\"contentUrl\":\"https:\\\/\\\/breanneboland.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/2020\\\/08\\\/22\\\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/\",\"name\":\"Breanne Boland\",\"description\":\"Appsec engineer, SRE, writer, UX, endless questions mostly\",\"publisher\":{\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#\\\/schema\\\/person\\\/7b8ba109de56e2b80e0773753109c1ce\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/breanneboland.com\\\/blog\\\/#\\\/schema\\\/person\\\/7b8ba109de56e2b80e0773753109c1ce\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g\",\"caption\":\"admin\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/","og_locale":"en_US","og_type":"article","og_title":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland","og_description":"This is the blog counterpart of my 22 August 2020 talk for Bugcrowd&#8217;s event, LevelUp 0x07. A year ago right now, I was an SRE, and my only thoughts of Chrome extensions were that they were 1. something that existed, and 2. useful but also prone to news-making security problems. This year, though, I moved &hellip; Continue reading Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews","og_url":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/","og_site_name":"Breanne Boland","article_published_time":"2020-08-23T02:08:48+00:00","article_modified_time":"2020-09-01T03:48:44+00:00","og_image":[{"url":"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png","type":"","width":"","height":""}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#article","isPartOf":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/"},"author":{"name":"admin","@id":"https:\/\/breanneboland.com\/blog\/#\/schema\/person\/7b8ba109de56e2b80e0773753109c1ce"},"headline":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews","datePublished":"2020-08-23T02:08:48+00:00","dateModified":"2020-09-01T03:48:44+00:00","mainEntityOfPage":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/"},"wordCount":3149,"publisher":{"@id":"https:\/\/breanneboland.com\/blog\/#\/schema\/person\/7b8ba109de56e2b80e0773753109c1ce"},"image":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#primaryimage"},"thumbnailUrl":"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png","keywords":["chrome","chrome extensions","code review","google things","javascript"],"articleSection":["Code shit"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/","url":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/","name":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews - Breanne Boland","isPartOf":{"@id":"https:\/\/breanneboland.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#primaryimage"},"image":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#primaryimage"},"thumbnailUrl":"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png","datePublished":"2020-08-23T02:08:48+00:00","dateModified":"2020-09-01T03:48:44+00:00","breadcrumb":{"@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#primaryimage","url":"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png","contentUrl":"https:\/\/breanneboland.com\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-09-at-5.49.55-PM-1024x711.png"},{"@type":"BreadcrumbList","@id":"https:\/\/breanneboland.com\/blog\/2020\/08\/22\/bugcrowd-levelup-0x07-how-to-do-chrome-extension-code-reviews\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/breanneboland.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Bugcrowd LevelUp 0x07: How to Do Chrome Extension Code Reviews"}]},{"@type":"WebSite","@id":"https:\/\/breanneboland.com\/blog\/#website","url":"https:\/\/breanneboland.com\/blog\/","name":"Breanne Boland","description":"Appsec engineer, SRE, writer, UX, endless questions mostly","publisher":{"@id":"https:\/\/breanneboland.com\/blog\/#\/schema\/person\/7b8ba109de56e2b80e0773753109c1ce"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/breanneboland.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/breanneboland.com\/blog\/#\/schema\/person\/7b8ba109de56e2b80e0773753109c1ce","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g","caption":"admin"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/764113b6dca6b6cee982a9f690f5c44d6166de3996e918649e2bafb27cd4c8bf?s=96&d=blank&r=g"}}]}},"_links":{"self":[{"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/posts\/1148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/comments?post=1148"}],"version-history":[{"count":6,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/posts\/1148\/revisions"}],"predecessor-version":[{"id":1166,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/posts\/1148\/revisions\/1166"}],"wp:attachment":[{"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/media?parent=1148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/categories?post=1148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/breanneboland.com\/blog\/wp-json\/wp\/v2\/tags?post=1148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}