joplin-server-bin
The PKGBUILD downloads and extracts Docker image layers directly from registry-1.docker.io during prepare(), which are not included in source=() or verified with checksums, creating a supply-chain risk if the registry or transport were compromised.
Triggered rules
external_download_not_in_source
curl/wget fetches a URL on a non-allowlisted host that is not part of source=(), so it is not checksum-verified by makepkg.
-
PKGBUILD:37
token="$(curl -s "https://auth.docker.io/token?service=$_service&scope=repository:$_image:pull" | jq -r .access_token)" -
PKGBUILD:39
idigest="$(curl -s -H "Authorization: Bearer $token" -H "Accept: $_accept" "https://$_registry/v2/$_image/manifests/$pkgver" \ -
PKGBUILD:42
curl -s -H "Authorization: Bearer $token" -H "Accept: $_vnd" "https://$_registry/v2/$_image/manifests/$idigest" \ -
PKGBUILD:46
count=$(curl -s --follow -H "Authorization: Bearer $token" "https://$_registry/v2/$_image/blobs/$ldigest" \
llm_review
An AI model (qwen/qwen3-235b-a22b-2507) reviewed this and agrees it is MEDIUM (confidence 95%): The PKGBUILD downloads and extracts Docker image layers directly from registry-1.docker.io during prepare(), which are not included in source=() or verified with checksums, creating a supply-chain risk if the registry or transport were compromised.
PKGBUILD
4 offending line(s) highlighted_pkgname=joplin-server
_image=joplin/server
pkgname="$_pkgname-bin"
pkgver=3.7.2
pkgrel=1
pkgdesc='Joplin Server, via Docker image'
arch=('any')
url="https://hub.docker.com/r/$_image"
license=('custom:Joplin-Server-Personal-Use-License')
depends=('nodejs' 'pnpm' 'pm2')
makedepends=('jq')
source=(
"$_pkgname.service"
"$_pkgname.sysusers"
"$_pkgname.tmpfiles"
'https://raw.githubusercontent.com/laurent22/joplin/dev/.env-sample'
)
sha256sums=('2b4bd101041ea99d90d735b65b6bd54573e7424e57fc127c90082034c19c1cde'
'2f3cea9bed6f79d7c93721dd1acb7c3b5c0368be264ae2894bd66034634e694d'
'55455d0ebfcb6ef72b8c4fe934a69ccfd9089f881058933d7cba0c07d7aaffc0'
'e85770c7a0391baa7cf18edeeb64b6a8fe2ccb409d31294d2bde4cd8096cf80f')
backup=("etc/$_pkgname.env")
provides=("$_pkgname")
options=(!strip !debug)
_vnd='application/vnd.docker.distribution.manifest.v2+json'
_vndlist='application/vnd.docker.distribution.manifest.list.v2+json'
_accept="$_vnd,$_vndlist"
_service=registry.docker.io
_registry=registry-1.docker.io
_path=home/joplin/packages
prepare() {
echo "Authenticating to '$_service'"
token="$(curl -s "https://auth.docker.io/token?service=$_service&scope=repository:$_image:pull" | jq -r .access_token)"
echo "Looking up image '$_image:$pkgver' via '$_registry'"
idigest="$(curl -s -H "Authorization: Bearer $token" -H "Accept: $_accept" "https://$_registry/v2/$_image/manifests/$pkgver" \
| jq -r 'if .mediaType == "'"$_vndlist"'" then .manifests[0] else . end | .digest')"
echo "Listing layers for manifest '$idigest'"
curl -s -H "Authorization: Bearer $token" -H "Accept: $_vnd" "https://$_registry/v2/$_image/manifests/$idigest" \
| jq -r '.layers[].digest' \
| while read ldigest; do
echo "Fetching layer '$ldigest'"
count=$(curl -s --follow -H "Authorization: Bearer $token" "https://$_registry/v2/$_image/blobs/$ldigest" \
| 2>&1 tar xzv $_path | grep -Ev 'Not found in archive|Exiting with failure status' | wc -l)
if [ $count -gt 0 ]; then echo "* unpacked $count files"; fi
done
}
package() {
install -d -m 0755 "$pkgdir/usr/lib/$_pkgname"
cp -a "$_path/"* "$pkgdir/usr/lib/$_pkgname/"
install -D -m 0644 "$_path/server/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -D -m 0640 .env-sample "$pkgdir/etc/$_pkgname.env"
ln -s '/var/lib/joplin/logs' "$pkgdir/usr/lib/$_pkgname/server/logs"
ln -s '/var/lib/joplin/temp' "$pkgdir/usr/lib/$_pkgname/server/temp"
install -D -m 0644 "$_pkgname.service" "$pkgdir/usr/lib/systemd/system/$_pkgname.service"
install -D -m 0644 "$_pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$_pkgname.conf"
install -D -m 0644 "$_pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$_pkgname.conf"
}
Changes since previous scan
--- PKGBUILD @ 2026-09-11 00:19+++ PKGBUILD @ 2026-09-17 00:27@@ -2,7 +2,7 @@ _image=joplin/server pkgname="$_pkgname-bin"-pkgver=3.7.1+pkgver=3.7.2 pkgrel=1 pkgdesc='Joplin Server, via Docker image' arch=('any')@@ -16,7 +16,7 @@ "$_pkgname.tmpfiles" 'https://raw.githubusercontent.com/laurent22/joplin/dev/.env-sample' )-sha256sums=('adac9f3a6df5a29c4fa865249e9c8b65cd6b582271fb9e69d99c4b9ebc83f5fa'+sha256sums=('2b4bd101041ea99d90d735b65b6bd54573e7424e57fc127c90082034c19c1cde' '2f3cea9bed6f79d7c93721dd1acb7c3b5c0368be264ae2894bd66034634e694d' '55455d0ebfcb6ef72b8c4fe934a69ccfd9089f881058933d7cba0c07d7aaffc0' 'e85770c7a0391baa7cf18edeeb64b6a8fe2ccb409d31294d2bde4cd8096cf80f')Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-09-17 00:27:14 | Medium | 2 |
| 2026-09-16 00:03:17 | Medium | 2 |
| 2026-09-15 00:25:31 | Medium | 2 |
| 2026-09-14 00:27:57 | Medium | 2 |
| 2026-09-13 00:19:54 | Medium | 2 |
| 2026-09-12 00:25:17 | Medium | 2 |
| 2026-09-11 21:24:02 | Medium | 2 |
| 2026-09-11 00:19:22 | Medium | 2 |
| 2026-09-10 00:22:44 | Medium | 2 |
| 2026-09-09 00:04:09 | Medium | 2 |
| 2026-09-08 00:18:08 | Medium | 2 |
| 2026-09-07 00:30:15 | Medium | 2 |
| 2026-09-06 00:17:06 | Medium | 2 |
| 2026-09-05 00:16:27 | Medium | 2 |
| 2026-09-04 00:03:13 | Medium | 2 |
| 2026-09-03 00:15:47 | Medium | 2 |
| 2026-09-02 00:02:31 | Medium | 2 |
| 2026-09-01 00:11:19 | Medium | 2 |
| 2026-08-31 00:19:57 | Medium | 2 |
| 2026-08-30 00:04:14 | Medium | 2 |