From 4f97b35b74e2ef03168f98dcf796ff821a4f492d Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 02:56:56 +0700 Subject: [PATCH] use API Token in favour of API Key for better security --- .env.example | 3 +-- .github/images/create_api_token.png | Bin 0 -> 36167 bytes README.md | 3 +-- auto_update_github_action.yml | 6 ++--- extended_guide.md | 12 ++++++---- lib/constants.js | 15 ++++++++---- lib/helpers.js | 36 +++++++++++++++++++--------- 7 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 .github/images/create_api_token.png diff --git a/.env.example b/.env.example index 83fcadf..a9fb3ae 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ -CLOUDFLARE_API_KEY= +CLOUDFLARE_API_TOKEN= CLOUDFLARE_ACCOUNT_ID= -CLOUDFLARE_ACCOUNT_EMAIL= CLOUDFLARE_LIST_ITEM_LIMIT=300000 DRY_RUN=0 FAST_MODE=0 diff --git a/.github/images/create_api_token.png b/.github/images/create_api_token.png new file mode 100644 index 0000000000000000000000000000000000000000..19350e484afbc67a3d8cee9d283e91339b61ca77 GIT binary patch literal 36167 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 B&yoND literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 2b728e0..cb3ac46 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,8 @@ Please note that the GitHub Action downloads the recommended blocklists and whit 1. Create a new empty, private repository. Forking or public repositories are discouraged, but supported - although the script never leaks your API keys and GitHub Actions secrets are automatically redacted from the logs, it's better to be safe than sorry. 2. Create the following GitHub Actions secrets in your repository settings: -- `CLOUDFLARE_API_KEY`: Your Cloudflare API key +- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API Token with Zero Trust read and write permissions - `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID -- `CLOUDFLARE_ACCOUNT_EMAIL`: Your Cloudflare account email - `CLOUDFLARE_LIST_ITEM_LIMIT`: The maximum number of blocked domains allowed for your Cloudflare Zero Trust plan. Use 300000 for the free plan or if you're unsure. - `PING_URL`: /Optional/ The HTTP(S) URL to ping (using curl) after the GitHub Action has successfully updated your filters. Useful for monitoring. diff --git a/auto_update_github_action.yml b/auto_update_github_action.yml index 8223210..47a4311 100644 --- a/auto_update_github_action.yml +++ b/auto_update_github_action.yml @@ -46,8 +46,7 @@ jobs: - name: Delete old rules and lists run: npm run cloudflare-delete env: - CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} - CLOUDFLARE_ACCOUNT_EMAIL: ${{ secrets.CLOUDFLARE_ACCOUNT_EMAIL }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_LIST_ITEM_LIMIT: ${{ secrets.CLOUDFLARE_LIST_ITEM_LIMIT }} FAST_MODE: ${{ vars.FAST_MODE }} @@ -55,8 +54,7 @@ jobs: - name: Create new rules and lists run: npm run cloudflare-create env: - CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} - CLOUDFLARE_ACCOUNT_EMAIL: ${{ secrets.CLOUDFLARE_ACCOUNT_EMAIL }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_LIST_ITEM_LIMIT: ${{ secrets.CLOUDFLARE_LIST_ITEM_LIMIT }} FAST_MODE: ${{ vars.FAST_MODE }} diff --git a/extended_guide.md b/extended_guide.md index 3d43c3e..8b22a19 100644 --- a/extended_guide.md +++ b/extended_guide.md @@ -16,13 +16,17 @@ https://dash.cloudflare.com/1234567890abcdef1234567890abcdef In this example, `1234567890abcdef1234567890abcdef` is the account ID. -### `CLOUDFLARE_API_KEY` +### `CLOUDFLARE_API_TOKEN` -The Cloudflare API key can be found in the [Cloudflare dashboard](https://dash.cloudflare.com/) too. Click on your profile picture (or user icon) in the top right corner, then click on "API Tokens" in the sidebar. Scroll down to the "API Keys" section and click on "View" next to the Global API Key. +Cloudflare API Token can be created in your [Cloudflare profile](https://dash.cloudflare.com/profile/api-tokens): -### `CLOUDFLARE_ACCOUNT_EMAIL` +1. Click "Create Token" and click "Get Started" in the "Create Custom Token" row. +2. Enter any name for your token +3. Add Zero Trust Read and Edit permissions for your account +4. Click "Continue to summary" and click "Create Token" +5. You will see the created API Token -The Cloudflare account email is the email address you use to log in to the Cloudflare dashboard. +![Creating API Token](.github/images/create_api_token.png) ### `CLOUDFLARE_LIST_ITEM_LIMIT` diff --git a/lib/constants.js b/lib/constants.js index 9567b91..5ed46e1 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -2,7 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); -export const API_TOKEN = process.env.CLOUDFLARE_API_KEY; +if (process.env.CLOUDFLARE_API_KEY) { + console.warn( + "Using Global API Key is very risky for your Cloudflare account. It is strongly recommended to create an API Token with scoped permissions instead." + ); +} + +export const API_KEY = process.env.CLOUDFLARE_API_KEY; + +export const API_TOKEN = process.env.CLOUDFLARE_API_TOKEN; export const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -33,12 +41,11 @@ export const LIST_TYPE = { }; export const USER_DEFINED_ALLOWLIST_URLS = process.env.ALLOWLIST_URLS - // .filter(x => x) removes empty items from the URL arrays - ? process.env.ALLOWLIST_URLS.split("\n").filter(x => x) + ? process.env.ALLOWLIST_URLS.split("\n").filter((x) => x) : undefined; export const USER_DEFINED_BLOCKLIST_URLS = process.env.BLOCKLIST_URLS - ? process.env.BLOCKLIST_URLS.split("\n").filter(x => x) + ? process.env.BLOCKLIST_URLS.split("\n").filter((x) => x) : undefined; export const RECOMMENDED_ALLOWLIST_URLS = [ diff --git a/lib/helpers.js b/lib/helpers.js index 84b4e8f..7c92111 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,4 +1,10 @@ -import { ACCOUNT_EMAIL, ACCOUNT_ID, API_HOST, API_TOKEN } from "./constants.js"; +import { + ACCOUNT_EMAIL, + ACCOUNT_ID, + API_HOST, + API_KEY, + API_TOKEN, +} from "./constants.js"; if (!globalThis.fetch) { console.warn( @@ -20,20 +26,30 @@ if (!globalThis.fetch) { * @returns {Promise} */ const request = async (url, options) => { - if (!API_TOKEN || !ACCOUNT_ID || !ACCOUNT_EMAIL) { + if (!(API_TOKEN || API_KEY) || !ACCOUNT_ID) { throw new Error( - "One or more required secrets have not been added: CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID, and CLOUDFLARE_ACCOUNT_EMAIL" + "The following secrets are required: CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID" ); } + const headers = API_TOKEN + ? { + Authorization: `Bearer ${API_TOKEN}`, + "Content-Type": "application/json", + } + : { + Authorization: `Bearer ${API_KEY}`, + "Content-Type": "application/json", + "X-Auth-Email": ACCOUNT_EMAIL, + "X-Auth-Key": API_KEY, + }; + const response = await fetch(url, { - headers: { - Authorization: `Bearer ${API_TOKEN}`, - "Content-Type": "application/json", - "X-Auth-Email": ACCOUNT_EMAIL, - "X-Auth-Key": API_TOKEN, - }, ...options, + headers: { + ...options.headers, + ...headers, + }, }); if (!response.ok) { @@ -42,8 +58,6 @@ const request = async (url, options) => { const data = await response.json(); - console.log(`HTTP request succeeded: ${data.success}`); - return data; };