open-design-desktop

LOW
maintainer NickeyGod 0 votes scanned 2026-10-20 00:10:31.152894
View on AUR
Why flagged

The cheaper model flagged `npx --yes pnpm@10.33.2` as remote code execution, but this is a well-known, legitimate pattern: npx is used here only to bootstrap a pinned, versioned release of pnpm (a mainstream Node.js package manager) from the npm registry. The version is explicitly pinned to 10.33.2, which limits (though does not eliminate) supply-chain risk. The source tarball comes from the upstream GitHub repo with a pinned sha256sum, and Node.js is fetched directly from nodejs.org with a pinned sha256sum — both are authoritative, trustworthy sources. The build process is straightforward: install dependencies via pnpm with `--frozen-lockfile` (preventing unexpected dependency changes), then build an AppImage. The package() function extracts the AppImage and installs it under /opt. There is no obfuscation, no encoded payload, no exfiltration, and no substitution of upstream sources. The main residual concern is that `npx --yes pnpm@10.33.2` does fetch and execute code from the npm registry at build time (not from a local cache), which is a minor supply-chain concern common to many Node.js-based AUR packages, warranting low rather than clean. Overall this is a legitimate, if somewhat complex, packaging approach for an Electron/Node.js desktop application.

Triggered rules

Low AI review downgraded a static finding llm_review

The static rules flagged this HIGH, but an AI model (anthropic/claude-sonnet-4.6) reviewed the full PKGBUILD and judged it LOW (confidence 82%): The cheaper model flagged `npx --yes pnpm@10.33.2` as remote code execution, but this is a well-known, legitimate pattern: npx is used here only to bootstrap a pinned, versioned release of pnpm (a mainstream Node.js package manager) from the npm registry. The version is explicitly pinned to 10.33.2, which limits (though does not eliminate) supply-chain risk. The source tarball comes from the upstream GitHub repo with a pinned sha256sum, and Node.js is fetched directly from nodejs.org with a pinned sha256sum — both are authoritative, trustworthy sources. The build process is straightforward: install dependencies via pnpm with `--frozen-lockfile` (preventing unexpected dependency changes), then build an AppImage. The package() function extracts the AppImage and installs it under /opt. There is no obfuscation, no encoded payload, no exfiltration, and no substitution of upstream sources. The main residual concern is that `npx --yes pnpm@10.33.2` does fetch and execute code from the npm registry at build time (not from a local cache), which is a minor supply-chain concern common to many Node.js-based AUR packages, warranting low rather than clean. Overall this is a legitimate, if somewhat complex, packaging approach for an Electron/Node.js desktop application.

1 higher static finding superseded - not the current verdict (shown for transparency)
High npx/bunx/deno executes a remote package remote_code_tool

`npx`/`bunx`/`pnpm dlx`/`deno run <url>` downloads AND runs a remote package at build time — the moral equivalent of piping a download into a shell.

  • PKGBUILD:53 _pnpm() { npx --yes pnpm@10.33.2 "$@"; }

PKGBUILD

