summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Fennell <matthew@fennell.dev>2026-10-18 18:27:35 +0100
committerMatthew Fennell <matthew@fennell.dev>2026-10-18 18:34:59 +0100
commitd149f04b58b11b0743dca9c482c36a1429a576af (patch)
tree623b4a1a4af94a8de102fb91c392c553d1e9ca11
parentfc0e4f879be8ab80b53dd4f258d9ed7604b3cce9 (diff)
Check for tampering in CSQLite sources
This script tries to ensure that CSQLite does not tamper with their SQLite sources. For each file in the repo, we determine whether it came from upstream SQLite or was added specifically for the package. We compare files from upstream with upstream's SQLite sources. For files that originate from CSQLite itself, we compare to the last known good commit, which received a full review. Our old clemensg/sqlite3pod CocoaPods dependency was a source package, which merely downloaded the sources from upstream and unpacked them itself. This gave more assurance that we were receiving actual upstream sources, with minimal/auditable packaging code. Since SwiftPM doesn't allow connection to the internet while sandboxed, this source package approach isn't as easy in the SwiftPM world; the relevant sources are vendored in the package. As we continue to bump the dependency, we want to ensure that nothing has been added in these intermediate vendored files. The script is slightly hacky at the moment, but can be improved as time goes on.
-rwxr-xr-xcsqlite/check-matches-upstream.sh91
1 files changed, 91 insertions, 0 deletions
diff --git a/csqlite/check-matches-upstream.sh b/csqlite/check-matches-upstream.sh
new file mode 100755
index 0000000..9f11502
--- /dev/null
+++ b/csqlite/check-matches-upstream.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+# SPDX-FileCopyrightText: 2026 Matthew Fennell <matthew@fennell.dev>
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+set -eux
+set -o pipefail
+
+# Each file not in upstream sqlite was manually checked at this commit
+known_safe_commit="d4560f1f808381e07b1f8673c51190c52bdca468"
+day_before_known_safe_commit="2026-08-21"
+
+working_dir=$(mktemp -d)
+cd "${working_dir}"
+
+table=$(curl --silent https://sqlite.org/download.html | grep -A 2 ^PRODUCT,VERSION,RELATIVE-URL,SIZE-IN-BYTES,SHA3-HASH | tail -n 2)
+amalgamation=$(echo "${table}" | grep sqlite-amalgamation)
+src=$(echo "${table}" | grep sqlite-src)
+
+amalgamation_relative_url=$(echo "${amalgamation}" | cut -d , -f 3)
+amalgamation_url="https://sqlite.org/${amalgamation_relative_url}"
+
+src_relative_url=$(echo "${src}" | cut -d , -f 3)
+src_url="https://sqlite.org/${src_relative_url}"
+
+amalgamation_hash=$(echo "${amalgamation}" | cut -d , -f 5)
+src_hash=$(echo "${src}" | cut -d , -f 5)
+
+git clone --shallow-since "${day_before_known_safe_commit}" https://github.com/sbooth/CSQLite.git CSQLite
+
+cp -r CSQLite csqlite-reference
+mv CSQLite csqlite-new
+
+cd "${working_dir}/csqlite-reference"
+git checkout "${known_safe_commit}"
+cd "${working_dir}"
+
+wget "${amalgamation_url}" --output-document amalgamation.zip
+wget "${src_url}" --output-document src.zip
+
+amalgamation_calculated_hash=$(openssl dgst -sha3-256 amalgamation.zip | cut -d = -f 2 | sed 's/ //g')
+src_calculated_hash=$(openssl dgst -sha3-256 src.zip | cut -d = -f 2 | sed 's/ //g')
+
+if [[ "${amalgamation_calculated_hash}" != "${amalgamation_hash}" ]]; then
+ echo "Calculated amalgamation hash ${amalgamation_calculated_hash} did not match with upstream ${amalgamation_hash}"
+ exit 1
+fi
+
+if [[ "${src_calculated_hash}" != "${src_hash}" ]]; then
+ echo "Calculated src hash ${src_calculated_hash} did not match with upstream ${src_hash}"
+ exit 1
+fi
+
+unzip amalgamation.zip
+unzip src.zip
+
+mv sqlite-amalgamation-* amalgamation
+mv sqlite-src-* src
+
+# Compare files copied from upstream sqlite to the upstream versions
+diff --unified --color amalgamation/sqlite3.c csqlite-new/Sources/CSQLite/sqlite3.c
+diff --unified --color amalgamation/sqlite3.h csqlite-new/Sources/CSQLite/include/sqlite3.h
+diff --unified --color src/ext/misc/decimal.c csqlite-new/Sources/CSQLite/decimal.c
+diff --unified --color src/ext/misc/ieee754.c csqlite-new/Sources/CSQLite/ieee754.c
+diff --unified --color src/ext/misc/series.c csqlite-new/Sources/CSQLite/series.c
+diff --unified --color src/ext/misc/shathree.c csqlite-new/Sources/CSQLite/shathree.c
+diff --unified --color src/ext/misc/uuid.c csqlite-new/Sources/CSQLite/uuid.c
+diff --unified --color src/src/sqlite3ext.h csqlite-new/Sources/CSQLite/include/sqlite3ext.h
+
+# Compare files not copied from upstream sqlite to known safe version
+diff --unified --color csqlite-reference/.github/dependabot.yml csqlite-new/.github/dependabot.yml
+diff --unified --color csqlite-reference/.github/workflows/swift.yml csqlite-new/.github/workflows/swift.yml
+diff --unified --color csqlite-reference/.gitignore csqlite-new/.gitignore
+diff --unified --color csqlite-reference/LICENSE.md csqlite-new/LICENSE.md
+diff --unified --color csqlite-reference/Package.swift csqlite-new/Package.swift
+diff --unified --color csqlite-reference/Package@swift-5.3.swift csqlite-new/Package@swift-5.3.swift
+diff --unified --color csqlite-reference/README.md csqlite-new/README.md
+diff --unified --color csqlite-reference/Sources/CSQLite/csqlite_shims.c csqlite-new/Sources/CSQLite/csqlite_shims.c
+diff --unified --color csqlite-reference/Sources/CSQLite/include/csqlite_shims.h csqlite-new/Sources/CSQLite/include/csqlite_shims.h
+diff --unified --color csqlite-reference/Sources/CSQLite/include/module.modulemap csqlite-new/Sources/CSQLite/include/module.modulemap
+diff --unified --color csqlite-reference/Tests/CSQLiteTests/CSQLiteBasicTests.swift csqlite-new/Tests/CSQLiteTests/CSQLiteBasicTests.swift
+diff --unified --color csqlite-reference/Tests/CSQLiteTests/CSQLiteExtensionTests.swift csqlite-new/Tests/CSQLiteTests/CSQLiteExtensionTests.swift
+diff --unified --color csqlite-reference/Tests/CSQLiteTests/CSQLiteFeatureTests.swift csqlite-new/Tests/CSQLiteTests/CSQLiteFeatureTests.swift
+
+# Compare directory structure, check for newly created files
+find csqlite-reference -printf "%P\n" | sort > csqlite-reference.files
+find csqlite-new -printf "%P\n" | sort > csqlite-new.files
+diff --unified --color csqlite-reference.files csqlite-new.files
+
+echo "No differences found"