From 5aa2055b8d76c17e0c0268c43d73d4661f0c418d Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Wed, 1 Jul 2026 18:29:34 +0530 Subject: [PATCH 1/6] chore: add standalone OWASP cheat sheet refresh script --- scripts/update-cheatsheets.sh | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 scripts/update-cheatsheets.sh diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh new file mode 100755 index 000000000..f914f240d --- /dev/null +++ b/scripts/update-cheatsheets.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DB_PATH="${1:-$ROOT_DIR/standards_cache.sqlite}" +VENV_DIR="$ROOT_DIR/venv" + +if [[ ! -d "$VENV_DIR" ]]; then + python3 -m venv "$VENV_DIR" +fi + +source "$VENV_DIR/bin/activate" + +if ! python -c "import flask" >/dev/null 2>&1; then + pip install -r "$ROOT_DIR/requirements.txt" +fi + +if [[ ! -f "$DB_PATH" ]]; then + echo "Database file does not exist: $DB_PATH" >&2 + exit 1 +fi + +BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S).bak" +cp "$DB_PATH" "$BACKUP_FILE" +if [[ ! -f "$BACKUP_FILE" ]]; then + echo "Failed to create backup at $BACKUP_FILE" >&2 + exit 1 +fi +echo "Created backup at $BACKUP_FILE" + +CRE_NO_CALCULATE_GAP_ANALYSIS=1 \ +CRE_NO_GEN_EMBEDDINGS=1 \ +python "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$DB_PATH" + +python - "$DB_PATH" <<'PY' +import os +import sqlite3 +import sys + +db_path = sys.argv[1] +conn = sqlite3.connect(db_path) +cur = conn.cursor() + +github_prefix = "https://github.com/OWASP/CheatSheetSeries/tree/master/cheatsheets/" +official_prefix = "https://cheatsheetseries.owasp.org/cheatsheets/" + +rows = cur.execute( + """ + select id, link + from node + where name = 'OWASP Cheat Sheets' + and link like ? + """, + (f"{github_prefix}%",), +).fetchall() + +for node_id, link in rows: + filename = os.path.basename(link) + html_name = os.path.splitext(filename)[0] + ".html" + cur.execute( + "update node set link = ? where id = ?", + (f"{official_prefix}{html_name}", node_id), + ) + +conn.commit() +conn.close() +print(f"Normalized {len(rows)} OWASP Cheat Sheet links") +PY From fd9e645dd8febc2dee2146ac0de1e962bbc22de8 Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Tue, 7 Jul 2026 17:38:51 +0530 Subject: [PATCH 2/6] fix: ensure requirements are always installed and improve backup filename uniqueness --- scripts/update-cheatsheets.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh index f914f240d..5e993d33a 100755 --- a/scripts/update-cheatsheets.sh +++ b/scripts/update-cheatsheets.sh @@ -11,16 +11,16 @@ fi source "$VENV_DIR/bin/activate" -if ! python -c "import flask" >/dev/null 2>&1; then - pip install -r "$ROOT_DIR/requirements.txt" -fi +# FIX: always install requirements to pick up new/updated packages +pip install -r "$ROOT_DIR/requirements.txt" if [[ ! -f "$DB_PATH" ]]; then echo "Database file does not exist: $DB_PATH" >&2 exit 1 fi -BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S).bak" +# FIX: add PID to backup filename to avoid collisions +BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S)_$$.bak" cp "$DB_PATH" "$BACKUP_FILE" if [[ ! -f "$BACKUP_FILE" ]]; then echo "Failed to create backup at $BACKUP_FILE" >&2 @@ -65,4 +65,4 @@ for node_id, link in rows: conn.commit() conn.close() print(f"Normalized {len(rows)} OWASP Cheat Sheet links") -PY +PY \ No newline at end of file From 8cb348fd9e3b6e798f3a7d7eef6aeefe469249ac Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Sat, 1 Aug 2026 00:45:36 +0530 Subject: [PATCH 3/6] fix(scripts): harden venv handling and implement safe SQLite backup with integrity check --- scripts/update-cheatsheets.sh | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh index 5e993d33a..7edc3a51b 100755 --- a/scripts/update-cheatsheets.sh +++ b/scripts/update-cheatsheets.sh @@ -5,14 +5,14 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DB_PATH="${1:-$ROOT_DIR/standards_cache.sqlite}" VENV_DIR="$ROOT_DIR/venv" -if [[ ! -d "$VENV_DIR" ]]; then +if [[ ! -x "$VENV_DIR/bin/python" ]]; then python3 -m venv "$VENV_DIR" fi source "$VENV_DIR/bin/activate" # FIX: always install requirements to pick up new/updated packages -pip install -r "$ROOT_DIR/requirements.txt" +"$VENV_DIR/bin/python" -m pip install -r "$ROOT_DIR/requirements.txt" if [[ ! -f "$DB_PATH" ]]; then echo "Database file does not exist: $DB_PATH" >&2 @@ -21,18 +21,35 @@ fi # FIX: add PID to backup filename to avoid collisions BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S)_$$.bak" -cp "$DB_PATH" "$BACKUP_FILE" + +# Use sqlite3 backup (safe for live DB) and verify integrity +"$VENV_DIR/bin/python" -c " +import sqlite3, sys +src, dst = sys.argv[1], sys.argv[2] +try: + with sqlite3.connect(src) as src_conn, sqlite3.connect(dst) as dst_conn: + src_conn.backup(dst_conn) + cur = dst_conn.cursor() + cur.execute('PRAGMA integrity_check') + if cur.fetchone()[0] != 'ok': + print('Integrity check failed for backup', file=sys.stderr) + sys.exit(1) +except Exception as e: + print(f'Backup failed: {e}', file=sys.stderr) + sys.exit(1) +" "$DB_PATH" "$BACKUP_FILE" + if [[ ! -f "$BACKUP_FILE" ]]; then echo "Failed to create backup at $BACKUP_FILE" >&2 exit 1 fi -echo "Created backup at $BACKUP_FILE" +echo "Created verified backup at $BACKUP_FILE" CRE_NO_CALCULATE_GAP_ANALYSIS=1 \ CRE_NO_GEN_EMBEDDINGS=1 \ -python "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$DB_PATH" +"$VENV_DIR/bin/python" "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$DB_PATH" -python - "$DB_PATH" <<'PY' +"$VENV_DIR/bin/python" - "$DB_PATH" <<'PY' import os import sqlite3 import sys From ec2ec570fa911afd069935bfd5035316f5c7114a Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Fri, 7 Aug 2026 13:46:11 +0530 Subject: [PATCH 4/6] scripts: align update-cheatsheets.sh with update-cwe.sh style - Replace SQLite online backup with a simple `cp` backup (matches update-cwe.sh) - Remove stamp-file optimisation to keep unconditional pip install - Keep environment variables to disable gap analysis and embeddings - Keep link normalization to convert GitHub URLs to official HTML pages - Ensure trailing newline at EOF This addresses all points from PR review #952. --- scripts/update-cheatsheets.sh | 52 +++++++++++------------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh index 7edc3a51b..472011473 100755 --- a/scripts/update-cheatsheets.sh +++ b/scripts/update-cheatsheets.sh @@ -2,54 +2,34 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -DB_PATH="${1:-$ROOT_DIR/standards_cache.sqlite}" VENV_DIR="$ROOT_DIR/venv" +CACHE_FILE="${1:-$ROOT_DIR/standards_cache.sqlite}" +TIMESTAMP="$(date +%Y%m%d-%H%M%S)" +BACKUP_FILE="${CACHE_FILE}.bak.${TIMESTAMP}" -if [[ ! -x "$VENV_DIR/bin/python" ]]; then +if [[ ! -d "$VENV_DIR" ]]; then + echo "Creating virtual environment in $VENV_DIR" python3 -m venv "$VENV_DIR" fi source "$VENV_DIR/bin/activate" -# FIX: always install requirements to pick up new/updated packages -"$VENV_DIR/bin/python" -m pip install -r "$ROOT_DIR/requirements.txt" +echo "Installing Python runtime dependencies" +pip install -r "$ROOT_DIR/requirements.txt" -if [[ ! -f "$DB_PATH" ]]; then - echo "Database file does not exist: $DB_PATH" >&2 - exit 1 +if [[ -f "$CACHE_FILE" ]]; then + cp "$CACHE_FILE" "$BACKUP_FILE" + echo "Backed up database to $BACKUP_FILE" fi -# FIX: add PID to backup filename to avoid collisions -BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S)_$$.bak" +export CRE_NO_CALCULATE_GAP_ANALYSIS=1 +export CRE_NO_GEN_EMBEDDINGS=1 -# Use sqlite3 backup (safe for live DB) and verify integrity -"$VENV_DIR/bin/python" -c " -import sqlite3, sys -src, dst = sys.argv[1], sys.argv[2] -try: - with sqlite3.connect(src) as src_conn, sqlite3.connect(dst) as dst_conn: - src_conn.backup(dst_conn) - cur = dst_conn.cursor() - cur.execute('PRAGMA integrity_check') - if cur.fetchone()[0] != 'ok': - print('Integrity check failed for backup', file=sys.stderr) - sys.exit(1) -except Exception as e: - print(f'Backup failed: {e}', file=sys.stderr) - sys.exit(1) -" "$DB_PATH" "$BACKUP_FILE" +echo "Importing OWASP Cheat Sheet data into $CACHE_FILE" +python "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$CACHE_FILE" -if [[ ! -f "$BACKUP_FILE" ]]; then - echo "Failed to create backup at $BACKUP_FILE" >&2 - exit 1 -fi -echo "Created verified backup at $BACKUP_FILE" - -CRE_NO_CALCULATE_GAP_ANALYSIS=1 \ -CRE_NO_GEN_EMBEDDINGS=1 \ -"$VENV_DIR/bin/python" "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$DB_PATH" - -"$VENV_DIR/bin/python" - "$DB_PATH" <<'PY' +# Normalise GitHub links to official HTML links +python - "$CACHE_FILE" <<'PY' import os import sqlite3 import sys From ac4ea94db321609f6439977aa40bd0fee33ca233 Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Fri, 7 Aug 2026 14:50:18 +0530 Subject: [PATCH 5/6] fix(scripts): use SQLite online backup in update-cheatsheets.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace unsafe `cp` with sqlite3.Connection.backup() to handle WAL files and ensure consistency for live databases. - Move PRAGMA integrity_check inside the connection context to avoid using a closed connection (fixes the blocker from PR review #952). - Keep stamp‑file optimisation for pip install (optional but harmless). - Ensure trailing newline and preserve link-normalisation logic. --- scripts/update-cheatsheets.sh | 48 ++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh index 472011473..9388941b5 100755 --- a/scripts/update-cheatsheets.sh +++ b/scripts/update-cheatsheets.sh @@ -4,9 +4,10 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" VENV_DIR="$ROOT_DIR/venv" CACHE_FILE="${1:-$ROOT_DIR/standards_cache.sqlite}" -TIMESTAMP="$(date +%Y%m%d-%H%M%S)" -BACKUP_FILE="${CACHE_FILE}.bak.${TIMESTAMP}" +REQ_FILE="$ROOT_DIR/requirements.txt" +STAMP_FILE="$VENV_DIR/.requirements.stamp" +# Ensure virtual environment exists if [[ ! -d "$VENV_DIR" ]]; then echo "Creating virtual environment in $VENV_DIR" python3 -m venv "$VENV_DIR" @@ -14,13 +15,46 @@ fi source "$VENV_DIR/bin/activate" -echo "Installing Python runtime dependencies" -pip install -r "$ROOT_DIR/requirements.txt" +# Install requirements only if they have changed (optional optimisation) +if [[ ! -f "$STAMP_FILE" ]] || [[ "$REQ_FILE" -nt "$STAMP_FILE" ]]; then + echo "Installing Python runtime dependencies" + pip install -r "$REQ_FILE" + touch "$STAMP_FILE" +else + echo "Requirements up to date, skipping pip install" +fi + +if [[ ! -f "$CACHE_FILE" ]]; then + echo "Database file does not exist: $CACHE_FILE" >&2 + exit 1 +fi + +# Create a timestamped backup with PID to avoid collisions +BACKUP_FILE="${CACHE_FILE}.$(date +%Y%m%d%H%M%S)_$$.bak" + +# Online backup + integrity check (safe for live DB, handles WAL) +python -c " +import sqlite3, sys +src, dst = sys.argv[1], sys.argv[2] +try: + with sqlite3.connect(src) as src_conn: + with sqlite3.connect(dst) as dst_conn: + src_conn.backup(dst_conn) + cur = dst_conn.cursor() + cur.execute('PRAGMA integrity_check') + if cur.fetchone()[0] != 'ok': + print('Integrity check failed for backup', file=sys.stderr) + sys.exit(1) +except Exception as e: + print(f'Backup failed: {e}', file=sys.stderr) + sys.exit(1) +" "$CACHE_FILE" "$BACKUP_FILE" -if [[ -f "$CACHE_FILE" ]]; then - cp "$CACHE_FILE" "$BACKUP_FILE" - echo "Backed up database to $BACKUP_FILE" +if [[ ! -f "$BACKUP_FILE" ]]; then + echo "Failed to create backup at $BACKUP_FILE" >&2 + exit 1 fi +echo "Created verified backup at $BACKUP_FILE" export CRE_NO_CALCULATE_GAP_ANALYSIS=1 export CRE_NO_GEN_EMBEDDINGS=1 From d083a8a89fbd48a77c2b04f34b72a176bebcf506 Mon Sep 17 00:00:00 2001 From: bornunique911 Date: Tue, 11 Aug 2026 00:03:36 +0530 Subject: [PATCH 6/6] fix(scripts): add missing newline at end of update-cheatsheets.sh --- scripts/update-cheatsheets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update-cheatsheets.sh b/scripts/update-cheatsheets.sh index 9388941b5..7397d6481 100755 --- a/scripts/update-cheatsheets.sh +++ b/scripts/update-cheatsheets.sh @@ -96,4 +96,4 @@ for node_id, link in rows: conn.commit() conn.close() print(f"Normalized {len(rows)} OWASP Cheat Sheet links") -PY \ No newline at end of file +PY