Back to skill

Security audit

Jellyseerr

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with Jellyseerr media requests, but its notification setup installs persistent services and exposes an unauthenticated webhook listener that needs review before use.

Install only if you are comfortable running a persistent Jellyseerr integration on this host. Prefer binding the webhook to localhost or a trusted interface behind HTTPS/authentication, restrict firewall access to the Jellyseerr server, inspect any generated systemd unit before enabling it, avoid the /tmp crontab method, and leave auto_approve disabled unless you intentionally want automatic media approvals.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/webhook_server.py:64
Finding

Unauthenticated and Unbounded Network Webhook Receiver

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/setup_webhook.sh:7
Finding

Root-Owned systemd Unit Injection Through Unvalidated Setup Inputs

Content
View full analysis
/dev/null << EOF [Unit] Description=Jellyseerr Webhook Receiver After=network.target [Service] Type=simple User=$USER WorkingDirectory=$SCRIPT_DIR ExecStart=/usr/bin/python3 $SCRIPT_DIR/webhook_server.py $PORT Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF # Reload systemd and enable service sudo systemctl daemon-reload sudo systemctl enable ${SERVICE_NAME} sudo systemctl start ${SERVICE_NAME} ``` ### Technical Analysis The script writes a root-owned unit under `/etc/systemd/system` and immediately enables and starts it. The command-line `PORT` value, the environment-derived `USER` value, and the resolved script path are interpolated directly into the unit without validation or systemd escaping. Shell command substitution is not performed on text introduced by variable expansion inside the heredoc, so ordinary shell metacharacters in `PORT` do not directly execute commands during file creation. However, newline characters remain significant to the systemd unit parser. A newline-bearing port argument can inject additional service directives after the `ExecStart` line. The `User` directive is derived from the mutable `$USER` environment variable instead of a fixed, dedicated service account. A caller can therefore influence which account systemd uses. A crafted argument can also inject a later `User=root` directive. If the installed Skill directory is writable by the invoking user, a root service that executes `webhook_server.py` from that directory creates a privilege-escalation and persistent-execution path. Creating a system servi ...[truncated 1933 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:76
Finding

Predictable Temporary File Used to Replace the User Crontab

Content
View full analysis
/tmp/cron_backup.txt echo "* * * * * $(pwd)/scripts/auto_monitor.sh" >> /tmp/cron_backup.txt crontab /tmp/cron_backup.txt ``` ### Technical Analysis The documented polling setup uses the fixed, globally predictable path `/tmp/cron_backup.txt`. Files in `/tmp` are exposed to other local users and processes, and normal shell redirection follows symbolic links. On systems where protected-symlink controls do not prevent the operation, another local user can prepare the path as a symbolic link to a file writable by the victim. The first redirection then truncates and overwrites that target. There is also a time-of-check/time-of-use interval between writing the backup, appending the new entry, and importing the file with `crontab`. A local attacker able to replace or alter the temporary path during that interval can influence the crontab content that is installed. The instructions do not use `mktemp`, do not verify ownership or file type, do not set restrictive permissions, and do not remove the temporary file afterward. The fixed filename can also retain sensitive crontab contents in `/tmp`. The cron mechanism is explicitly documented and is functionally relevant to polling. It is not hidden persistence, but this implementation introduces unnecessary local-file and scheduled-command risks. ### Attack Path One possible exploitation sequence is: 1. A local attacker predicts that the victim will follow the documented polling setup. 2. The attacker creates `/tmp/cron_backup.txt` as a symlink to a file the victim can modify, on a system without effective protected-symlink enforcement. 3. The victim executes the first command, causing shell redirection to truncate and overwrite the symlink target with the victim's current crontab. 4. The subse ...[truncated 1072 chars]
Remediation
View remediation
/dev/null | grep -Fv -- "$SCRIPT_PATH" printf '%s\n' "* * * * * $SCRIPT_PATH" ) | crontab - ``` Additional hardening should include: - Resolve and safely quote the absolute script path. - Validate that the script is owned by the expected user and is not writable by untrusted users. - Prefer a user-level systemd timer with explicit installation and uninstall instructions. - If a temporary file is unavoidable, create it with `mktemp`, apply mode `600`, verify ownership and file type, and remove it through an `EXIT` trap. - Do not retain copies of the user's crontab under a globally shared temporary directory. - Document how to remove only the exact installed entry instead of broadly filtering unrelated cron jobs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (64)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documented capability extends beyond Jellyseerr request/search operations to running an HTTP receiver, processing inbound events, and preparing outbound notifications using additional configuration data. This broader integration increases data-flow and exposure risks and is insufficiently disclosed by the current description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented capability extends beyond Jellyseerr request/search operations to running an HTTP receiver, processing inbound events, and preparing outbound notifications using additional configuration data. This broader integration increases data-flow and exposure risks and is insufficiently disclosed by the current description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented capability extends beyond Jellyseerr request/search operations to running an HTTP receiver, processing inbound events, and preparing outbound notifications using additional configuration data. This broader integration increases data-flow and exposure risks and is insufficiently disclosed by the current description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented capability extends beyond Jellyseerr request/search operations to running an HTTP receiver, processing inbound events, and preparing outbound notifications using additional configuration data. This broader integration increases data-flow and exposure risks and is insufficiently disclosed by the current description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented capability extends beyond Jellyseerr request/search operations to running an HTTP receiver, processing inbound events, and preparing outbound notifications using additional configuration data. This broader integration increases data-flow and exposure risks and is insufficiently disclosed by the current description.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 165)May include surrounding context.

bash
sudo systemctl stop jellyseerr-webhook
sudo systemctl disable jellyseerr-webhook
sudo rm /etc/systemd/system/jellyseerr-webhook.service
sudo systemctl daemon-reload

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/setup_webhook.sh (reported line 13)May include surrounding context.

sh
#!/bin/bash
# Setup webhook server as a systemd service

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="jellyseerr-webhook"
PORT="${1:-8384}"

# Create systemd service file
sudo tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null << EOF
[Unit]
Description=Jellyseerr Webhook Receiver
After=network.target

[Service]
Type=simple
User=$USER
WorkingDirectory=$SCRIPT_DIR
ExecStart=/usr/bin/python3 $SCRIPT_DIR/webhook_server.py $PORT
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Reload systemd and enable service
sudo systemctl daemon-reload
sudo systemctl enable ${SERVICE_NAME}
sudo systemctl start ${SERVICE_NAME}

echo "✓ Webhook server installed and started on port $PORT"
echo ""
echo "Next steps:"
echo "1. Get your server's IP address: hostname -I"
echo "2. In Jellyseerr, go to Settings → Notifications �

Obfuscated Code

High
Category
Supply Chain
Confidence
50% confidence
Finding

Code contains obfuscation (base64, hex encoding with execution). This is often used to hide malicious functionality.

Content

Scanner excerpt · scripts/setup_webhook.sh (reported line 42)May include surrounding context.

sh
echo "4. Set Webhook URL to: http://YOUR_IP:$PORT/"
echo "5. In JSON Payload, paste the following (base64 encoded):"
echo ""
echo 'eyJub3RpZmljYXRpb25fdHlwZSI6Int7bm90aWZpY2F0aW9uX3R5cGV9fSIsInN1YmplY3QiOiJ7e3N1YmplY3R9fSIsIm1lc3NhZ2UiOiJ7e21lc3NhZ2V9fSIsIm1lZGlhX3R5cGUiOiJ7e21lZGlhX3R5cGV9fSIsIm1lZGlhX3RtZGJpZCI6Int7bWVkaWFfdG1kYmlkfX0ifQ=='
echo ""
echo "6. Enable notification type: Media Available"
echo "7. Test the webhook and Save Changes"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises executable scripts and host-modifying setup steps but declares no explicit tool scope or permission boundaries. In an agent ecosystem, this creates hidden capabilities: shell, network, environment access, and file writes may be invoked without the skill manifest clearly warning reviewers or policy engines.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The webhook setup tells the user to run an installation script with sudo without clearly describing the privileged changes being made. Running undocumented root-level installation increases the risk of unintended system modification and reduces informed consent.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
93% confidence
Finding

Instructing users to run a script with sudo introduces root-level execution, which is inherently high trust and can affect the entire host. Without transparent disclosure of script contents and effects, this creates an avoidable security risk.

Content

Scanner excerpt · SKILL.md (reported line 66)May include surrounding context.

Quick setup:

bash
scripts/install_service.sh  # Run with sudo

Then configure Jellyseerr to send webhooks to http://YOUR_IP:8384/

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The polling setup appends a cron job into the user's crontab, creating persistence, but the instructions do not clearly warn that this is a lasting system change. Users may believe they are running a one-time command when they are actually scheduling recurring execution every minute.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

The cron instructions establish recurring execution, creating session persistence beyond the immediate user action. Persistence is not inherently malicious, but when introduced without strong disclosure and lifecycle management it can lead to unnoticed background activity and long-term exposure.

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

For environments where webhooks aren't available, use cron-based polling:

bash
crontab -l > /tmp/cron_backup.txt
echo "* * * * * $(pwd)/scripts/auto_monitor.sh" >> /tmp/cron_backup.txt
crontab /tmp/cron_backup.txt

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The example configuration enables auto_approve, which can cause requests to be approved automatically without a human review step. In a media-request workflow this may allow unauthorized or unintended content acquisition if the account or agent is misused.

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

{ "server_url": "https://jellyseerr.yourdomain.com", "api_key": "your-api-key", "auto_approve": true }

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The guide instructs users to configure a webhook endpoint over plain HTTP using the server IP, which exposes webhook payloads to interception or modification by any attacker on the local network path. Even if the payload is not highly sensitive, unauthenticated and unencrypted transport can enable spoofed notifications, event tampering, and disclosure of media-request metadata.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 96)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 102)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 120)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 127)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 151)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 157)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 163)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 164)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 165)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/WEBHOOK_SETUP.md (reported line 166)May include surrounding context.

Check Service Status

bash
sudo systemctl status jellyseerr-webhook

View Live Logs

Static analysis

No suspicious patterns detected.