upwork
maintainer jasongodev
· 68 votes
· scanned 2026-08-03 00:08:14.047287
LOW
View on AUR ↗
Why flagged
The package downloads a prebuilt .deb from Upwork's official domain, which is a normal source for this software;虽 host not whitelisted, it is plausibly official and the downloaded binary is repackaged without executing remote code or adding malicious payloads.
Triggered rules
LOW
AI review downgraded a static finding
llm_review
The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-07-25) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The package downloads a prebuilt .deb from Upwork's official domain, which is a normal source for this software;虽 host not whitelisted, it is plausibly official and the downloaded binary is repackaged without executing remote code or adding malicious payloads.
1 higher static finding superseded - not the current verdict (shown for transparency)
MEDIUM
source=() URL on a non-standard host
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:30
"https://upwork-usw2-desktopapp.upwork.com/binaries/v${pkgver//./_}_$_hashver/upwork_${pkgver}_amd64.deb" -
PKGBUILD:31
'upwork-team-software-license-agreement-1-1.pdf::https://upwork.pactsafe.io/versions/6887e5128f84f23a737bf6bb.pdf'
PKGBUILD
2 offending line(s) highlighted
1
# Maintainer: Jason Go <jasongo@jasongo.net>
2
# Contributor: Yurii Kolesnykov <root@yurikoles.com>
3
4
pkgname=upwork
5
pkgver=5.8.0.41
6
pkgrel=5
7
_hashver='f0de03505cc349f2'
8
pkgdesc='Track your time for Hourly Payment Protection. Stay connected.'
9
arch=('x86_64')
10
url='https://www.upwork.com/ab/downloads/?os=linux'
11
license=('LicenseRef-Upwork-EULA')
12
_electron='electron36'
13
depends=(
14
"$_electron"
15
'libxcrypt-compat' # electron-builder needs libcrypt.so.1
16
'libxss' # Upwork's uta_native.node needs libXss.so.1
17
)
18
makedepends=('asar' 'curl')
19
optdepends=(
20
'firefox: Upwork needs a web browser to login'
21
'epiphany: Upwork needs a web browser to login'
22
'konqueror: Upwork needs a web browser to login'
23
'upwork-wayland: Allows screenshot to work in Wayland'
24
'libappindicator: For system notifications'
25
'gnome-shell-extension-appindicator: To show tray icon in GNOME'
26
)
27
conflicts=('upwork-beta')
28
options=(!debug !strip)
29
source=(
30
"https://upwork-usw2-desktopapp.upwork.com/binaries/v${pkgver//./_}_$_hashver/upwork_${pkgver}_amd64.deb"
31
'upwork-team-software-license-agreement-1-1.pdf::https://upwork.pactsafe.io/versions/6887e5128f84f23a737bf6bb.pdf'
32
'upwork.sh.in')
33
# See https://upwork-usw2-desktopapp.upwork.com/binaries/v5_8_0_41_f0de03505cc349f2/upwork_5.8.0.41_amd64.deb.sha256
34
sha256sums=('b2ed1ff34cfcc09cfa9ff472e39443aa999dd773867a57aef6f50798fb257239'
35
'1d2db24cd1364f79d11b8683c15274f4e5c7ed9a3e46a5938b55c6e9ca56937f'
36
'2c0d3d540933d4d5af57ab3021a2f37a2e855b43c1255dffccb333fd172ac5dd')
37
38
# These are the headers that Upwork 5.8.0.33 Electron use to download the update file without restriction.
39
# Notice that we are using the headers from an older Upwork version.
40
# This is because Upwork's update codes download the .deb file only when it is outdated.
41
# From the eyes of the WAF it will be weird that the latest user-agent is downloading an update.
42
# Hence, we use the older user-agent to simulate Upwork's update routine.
43
_headers=(
44
'sec-fetch-site: none'
45
'sec-fetch-mode: no-cors'
46
'sec-fetch-dest: empty'
47
'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Upwork/5.8.0 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36'
48
'accept-encoding: gzip, deflate, br'
49
'accept-language: en-US'
50
)
51
# DLAGENTS seem to have problem accepting arguments with spaces and so escape all of them
52
DLAGENTS=("https::/usr/bin/curl $(printf -- "-H %s " "${_headers[@]// /\\ }") -qfL -b '' -C - --retry 3 --retry-delay 3 -o %o %u")
53
54
prepare() {
55
bsdtar -xf data.tar.xz -C ./
56
57
# Change Electron executable
58
sed -i "s|@ELECTRON@|$_electron|" upwork.sh.in
59
60
# Change the upwork wrapper path to /usr/bin/upwork
61
sed -i 's|Exec=/opt/Upwork/upwork|Exec=/usr/bin/upwork|' ./usr/share/applications/upwork.desktop
62
sed -i 's|/opt/Upwork/upwork|/usr/bin/upwork|' ./opt/Upwork/resources/apparmor-profile
63
64
# Extract app.asar so we can modify main.js
65
cd ./opt/Upwork/resources
66
asar e app.asar ./out
67
cd ./out/out/main
68
69
# Not needed
70
rm main.compiled.jsc
71
72
# In AUR/upwork the addons are in /usr/lib/upwork instead of /opt/Upwork
73
sed -i 's|(process.execPath),"uta_native.node"|("/usr/lib/upwork/uta_native.node"),"uta_native.node"|' main.js
74
sed -i -E 's|join\([^,]+,"cmon"\)|join("/usr/lib/upwork/","cmon")|' main.js
75
76
# Disable updates
77
sed -i 's|UpdateBinaryInitiate(|UpdateBinaryInitiate(a,b,c){}xxx(|' main.js
78
79
# Pack app.asar again
80
cd "$srcdir/opt/Upwork/resources"
81
asar p ./out app.asar
82
}
83
84
package() {
85
# 1. COPY THE BINARIES
86
install -Dm755 upwork.sh.in "$pkgdir/usr/bin/upwork"
87
install -Dm755 -t "$pkgdir/usr/lib/upwork/" ./opt/Upwork/{cmon,uta_native.node}
88
install -Dm644 -t "$pkgdir/usr/lib/upwork/" ./opt/Upwork/resources/app.asar
89
90
# 2. COPY THE REST OF THE /usr/share/* from deb file
91
mkdir -p "$pkgdir/usr/share"
92
cp -dr --no-preserve=ownership ./usr/share/* "$pkgdir/usr/share"
93
install -Dm644 -t "$pkgdir/usr/share/licenses/upwork/" upwork-team-software-license-agreement-1-1.pdf
94
95
# 3. COPY APPARMOR PROFILE
96
install -Dm644 ./opt/Upwork/resources/apparmor-profile "$pkgdir/etc/apparmor.d/upwork"
97
}
98
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | LOW | 2 |
| 2026-08-02 00:16:08 | LOW | 2 |
| 2026-08-01 00:11:18 | LOW | 2 |
| 2026-07-31 00:14:10 | LOW | 2 |
| 2026-07-30 00:17:23 | LOW | 2 |
| 2026-07-29 00:25:53 | LOW | 2 |
| 2026-07-28 00:07:28 | LOW | 2 |
| 2026-07-27 00:24:32 | LOW | 2 |
| 2026-07-26 00:07:32 | LOW | 2 |
| 2026-07-25 00:13:44 | LOW | 2 |
| 2026-07-24 00:02:28 | LOW | 2 |
| 2026-07-23 00:14:47 | LOW | 2 |
| 2026-07-22 00:29:32 | LOW | 2 |
| 2026-07-21 00:24:15 | LOW | 2 |
| 2026-07-20 00:19:49 | LOW | 2 |
| 2026-07-19 00:17:08 | LOW | 2 |
| 2026-07-18 00:14:48 | LOW | 2 |
| 2026-07-17 00:06:16 | LOW | 2 |
| 2026-07-16 00:05:41 | LOW | 2 |
| 2026-07-15 00:09:25 | LOW | 2 |