| Advisory ID | github_osv/GHSA-w5ff-2mjc-4phc |
| Aliases |
CVE-2026-33319
|
| Summary | AVideo has an OS Command Injection via Unescaped URL in LinkedIn Video Upload Shell Command ## Summary The `uploadVideoToLinkedIn()` method in the SocialMediaPublisher plugin constructs a shell command by directly interpolating an upload URL received from LinkedIn's API response, without sanitization via `escapeshellarg()`. If an attacker can influence the LinkedIn API response (via MITM, compromised OAuth token, or API compromise), they can inject arbitrary OS commands that execute as the web server user. ## Details The vulnerability exists in `plugin/SocialMediaPublisher/Objects/SocialUploader.php`. The `initializeLinkedInUploadSession()` method (line 649) sends a POST request to `https://api.linkedin.com/rest/videos?action=initializeUpload` and parses the JSON response at line 693: ```php // SocialUploader.php:693 $responseArray = json_decode($response, true); ``` The parsed `uploadInstructions` array is iterated at line 532, and each `uploadUrl` is passed to `uploadVideoToLinkedIn()` at line 542: ```php // SocialUploader.php:542 $uploadResponse = self::uploadVideoToLinkedIn($instruction['uploadUrl'], $tmpFile); ``` The `uploadVideoToLinkedIn()` method (line 711) constructs a shell command by directly concatenating both `$uploadUrl` and `$filePath` into a string passed to `exec()`: ```php // SocialUploader.php:713-720 $shellCmd = 'curl -v -H "Content-Type:application/octet-stream" --upload-file "' . $filePath . '" "' . $uploadUrl . '" 2>&1'; _error_log("Upload Video Shell Command:\n" . $shellCmd); exec($shellCmd, $o); ``` Neither `$uploadUrl` nor `$filePath` is sanitized with `escapeshellarg()`. A malicious URL such as `https://uploads.linkedin.local" ; id ; echo "` would break out of the quoted string and execute arbitrary commands. The `$uploadUrl` originates from LinkedIn's API response — a trusted third-party source over HTTPS — so exploitation requires compromising that response (MITM at CA level, compromised OAuth token leading to attacker-controlled API responses, or LinkedIn API compromise). This makes the attack complexity high, but the missing sanitization is a defense-in-depth failure that could become critical if the trust boundary is ever violated. ## PoC This vulnerability requires manipulating the LinkedIn API response. A simulated proof-of-concept using a local proxy: **Step 1:** Set up a proxy that intercepts the LinkedIn API response and replaces the `uploadUrl` field: ```json { "value": { "uploadInstructions": [ { "uploadUrl": "https://example.com\" ; id > /tmp/pwned ; echo \"", "firstByte": 0, "lastByte": 1024 } ], "uploadToken": "token123", "video": "urn:li:video:123" } } ``` **Step 2:** The resulting shell command becomes: ```bash curl -v -H "Content-Type:application/octet-stream" --upload-file "/tmp/tmpfile" "https://uploads.linkedin.local" ; id > /tmp/pwned ; echo "" 2>&1 ``` **Step 3:** The `id` command executes as the web server user, writing output to `/tmp/pwned`. **Step 4:** Verify: ```bash cat /tmp/pwned # uid=33(www-data) gid=33(www-data) groups=33(www-data) ``` ## Impact - **Remote Code Execution:** If the LinkedIn API response is compromised, an attacker gains arbitrary command execution as the web server user (`www-data`). - **Confidentiality:** Full read access to application source code, configuration files (including database credentials), and any data accessible to the web server process. - **Integrity:** Ability to modify application files, inject backdoors, or alter database records. - **Practical risk is low** due to the high attack complexity — exploitation requires compromising a trusted HTTPS API response from LinkedIn. This is primarily a defense-in-depth issue. ## Recommended Fix Sanitize both `$uploadUrl` and `$filePath` with `escapeshellarg()` before interpolation into the shell command. Alternatively, replace the `exec()` call with PHP's native cURL functions (which are already used elsewhere in the same class): **Option 1 — Minimal fix with `escapeshellarg()`:** ```php // plugin/SocialMediaPublisher/Objects/SocialUploader.php:711-715 static function uploadVideoToLinkedIn($uploadUrl, $filePath) { $shellCmd = 'curl -v -H "Content-Type:application/octet-stream" --upload-file ' . escapeshellarg($filePath) . ' ' . escapeshellarg($uploadUrl) . ' 2>&1'; ``` **Option 2 — Replace shell exec with native PHP cURL (preferred):** ```php static function uploadVideoToLinkedIn($uploadUrl, $filePath) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $uploadUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/octet-stream']); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'r')); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); $response = curl_exec($ch); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $headers = substr($response, 0, $headerSize); curl_close($ch); // Extract ETag from response headers $matches = []; preg_match('/(etag:)(\s?)(.*)(\n)/i', $headers, $matches); $etag = isset($matches[3]) ? trim($matches[3]) : null; // ... rest of function } ``` Option 2 is strongly preferred as it eliminates the shell execution entirely, removing the injection surface and aligning with the PHP cURL usage already present in `initializeLinkedInUploadSession()` on line 664. |
| Status | Published |
| Exploitability | 0.5 |
| Weighted Severity | 5.3 |
| Risk | 2.6 |
| Affected and Fixed Packages | Package Details |
| Introduced and Fixed Package Commit Patches | Package Commit Patches Details |
| System | Score | Found at |
|---|---|---|
| cvssv3.1 | 5.9 | https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-w5ff-2mjc-4phc/GHSA-w5ff-2mjc-4phc.json |
| generic_textual | MODERATE |
| Reference id | Reference type | URL |
|---|---|---|
| https://github.com/WWBN/AVideo | ||
| 67d932eb05e1bc9b36796f73ff4f9fb47590598b | Other | https://github.com/WWBN/AVideo/commit/67d932eb05e1bc9b36796f73ff4f9fb47590598b |
| CVE-2026-33319 | https://nvd.nist.gov/vuln/detail/CVE-2026-33319 | |
| GHSA-w5ff-2mjc-4phc | Other | https://github.com/WWBN/AVideo/security/advisories/GHSA-w5ff-2mjc-4phc |
No EPSS data available for this advisory.
| Patch URL | |
|---|---|
| There are no known patches. | |
| Attack Vector (AV) | Attack Complexity (AC) | Privileges Required (PR) | User Interaction (UI) | Scope (S) | Confidentiality Impact (C) | Integrity Impact (I) | Availability Impact (A) |
|---|---|---|---|---|---|---|---|
network adjacent_network local physical |
low high |
none low high |
none required |
unchanged changed |
high low none |
high low none |
high low none |
Vector: SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-03-23T11:56:47Z/
Decision: Track*
Source URL: https://github.com/cisagov/vulnrichment/blob/develop/2026/33xxx/CVE-2026-33319.json
Source Advisory: vulnrichment/CVE-2026-33319
[{'Exploitation': 'poc'},
{'Automatable': 'no'},
{'Technical Impact': 'total'},
{'Mission Prevalence': 'minimal'},
{'Public Well-being Impact': 'material'},
{'Mission & Well-being': 'medium'}]