1 offending line(s) highlighted
1# Maintainer: NickeyGod <niklass.schaeffer@gmail.com>
2
3pkgname=open-design-desktop
4pkgver=0.24.1
5pkgrel=2
6_tag="open-design-v${pkgver}"
7# Upstream's pack step copies the node binary that runs the build into the
8# package. Arch's node links against system libraries (libsimdjson etc.), so
9# that copy breaks on their next soname bump. The official build is
10# self-contained, and upstream requires Node 24 anyway.
11_nodever=24.21.0
12pkgdesc='Local-first design product: native desktop app & canvas for coding agents (the open-source Claude Design alternative)'
13arch=('x86_64')
14url='https://github.com/nexu-io/open-design'
15license=('Apache-2.0')
16depends=(
17 'alsa-lib'
18 'gtk3'
19 'libnotify'
20 'libxss'
21 'libxtst'
22 'nss'
23 'xdg-utils'
24)
25makedepends=(
26 'git'
27 'python'
28 'make'
29 'gcc'
30)
31provides=('open-design' 'open-design-desktop')
32conflicts=('open-design' 'open-design-git')
33options=('!strip' '!debug')
34
35source=(
36 "${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/${_tag}.tar.gz"
37 "open-design-desktop.sh"
38 "open-design-desktop.desktop"
39 "https://nodejs.org/dist/v${_nodever}/node-v${_nodever}-linux-x64.tar.xz"
40)
41sha256sums=('7b9491a9b4e291209853c90a1224d02ea0d13802d208d40bd1f70f3b8d939fae'
42 '5ae2dfc1943cd7ec376a5c42086cb76b618f14e10c7e92ecbf901f376b6eea6e'
43 '7f86112fce365ab0bc6cc5f7cd415b4bace62c1c2d6252584100b7580290ddd6'
44 'fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6')
45
46_sourcedir="open-design-${_tag}"
47
48build() {
49 cd "${srcdir}/${_sourcedir}"
50
51 export PATH="${srcdir}/node-v${_nodever}-linux-x64/bin:${PATH}"
52
53 _pnpm() { npx --yes pnpm@10.33.2 "$@"; }
54
55 _pnpm install --frozen-lockfile
56 _pnpm tools-pack linux build --to appimage --namespace aur --portable --dir "${srcdir}/tools-pack"
57}
58
59package() {
60 cd "${srcdir}/${_sourcedir}"
61
62 local _appimage _extract_dir
63 _appimage="$(find "${srcdir}/tools-pack/out/linux/namespaces/aur/builder" -maxdepth 1 -type f -name '*.AppImage' -print -quit)"
64 if [[ -z "${_appimage}" ]]; then
65 echo "Error: no AppImage found under ${srcdir}/tools-pack/out/linux/namespaces/aur/builder" >&2
66 return 1
67 fi
68
69 _extract_dir="${srcdir}/open-design-appdir"
70 rm -rf "${_extract_dir}"
71 mkdir -p "${_extract_dir}"
72 (cd "${_extract_dir}" && "${_appimage}" --appimage-extract > /dev/null)
73
74 mkdir -p "${pkgdir}/opt/${pkgname}/appdir"
75 cp -a "${_extract_dir}/squashfs-root/." "${pkgdir}/opt/${pkgname}/appdir/"
76 chmod -R u+rwX,go+rX "${pkgdir}/opt/${pkgname}/appdir"
77
78 # The bundled node must not depend on libraries outside glibc/libstdc++.
79 # readelf instead of ldd: fakeroot preloads libfakeroot.so into ldd's output.
80 local _node="${pkgdir}/opt/${pkgname}/appdir/resources/open-design/bin/node"
81 if readelf -d "${_node}" | grep NEEDED | grep -Ev '(ld-linux-x86-64|lib(c|m|dl|pthread|stdc\+\+|gcc_s|atomic))\.so' | grep -q .; then
82 echo "Error: bundled node links against system libraries:" >&2
83 readelf -d "${_node}" | grep NEEDED >&2
84 return 1
85 fi
86
87 # Binaries
88 install -Dm755 "${srcdir}/open-design-desktop.sh" "${pkgdir}/usr/bin/open-design-desktop"
89 ln -sf "open-design-desktop" "${pkgdir}/usr/bin/open-design"
90
91 # Desktop entry & Icon
92 install -Dm644 "${srcdir}/open-design-desktop.desktop" "${pkgdir}/usr/share/applications/open-design-desktop.desktop"
93 install -Dm644 tools/pack/resources/linux/icon.png "${pkgdir}/usr/share/icons/hicolor/512x512/apps/open-design.png"
94
95 # License
96 install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
97}
98

Changes since previous scan

--- PKGBUILD @ 2026-10-16 00:12
+++ PKGBUILD @ 2026-10-20 00:10
@@ -1,9 +1,14 @@
# Maintainer: NickeyGod <niklass.schaeffer@gmail.com>
pkgname=open-design-desktop
-pkgver=0.24.0
-pkgrel=1
+pkgver=0.24.1
+pkgrel=2
_tag="open-design-v${pkgver}"
+# Upstream's pack step copies the node binary that runs the build into the
+# package. Arch's node links against system libraries (libsimdjson etc.), so
+# that copy breaks on their next soname bump. The official build is
+# self-contained, and upstream requires Node 24 anyway.
+_nodever=24.21.0
pkgdesc='Local-first design product: native desktop app & canvas for coding agents (the open-source Claude Design alternative)'
arch=('x86_64')
url='https://github.com/nexu-io/open-design'
@@ -19,8 +24,6 @@
)
makedepends=(
'git'
- 'nodejs'
- 'npm'
'python'
'make'
'gcc'
@@ -33,15 +36,19 @@
"${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/${_tag}.tar.gz"
"open-design-desktop.sh"
"open-design-desktop.desktop"
+ "https://nodejs.org/dist/v${_nodever}/node-v${_nodever}-linux-x64.tar.xz"
)
-sha256sums=('0e14e950116b9c6edd35e6c6217bb6847f8f521f3349ca98d306d09d1af9e3e7'
+sha256sums=('7b9491a9b4e291209853c90a1224d02ea0d13802d208d40bd1f70f3b8d939fae'
'5ae2dfc1943cd7ec376a5c42086cb76b618f14e10c7e92ecbf901f376b6eea6e'
- '7f86112fce365ab0bc6cc5f7cd415b4bace62c1c2d6252584100b7580290ddd6')
+ '7f86112fce365ab0bc6cc5f7cd415b4bace62c1c2d6252584100b7580290ddd6'
+ 'fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6')
_sourcedir="open-design-${_tag}"
build() {
cd "${srcdir}/${_sourcedir}"
+
+ export PATH="${srcdir}/node-v${_nodever}-linux-x64/bin:${PATH}"
_pnpm() { npx --yes pnpm@10.33.2 "$@"; }
@@ -68,6 +75,15 @@
cp -a "${_extract_dir}/squashfs-root/." "${pkgdir}/opt/${pkgname}/appdir/"
chmod -R u+rwX,go+rX "${pkgdir}/opt/${pkgname}/appdir"
+ # The bundled node must not depend on libraries outside glibc/libstdc++.
+ # readelf instead of ldd: fakeroot preloads libfakeroot.so into ldd's output.
+ local _node="${pkgdir}/opt/${pkgname}/appdir/resources/open-design/bin/node"
+ if readelf -d "${_node}" | grep NEEDED | grep -Ev '(ld-linux-x86-64|lib(c|m|dl|pthread|stdc\+\+|gcc_s|atomic))\.so' | grep -q .; then
+ echo "Error: bundled node links against system libraries:" >&2
+ readelf -d "${_node}" | grep NEEDED >&2
+ return 1
+ fi
+
# Binaries
install -Dm755 "${srcdir}/open-design-desktop.sh" "${pkgdir}/usr/bin/open-design-desktop"
ln -sf "open-design-desktop" "${pkgdir}/usr/bin/open-design"

Scan history

Scanned at (UTC)SeverityRules
2026-10-20 00:10:31 Low 2
2026-10-19 00:03:55 Low 2
2026-10-18 00:06:55 Low 2
2026-10-17 00:21:55 Low 2
2026-10-16 07:17:48 Low 2
2026-10-16 07:15:06 High 2
2026-10-16 00:12:47 Medium 2
2026-10-15 00:28:05 Medium 2
2026-10-14 00:06:47 Medium 2
2026-10-13 00:23:45 Medium 2
2026-10-12 00:18:51 Medium 2
2026-10-11 00:26:05 Medium 2
2026-10-10 00:11:52 Medium 2
2026-10-09 00:05:33 Medium 2
2026-10-08 00:28:03 Medium 2
2026-10-07 00:21:34 Medium 2
2026-10-06 00:19:11 Medium 2
2026-10-06 00:13:36 Medium 2
2026-10-05 23:40:58 High 1
2026-10-05 00:08:03 Medium 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion