

ICARAX Tech Blog – How to confirm that the critical Check Point VPN patches (CVE‑2024‑xxxx) have been applied via the Management API.
Why this matters – The recent Check Point advisory disclosed a remote‑code‑execution flaw in the VPN blade. After applying the hot‑fix, administrators should verify that the device reports the patched version. The code below shows a minimal, production‑ready way to query a Check Point Security Management Server (or Gaia device) and decide if the required patch level is present.
<a name="step-1-prerequisites"></a>
| Item | Minimum version / notes |
|---|---|
| Check Point | R80.20+ Management Server or Gaia device with API enabled (mgmt_cli or REST). |
| API credentials | A user with read role (or admin for full access) – generate an API key or use username/password. |
| Python | 3.9+ (official CPython). |
| Node.js | 18.x LTS (for TypeScript/JavaScript). |
| Package managers | pip (Python) and npm or yarn (JS/TS). |
| Network | Outbound HTTPS (TCP 443) to the Management Server; allow self‑signed certs if you use a dev‑only CA (see troubleshooting). |
| IDE / Editor | VS Code, PyCharm, WebStorm, etc. (optional). |
Tip: If you only need to verify a Gaia gateway, you can hit the Gaia REST API (
https://<gaia_ip>:443/web_api) – the same code works; just change the endpoint.
<a name="step-2-installation-and-setup"></a>
# 1️⃣ Create a virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts\activate
# 2️⃣ Install dependencies
pip install --upgrade pip
pip install requests python-dotenv tqdm
# 1️⃣ Initialise a new npm project
npm init -y
# (or yarn init -y)
# 2️⃣ Install core libs
npm install axios dotenv # axios for HTTP, dotenv for env vars
# For TypeScript support
npm install --save-dev typescript @types/node ts-node
npx tsc --init # creates tsconfig.json (adjust as needed)
Result: You now have a clean project folder with
.venv(Python) ornode_modules(JS/TS) ready to run the examples.
<a name="step-3-basic-implementation"></a>
Both snippets follow the same logical flow:
/show-version (or /show-system-info) to retrieve the current software version.R80.40 Jumbo Hotfix Accumulator 123).Note: The exact version string format varies by product. Adjust
PATCHED_VERSIONto match the advisory you are verifying against.
check_patch.py)#!/usr/bin/env python3
"""
check_patch.py
Verifies that a Check Point Management Server or Gaia device reports the
patched VPN version that mitigates CVE‑2024‑xxxx.
Usage:
export CP_MGMT_HOST="mgmt.example.com"
export CP_API_KEY="<your-api-key>"
python check_patch.py
"""
import os
import sys
import json
import logging
from typing import Tuple
import requests
from dotenv import load_dotenv
from tqdm import tqdm # optional progress bar for demo purposes
# ----------------------------------------------------------------------
# Configuration (loaded from .env or environment)
# ----------------------------------------------------------------------
load_dotenv() # reads .env file into os.environ
CP_MGMT_HOST = os.getenv("CP_MGMT_HOST") # e.g. "mgmt.example.com"
CP_API_KEY = os.getenv("CP_API_KEY") # API key generated via mgmt_cli
CP_USER = os.getenv("CP_USER") # optional: username/password auth
CP_PASSWORD = os.getenv("CP_PASSWORD")
# The version string that indicates the patch is present.
# Replace with the exact string from the Check Point sk/article.
PATCHED_VERSION = "R80.40 Jumbo Hotfix Accumulator 123"
# ----------------------------------------------------------------------
# Logging setup
# ----------------------------------------------------------------------
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
log = logging.getLogger("checkpoint-patch")
# ----------------------------------------------------------------------
# Helper functions
# ----------------------------------------------------------------------
def build_base_url() -> str:
"""Construct the base URL for the Check Point Management API."""
# The API always lives under /web_api
return f"https://{CP_MGMT_HOST}/web_api"
def auth_headers() -> dict:
"""Return HTTP headers for authentication.
Prefer API‑key; fall back to basic auth if needed.
"""
if CP_API_KEY:
return {"Content-Type": "application/json", "X-Chkp-SID": CP_API_KEY}
if CP_USER and CP_PASSWORD:
# This example uses token login; you could also use basic auth.
raise RuntimeError("Username/password flow not shown – use API key for simplicity.")
raise RuntimeError("No authentication credentials provided.")
def get_version() -> Tuple[bool, str]:
"""
Call /show-version and return (success, version_string).
On failure, success=False and version_string contains error info.
"""
url = f"{build_base_url()}/show-version"
try:
resp = requests.get(
url,
headers=auth_headers(),
verify=False, # Set to True in prod; use proper CA bundle.
timeout=10,
)
resp.raise_for_status()
data = resp.json()
version = data.get("version", "").strip()
log.info(f"Retrieved version: {version!r}")
return True, version
except requests.RequestException as exc:
log.error(f"HTTP request failed: {exc}")
return False, str(exc)
except (KeyError, json.JSONDecodeError) as exc:
log.error(f"Failed to parse response: {exc}")
return False, str(exc)
def is_patched(version: str) -> bool:
"""
Simple substring check – adjust as needed for your version scheme.
"""
return PATCHED_VERSION in version
def main() -> int:
"""Entry point – returns 0 if patched, 1 otherwise."""
if not CP_MGMT_HOST:
log.error("Environment variable CP_MGMT_HOST is missing.")
return 1
# Show a tiny progress bar just for demo; remove in production.
for _ in tqdm(range(1), desc="Checking patch status", unit="step"):
ok, version_or_err = get_version()
if not ok:
log.error(f"Unable to retrieve version: {version_or_err}")
return 1
patched = is_patched(version_or_err)
if patched:
log.info("✅ Patch detected – system is up‑to‑date.")
return 0
else:
log.warning(
f"⚠️ Patch NOT detected. Current version: {version_or_err!r} "
f"(expected to contain {PATCHED_VERSION!r})"
)
return 1
if __name__ == "__main__":
sys.exit(main())
How to run
export CP_MGMT_HOST="mgmt.corp.example.com"
export CP_API_KEY="abcd1234-ef56-7890-abcd-ef1234567890"
python check_patch.py
Exit code 0 → patched; 1 → not patched or error.
check-patch.ts)/**
* check-patch.ts
* Verifies that a Check Point Management Server or Gaia device reports the
* patched VPN version that mitigates CVE‑2024‑xxxx.
*
* Prerequisites:
* - Node.js >=18
* - .env file with CP_MGMT_HOST and CP_API_KEY (or CP_USER/CP_PASSWORD)
*
* Run:
* npm install axios dotenv
* npx ts-node check-patch.ts
*/
import axios, { AxiosInstance, AxiosResponse } from "axios";
import * as dotenv from "dotenv";
import { log, info, warn, error } from "console"; // simple logging; replace with winston/pino in prod
dotenv.config();
// -------------------------- Configuration --------------------------
const CP_MGMT_HOST: string | undefined = process.env.CP_MGMT_HOST;
const CP_API_KEY: string | undefined = process.env.CP_API_KEY;
const CP_USER: string | undefined = process.env.CP_USER;
const CP_PASSWORD: string | undefined = process.env.CP_PASSWORD;
// Version string that signals the patch is present (update per advisory)
const PATCHED_VERSION = "R80.40 Jumbo Hotfix Accumulator 123";
if (!CP_MGMT_HOST) {
error("Missing CP_MGMT_HOST environment variable");
process.exit(1);
}
// -------------------------- HTTP client --------------------------
const baseURL = `https://${CP_MGMT_HOST}/web_api`;
const client: AxiosInstance = axios.create({
baseURL,
timeout: 10_000,
// In production, set `verify` to true and provide proper CA bundle.
// For self‑signed dev certs:
httpsAgent: undefined, // let Node decide; you can inject a custom agent if needed.
});
// Attach auth header (API‑key preferred)
if (CP_API_KEY) {
client.defaults.headers.common["X-Chkp-SID"] = CP_API_KEY;
} else if (CP_USER && CP_PASSWORD) {
// Example of basic auth – you could also perform a login call first.
client.defaults.auth = { username: CP_USER, password: CP_PASSWORD };
} else {
error("No authentication credentials provided (API key or user/pass).");
process.exit(1);
}
// -------------------------- Helper functions --------------------------
async function getVersion(): Promise<{ success: boolean; versionOrError: string }> {
try {
const resp: AxiosResponse = await client.get("/show-version");
const version: string = resp.data.version?.trim() ?? "";
info(`Retrieved version: "${version}"`);
return { success: true, versionOrError: version };
} catch (err: any) {
if (axios.isAxiosError(err)) {
error(`HTTP error: ${err.message}`);
return { success: false, versionOrError: err.message };
}
error(`Unexpected error: ${err}`);
return { success: false, versionOrError: String(err) };
}
}
function isPatched(version: string): boolean {
// Simple substring check – replace with semver logic if needed.
return version.includes(PATCHED_VERSION);
}
// -------------------------- Main --------------------------
(async () => {
const { success, versionOrError } = await getVersion();
if (!success) {
error(`Failed to obtain version: ${versionOrError}`);
process.exit(1);
}
const patched = isPatched(versionOrError);
if (patched) {
info("✅ Patch detected – system is up‑to‑date.");
process.exit(0);
} else {
warn(
`⚠️ Patch NOT detected. Current version: "${versionOrError}" ` +
`(expected to contain "${PATCHED_VERSION}")`
);
process.exit(1);
}
})();
How to run
export CP_MGMT_HOST="mgmt.corp.example.com"
export CP_API_KEY="abcd1234-ef56-7890-abcd-ef1234567890"
npx ts-node check-patch.ts
# or compile first:
# npx tsc && node dist/check-patch.js
Exit code 0 → patched; 1 → not patched or error.
<a name="step-4-configuration"></a>
| Variable | Description | Example | Required? |
|---|---|---|---|
CP_MGMT_HOST | Hostname or IP of the Check Point Management Server (or Gaia device). | mgmt.example.com | ✅ |
CP_API_KEY | API key generated via mgmt_cli login → show api-key or via SmartConsole. | a1b2c3d4-5678-90ab-cdef-1234567890ab | ✅ (if using key auth) |
CP_USER | Username for password‑based auth (optional). | admin | ❌ |
CP_PASSWORD | Password for the above user (optional). | s3cr3t! | ❌ |
PATCHED_VERSION (hard‑coded) | The exact version string that indicates the hotfix is installed. Update per the Check Point SK article. | R80.40 Jumbo Hotfix Accumulator 123 | ✅ (code) |
NODE_TLS_REJECT_UNAUTHORIZED (Node) | Set to 0 only in dev/test environments with self‑signed certs. Never in prod. | 0 | ❌ |
REQUESTS_CA_BUNDLE (Python) | Path to a custom CA bundle if your org uses an internal PKI. | /etc/ssl/certs/ca-bundle.crt | ❌ |
Sample .env (never commit to VCS)
CP_MGMT_HOST=mgmt.corp.example.com
CP_API_KEY=a1b2c3d4-5678-90ab-cdef-1234567890ab
# CP_USER=admin
# CP_PASSWORD=superSecret!
Security tip: Store secrets in a vault (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) and inject them at runtime rather than keeping them in plain files.
<a name="step-5-common-patterns"></a>
| Pattern | Why it’s useful | Python example | TypeScript example |
|---|---|---|---|
| Retry with exponential backoff | Handles transient network glitches. | tenacity library or custom loop. | axios-retry or manual setTimeout. |
| Centralised logger | Uniform output, easy to switch to JSON logs for SIEM. | logging + structlog. | pino or winston. |
| Config validation | Fail fast if required vars missing. | pydantic.BaseSettings. | zod or joi. |
| Separation of concerns | API client vs. business logic. | Create CheckPointClient class. | Create CheckPointApi class. |
| Type safety | Prevents runtime bugs. | Use TypedDict / dataclasses. | TypeScript interfaces. |
| Graceful shutdown | Handles SIGINT/SIGTERM in long‑running services. | signal module. | process.on('SIGINT', ...). |
Illustrative retry wrapper (Python)
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import requests
@retry(
reraise=True,
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10),
retry=retry_if_exception_type(requests.RequestException),
)
def safe_get(url: str, **kwargs) -> requests.Response:
return requests.get(url, **kwargs)
Illustrative retry wrapper (TS)
import axios from "axios";
import { retry } from "axios-retry";
const api = axios.create({ baseURL, timeout: 8000 });
retry(api, { retries: 3, retryDelay: (retryCount) => Math.pow(2, retryCount) * 1000 });
<a name="step-6-troubleshooting"></a>
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized / X-Chkp-SID missing | API key expired or incorrect. | Regenerate key via mgmt_cli login -u <user> -p <password> → show api-key. |
SSL: CERTIFICATE_VERIFY_FAILED | Self‑signed or internal CA not trusted. | Add the CA to trust store (certifi for Python, NODE_EXTRA_CA_CERTS for Node) or set verify=False/rejectUnauthorized: false only for testing. |
404 Not Found on /show-version | Talking to a Gaia device that uses a different API base (/web_api is still correct for R80.10+; older versions need /api/v1.0). | Verify OS version; for Gaia <R80.10 use /api/v1.0/show-version. |
Timeout (ReadTimeoutError) | Network firewall blocking TCP 443 or host unreachable. | Check routing, VPN, and that the management interface is reachable (ping, telnet <host> 443). |
| Empty version string | API returned success but no version field (possible permission issue). | Ensure the API key/user has at least Read role on the domain. |
ECONNREFUSED | Service not listening on 443 (maybe API disabled). | Enable API: mgmt_cli set global-properties api-status true (or via SmartConsole). |
| Unexpected JSON parsing error | Response is HTML (e.g., login portal) due to redirect. | Confirm you are using https:// and not hitting a captive portal; check for proxy interception. |
Quick diagnostic script (Python)
import requests, socket, sys
host = sys.argv[1] if len(sys.argv) > 1 else "mgmt.example.com"
port = 443
try:
sock = socket.create_connection((host, port), timeout=5)
sock.close()
print(f"TCP {host}:{port} reachable")
except OSError as e:
print(f"TCP connect failed: {e}")
# Try a GET with insecure TLS to see if we get a response
try:
r = requests.get(f"https://{host}/web_api/show-version", verify=False, timeout=5)
print(f"HTTP status: {r.status_code}")
print(r.text[:200])
except Exception as e:
print(f"Request error: {e}")
<a name="step-7-production-checklist"></a>
| ✅ Item | Description |
|---|---|
| Secrets management | Store CP_API_KEY (or user/pass) in a vault or CI secret store; never commit to git. |
| TLS verification | Set verify=True (Python) / rejectUnauthorized: true (Node) and use a trusted CA bundle. |
| Least‑privilege API user | Create a dedicated API user with only the read role on the relevant domain (no write access). |
| Rate limiting awareness | Check Point API enforces ~30 req/sec per client; implement back‑off if you poll many devices. |
| Idempotent checks | Design the script to be safely run multiple times (e.g., via cron or CI). |
| Observability | Emit structured logs (JSON) to a SIEM; expose Prometheus metrics (patched: 1 / 0). |
| Alerting | Trigger an alert (PagerDuty, Opsgenie, email) when the script exits non‑zero. |
| Version pinning | Lock dependencies (pip freeze > requirements.txt, package-lock.json) to avoid surprise breaking changes. |
| Testing | Write unit tests that mock requests.get / axios.get to verify success/failure branches. |
| Documentation | Keep a README.md with the exact commands to run, required env vars, and how to update PATCHED_VERSION. |
| Patch verification cadence | Run the check after every maintenance window or as part of a post‑deploy pipeline. |
| Fail‑closed | If the script cannot reach the device, treat it as unknown and raise an incident rather than assuming patched. |
| Backup | Keep a copy of the pre‑patch configuration (via mgmt_cli show configuration) in case rollback is needed. |
You now have:
check_patch.py) that talks to the Check Point Management API, validates the VPN patch level, and returns an appropriate exit code.check-patch.ts) using axios.Deploy these snippets into your automation pipeline (Jenkins, GitHub Actions, GitLab CI, etc.) or run them as a periodic cron job on your management host. When the script exits with code 0, you can be confident that the critical Check Point VPN vulnerability has been mitigated on that system.
Happy patching—and stay secure! 🚀
Source: Security Week AI
Follow ICARAX for more AI insights and tutorials.
