Chrome Checker Bot
Chrome Checker Bot (CCBot), also known as the Chrome/Chromium Vulnerability Checker, is a Python script that monitors the Chrome Releases blog for vulnerabilities announced in Chrome/Chromium. It polls the blog's Atom feed for Stable desktop releases and checks them for security fixes. If it finds any, it sends a formatted message to Slack through an incoming webhook.
This software was written by Joshua Rogers. For more information, see the blog post.
Installation
Running CCBot outside Docker requires Python 3.10 or newer.
Via pip
Install the package into a virtual environment, since many systems no longer allow a system-wide pip install:
python3 -m venv ccbot-venv
ccbot-venv/bin/pip install ccbot-py
SLACK_WEBHOOK_URL='your_slack_webhook_url' ccbot-venv/bin/ccbot
Via Docker (Docker Hub)
docker run -e SLACK_WEBHOOK_URL='your_slack_webhook_url' megamansec/ccbot
Via Docker (GHCR)
docker run -e SLACK_WEBHOOK_URL='your_slack_webhook_url' ghcr.io/megamansec/ccbot
From source
git clone https://github.com/MegaManSec/CCBot.git
cd CCBot
python3 -m venv venv
venv/bin/pip install --upgrade pip
venv/bin/pip install .
SLACK_WEBHOOK_URL='your_slack_webhook_url' venv/bin/ccbot
Configuration
CCBot reads one setting from the environment:
SLACK_WEBHOOK_URL: Your Slack incoming webhook URL, read at startup. If it is unset or empty, CCBot prints each alert to standard output instead of sending it.
The feed URL (RSS_URL) and the 10-minute refresh interval (REFRESH_INTERVAL_SECONDS) are fixed in ccbot/ccbot.py. CCBot reads Blogger's own Atom feed with redirect=false, because the FeedBurner copy it otherwise redirects to is served stale.
Functionality
The script performs the following tasks:
- Fetches the latest entries from the Chrome Releases Atom feed.
- Keeps only Stable desktop release posts: entries titled "Stable Channel Update for Desktop", or tagged
Desktop Updatetogether withStable updatesorExtended Stable updates. - Fetches each new post and extracts its CVEs from the post's text. If the post can't be fetched or lists no CVEs, it falls back to the post's HTML in the feed.
- Sends a Slack message if CVEs are found, or if the post mentions "security" but no CVEs could be extracted.
Slack Message Format
For each release, CCBot sends a Slack attachment with a red bar:
- Timestamp: When the post was published, in UTC, as
[DD/MM/YY HH:MM:SS]. - URL: Link to the release post.
- Security Issues: One line per CVE, with its severity, CVE ID and description.
Each message holds up to 2,000 characters of Security Issues. A longer list is split across several messages, numbered "Security Issues (1/2)", "Security Issues (2/2)" and so on, each with the timestamp and URL. A CVE is never split between messages; a single CVE entry longer than 2,000 characters is cut and ends with [...truncated...].
Notes
- The script runs until stopped, checking the feed every 10 minutes. A post that fails, for example because it can't be fetched and the feed lists no CVEs for it, or because Slack rejects a message, is retried at the next check. The retry sends only the messages not yet delivered, so a message Slack accepted but whose response was lost can arrive twice. Messages still unsent when the post drops out of the feed, for example because the webhook keeps failing for about a week, are not retried.
- At startup, CCBot records the posts already in the feed and doesn't alert on them, so the first message arrives with the next Stable desktop release. This record and the retries are kept in memory only: after a restart, posts published while CCBot was stopped are never alerted, and messages waiting to be retried are never sent, although earlier messages for the same post may already have been delivered.
- If a post contains the word "security" but no CVEs could be extracted, CCBot still notifies Slack for manual verification, with
Article contained the word 'security' but no CVEs detected. Someone should double-check.. - CVEs are matched with regular expressions, first against the rendered text of the post, then against the post's HTML in the feed. If Google changes the post format, CVEs may stop being detected; the manual-verification message is the fallback.
systemd Installation
An installation script for Debian-based systems, install.sh, is provided. It needs Python 3.10 or newer (Debian 12 or Ubuntu 22.04 and later) and the python3-venv package, and it installs the copy of CCBot in the current directory, so run it as root from the root of a clone:
sudo apt install python3-venv
git clone https://github.com/MegaManSec/CCBot.git
cd CCBot
sudo ./install.sh "https://hooks.slack.com/services/[...]"
The script:
- Creates (if necessary) a Python virtual environment in
/opt/ccbot. - Installs the package into that virtual environment.
- Installs, enables and (re)starts a systemd service (
/etc/systemd/system/ccbot.service) that runsccbotin the background. - Configures logging to
/var/log/ccbot.logand/var/log/ccbot_error.log. - Sets up log rotation in
/etc/logrotate.d/ccbot.
When it finishes, it prints ccbot has been installed, the service is started, and log rotation is set up. and the paths it used. If creating the virtual environment fails, delete /opt/ccbot before running the script again.
The URL argument is optional and sets the service's SLACK_WEBHOOK_URL. On a first install without it, the service still starts with an empty webhook, so alerts are only written to /var/log/ccbot.log. To set or change the webhook later, run the installer again with the URL, or edit /etc/systemd/system/ccbot.service and run:
sudo systemctl daemon-reload
sudo systemctl restart ccbot
When reinstalling, the installer rewrites ccbot.service:
- Without an argument, it keeps the existing
EnvironmentandEnvironmentFilelines, including the webhook, exactly as they are, as long asSLACK_WEBHOOK_URLisn't set in the installer's own environment. - With a URL argument, or with
SLACK_WEBHOOK_URLset in its environment (a root shell,sudo -E, orsudo SLACK_WEBHOOK_URL='...' ./install.sh), it replaces all of those lines with that webhook. An empty value clears it. A plainsudodrops variables exported in your shell. - Any other change to
ccbot.serviceis lost, so put other settings in a drop-in withsudo systemctl edit ccbot.
Tests
The tests also run install.sh, which isn't in the PyPI package, so they need a clone of this repository and bash. After the From source steps, run from the root of the clone:
venv/bin/python -m unittest discover -s tests
License
This project is licensed under AGPL-3.0-or-later.
Metadata
Release files for ccbot-py 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ccbot_py-1.1.1.tar.gz | 26.9 kB | With provenance | Details for ccbot_py-1.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ccbot_py-1.1.1-py3-none-any.whl | Python 3 | none | any | Details for ccbot_py-1.1.1-py3-none-any.whl |
Total release size: 47.3 kB
Release files / ccbot_py-1.1.1.tar.gz
| Download URL | ccbot_py-1.1.1.tar.gz |
|---|---|
| Size | 26.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
028f1671749653d7b375ab08330cf257296361d8873fe8760af31093dddce39b
|
|
BLAKE2b-256 checksum How to use checksums |
3552770b6b7dcd89b0357be316c3f72f54d4888b710b3644d77a6bd70a93be43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logRelease files / ccbot_py-1.1.1-py3-none-any.whl
| Download URL | ccbot_py-1.1.1-py3-none-any.whl |
|---|---|
| Size | 20.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e3d1d3a9210b6fd2fb11e451f1b587684e055136cc90362d83df384c97eac5a
|
|
BLAKE2b-256 checksum How to use checksums |
c625631029790e27d7f9957bbd2863ae604aeb4fbc1eefca8f558e6acad82f47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logSecurity for ccbot-py 1.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for ccbot_py-1.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.