Skip to content

Instantly share code, notes, and snippets.

@paulirish
Last active February 20, 2025 18:49
Show Gist options
  • Save paulirish/78d6c1406c901be02c2d to your computer and use it in GitHub Desktop.
Save paulirish/78d6c1406c901be02c2d to your computer and use it in GitHub Desktop.
How to view-source of a Chrome extension

Option 1: Command-line download extension as zip and extract

extension_id=jifpbeccnghkjeaalbbjmodiffmgedin   # change this ID
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc" 
unzip -d "$extension_id-source" "$extension_id.zip"

Thx to crxviewer for the magic download URL.

Option 2: Use the CRX Viewer website

https://robwu.nl/crxviewer/

Option 3: Use the CRX Viewer extension

The Chrome extension source viewer is open source (github repo) and makes this super easy.

Option 3: View source of locally installed extension

  1. Find your Chrome local profile directory. Open chrome://version/ and find the "Profile Path:` field. Open that folder up.
  2. Open the Extensions/ subfolder
  3. All your extensions are here, with typically readable source.

Mapping between locally installed extension IDs and names

  • On about:extensions, turn on Developer Mode and you'll see IDs under each entry
  • Inside the Extensions/ folders, the manifest.json has a readable name field

image

@Krovikan-Vamp
Copy link

Thanks Paul!

@disaac
Copy link

disaac commented Dec 5, 2024

@stefanschmidt Thanks for the updated curl commands. I refactored a bit to make it a copy paste snippet that automates the process of downloading, verifying, and extracting a Chrome extension to a directory with the extension_name. It also uses grep -oP to extract the sha256 from the xml in case someone doesn't want to or can't install xmlstarlet.

NOTE: This worked on the specific extension I was targeting didn't test on any others.

extension_name=disable-html5-autoplay
mkdir -p "$extension_name"
extension_id=cafckninonjkogajnihihlnnimmkndgf 
# Download the crx file
curl --output "$extension_id.crx" --silent --location "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc&acceptformat=crx3"
# Check the sha256 hash of the crx file
dlSha=$(sha256sum "$extension_id.crx" | cut -d ' ' -f 1)
# download sha info from xml file
curl --silent --location --output "$extension_id.xml" "https://clients2.google.com/service/update2/crx?os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc&acceptformat=crx3"
# Check the sha256 hash from the xml file
xmlSha=$(grep -oP 'hash_sha256="\K\w+(?=")' "$extension_id.xml")
if [[ $dlSha == $xmlSha ]]; then
 echo "SHA256 hash is correct expanding crx src"
 unzip "$extension_id.crx" -d "$extension_name"
 # Remove the crx file and xml file after extracting
 rm "$extension_id.crx" "$extension_id.xml"
else
  echo "SHA256 hash is incorrect"
fi

@1oglop1
Copy link

1oglop1 commented Dec 17, 2024

Nothing from above worked for me, I kept getting 0B responses until I replaced prodversion=44.0.2403.130 with the actual version of my browser which is 131.0.6778.109 at the time of writing this. -> prodversion=131.0.6778.109 then downloaded the file.

@zilun-wang
Copy link

Nothing from above worked for me, I kept getting 0B responses until I replaced prodversion=44.0.2403.130 with the actual version of my browser which is 131.0.6778.109 at the time of writing this. -> prodversion=131.0.6778.109 then downloaded the file.

Thanks for your update. This works for me.

@MD123451
Copy link

MD123451 commented Jan 7, 2025

Hm Interesting

@stefanschmidt
Copy link

stefanschmidt commented Jan 16, 2025

tl;dr

Either set prodversion to the most recent Chrome release or use the following:

extension_id=jifpbeccnghkjeaalbbjmodiffmgedin
https://clients2.google.com/service/update2/crx?response=redirect&prodversion=2147483647&x=id%3D${extension_id}%26uc&acceptformat=crx3

Explanation

It turns out Chrome extensions have an optional manifest key minimum_chrome_version.

Apparently while making the switch from Manifest V2 to Manifest V3 extension developers are increasingly making use of it.

The extension I used as example above had "minimum_chrome_version": "88" added to the manifest in December 2023.

Behind the scenes the Google API appears to verify minimum_chrome_version by checking the value of prodversion.

So in this case a value less than 88 will result in an empty response body.

$ curl -Ls -o /dev/null --write-out '%{http_code}\n' "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=87&x=id%3Djifpbeccnghkjeaalbbjmodiffmgedin%26uc&acceptformat=crx3"
204

but a value >=88 will deliver the extension.

$ curl -Ls -o /dev/null --write-out '%{http_code}\n' "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=88&x=id%3Djifpbeccnghkjeaalbbjmodiffmgedin%26uc&acceptformat=crx3"
200

The largest value that works for prodversion is 2147483647.

$ curl -Ls -o /dev/null --write-out '%{http_code}\n' "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=2147483647&x=id%3Djifpbeccnghkjeaalbbjmodiffmgedin%26uc&acceptformat=crx3"
200

$ curl -Ls -o /dev/null --write-out '%{http_code}\n' "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=2147483648&x=id%3Djifpbeccnghkjeaalbbjmodiffmgedin%26uc&acceptformat=crx3"
204

So apparently Google uses a signed 32-bit integer variable for processing the parameter prodversion resulting in $2^{31}-1 = 2147483647$ as the maximum value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment