pollis
The package downloads a prebuilt .deb from a non-whitelisted, project-owned CDN (cdn.pollis.com); while the checksum is verified, the source is a binary blob that could be tampered with if the host is compromised, posing a supply-chain risk.
Triggered rules
source_untrusted_domain
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
-
PKGBUILD:20
source=("https://cdn.pollis.com/releases/v${pkgver}/pollis-v${pkgver}-linux.deb")
llm_review
An AI model (qwen/qwen3-235b-a22b-2507) reviewed this and agrees it is MEDIUM (confidence 95%): The package downloads a prebuilt .deb from a non-whitelisted, project-owned CDN (cdn.pollis.com); while the checksum is verified, the source is a binary blob that could be tampered with if the host is compromised, posing a supply-chain risk.
PKGBUILD
1 offending line(s) highlighted# Maintainer: Pollis <hello@pollis.com>
# Generated by scripts/publish-aur.sh — do not edit by hand; the release
# pipeline overwrites this file on every release.
pkgname=pollis
pkgver=1.18.0
pkgrel=1
pkgdesc="End-to-end encrypted messaging"
arch=('x86_64')
url="https://pollis.com"
license=('LicenseRef-proprietary')
depends=(
'webkit2gtk-4.1'
'gtk3'
'libayatana-appindicator'
'alsa-lib'
'libpulse'
'dbus'
)
source=("https://cdn.pollis.com/releases/v${pkgver}/pollis-v${pkgver}-linux.deb")
sha256sums=('8478cac4507b6f0a4275492ecec53d74c2e564cd9a4bd43ee0241624b76a958c')
package() {
# The Tauri .deb already lays the app out under /usr (binary at
# /usr/bin/pollis, capture helper at /usr/bin/pollis-capture-linux,
# .desktop + icons under /usr/share) — extract it verbatim. No
# /opt symlink: that is the Electron layout and would clobber the
# real /usr/bin/pollis with a dangling link.
bsdtar -xf data.tar.* -C "${pkgdir}/"
# Tauri's .desktop template emits a bare `Exec=pollis`, which the launcher
# resolves through $PATH — so any binary named `pollis` ahead of /usr/bin
# hijacks the menu entry. That is not hypothetical for Arch specifically:
# website/install.sh picks .deb only when dpkg exists and .rpm only when
# dnf/yum exists, so on Arch it always falls through to the AppImage branch,
# which writes a launcher at ~/.local/bin/pollis and tells the user to put
# that directory on their PATH. Anyone who ran install.sh before switching to
# this package keeps launching the stale AppImage while pacman upgrades the
# real binary underneath — and it fails silently, because the AppImage still
# starts. Pin Exec to the path this package actually owns.
local desktop pinned=0
for desktop in "${pkgdir}"/usr/share/applications/*.desktop; do
[ -e "$desktop" ] || continue
sed -i -E 's|^Exec=pollis([[:space:]].*)?$|Exec=/usr/bin/pollis\1|' "$desktop"
if grep -q '^Exec=/usr/bin/pollis' "$desktop"; then
pinned=1
fi
done
# Never ship a launcher that can still be hijacked: if the .deb's layout
# changed under us, fail the build here rather than reintroduce the bug.
if [ "$pinned" -ne 1 ]; then
echo "No .desktop with an 'Exec=pollis' line under /usr/share/applications — refusing to package a hijackable launcher." >&2
return 1
fi
}
Changes since previous scan
--- PKGBUILD @ 2026-10-31 19:58+++ PKGBUILD @ 2026-11-01 00:21@@ -3,7 +3,7 @@ # pipeline overwrites this file on every release. pkgname=pollis-pkgver=1.17.23+pkgver=1.18.0 pkgrel=1 pkgdesc="End-to-end encrypted messaging" arch=('x86_64')@@ -18,7 +18,7 @@ 'dbus' ) source=("https://cdn.pollis.com/releases/v${pkgver}/pollis-v${pkgver}-linux.deb")-sha256sums=('0939157d7711fdea5bbe8baa5365e4c929d360143173d128cfc7baad64f2138c')+sha256sums=('8478cac4507b6f0a4275492ecec53d74c2e564cd9a4bd43ee0241624b76a958c') package() { # The Tauri .deb already lays the app out under /usr (binary atScan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-11-01 00:21:48 | Medium | 2 |
| 2026-10-31 21:59:05 | Medium | 2 |
| 2026-10-31 19:58:49 | Medium | 2 |
| 2026-10-31 00:07:41 | Medium | 2 |
| 2026-10-30 19:57:05 | Medium | 2 |
| 2026-10-30 07:55:24 | Medium | 2 |
| 2026-10-30 00:29:30 | Medium | 2 |
| 2026-10-29 21:53:30 | Medium | 2 |
| 2026-10-29 17:53:05 | Medium | 2 |
| 2026-10-29 07:52:02 | Medium | 2 |
| 2026-10-29 05:51:59 | Medium | 2 |
| 2026-10-29 01:51:16 | Medium | 2 |
| 2026-10-29 00:13:55 | Medium | 2 |
| 2026-10-28 23:51:05 | Medium | 2 |
| 2026-10-28 21:50:44 | Medium | 2 |
| 2026-10-28 17:50:30 | Medium | 2 |
| 2026-10-28 00:06:54 | Medium | 2 |
| 2026-10-27 21:48:49 | Medium | 2 |
| 2026-10-27 00:23:28 | Medium | 2 |
| 2026-10-26 21:45:59 | Medium | 2 |