joplin-server-bin
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 (anthropic/claude-4.6-sonnet-20260217) reviewed this and agrees it is MEDIUM (confidence 82%): This PKGBUILD pulls Joplin Server from the official Docker Hub registry (registry-1.docker.io) using the standard Docker Registry v2 API with bearer token authentication - a known and legitimate pattern for packaging Docker-image-based software in AUR. The source is the official joplin/server image from a well-known vendor. The cheaper model's HIGH rating is a false positive in terms of malware/RCE. However, there is a genuine medium-severity concern: the Docker image layers are fetched in prepare() outside of the source=() array, bypassing makepkg's integrity verification. The manifest digest is used to identify the correct manifest, but the individual layer blobs are extracted without verifying their digests against the manifest's declared layer digests (even though those digests are available in the manifest JSON). This means a compromised registry response or MITM could substitute layer content. This is a real but non-malicious packaging weakness - the maintainer is not acting maliciously, but the lack of layer digest verification is a legitimate security concern worth flagging at medium severity.
PKGBUILD
4 offending line(s) highlighted_pkgname=joplin-server
_image=joplin/server
pkgname="$_pkgname-bin"
pkgver=3.7.1
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=('adac9f3a6df5a29c4fa865249e9c8b65cd6b582271fb9e69d99c4b9ebc83f5fa'
'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"
}
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | MEDIUM | 2 |
| 2026-08-02 00:16:08 | MEDIUM | 2 |
| 2026-08-01 00:11:18 | MEDIUM | 2 |
| 2026-07-31 00:14:10 | MEDIUM | 2 |
| 2026-07-30 00:17:23 | MEDIUM | 2 |
| 2026-07-29 00:25:53 | MEDIUM | 2 |
| 2026-07-28 00:07:28 | MEDIUM | 2 |
| 2026-07-27 00:24:32 | MEDIUM | 2 |
| 2026-07-26 00:07:32 | MEDIUM | 2 |
| 2026-07-25 00:13:44 | MEDIUM | 2 |
| 2026-07-24 00:02:28 | MEDIUM | 2 |
| 2026-07-23 00:14:47 | MEDIUM | 2 |
| 2026-07-22 00:29:32 | MEDIUM | 2 |
| 2026-07-21 00:24:15 | MEDIUM | 2 |
| 2026-07-20 00:19:49 | MEDIUM | 2 |
| 2026-07-19 00:17:08 | MEDIUM | 2 |
| 2026-07-18 00:14:48 | MEDIUM | 2 |
| 2026-07-17 00:06:16 | MEDIUM | 2 |
| 2026-07-16 00:05:41 | MEDIUM | 2 |
| 2026-07-15 00:09:25 | MEDIUM | 2 |