T09 · Insecure Skill Coding Practices
- Location
scripts/cc-webhook.py:26- Finding
Unauthenticated Webhook Permits Unauthorized Content Modification and Approval
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This LinkedIn automation skill is mostly coherent, but it can affect a real public account and has under-scoped automation, persistence, and webhook security risks that need review before use.
Review this carefully before installing. Use a dedicated LinkedIn browser profile, avoid exposing or installing the webhook as a system service until authentication and least-privilege service configuration are added, remove --no-sandbox, require explicit confirmation for public or destructive actions, and add LinkedIn-only URL validation and local file permission controls.
scripts/cc-webhook.py:26Unauthenticated Webhook Permits Unauthorized Content Modification and Approval
references/content-calendar.md:75Privileged Persistent Service Installation Exceeds Minimum Required Privileges
scripts/lib/actions.py:135Arbitrary URLs Are Opened in a Persistent Authenticated Browser Context
scripts/lib/browser.py:23Chromium Sandbox Is Explicitly Disabled While Processing Remote Content
scripts/lib/style_learner.py:9Personal LinkedIn Writing Samples Are Persisted Without Explicit Owner-Only Permissions
scripts/requirements.txt:1Playwright Dependency Uses an Unbounded Version Range
The skill adds behavior for learning and persisting a user's writing profile from their posts and comments, but this data collection and local storage is not clearly surfaced in the top-level declared purpose. Hidden or under-disclosed profiling increases privacy risk because users may not realize the skill is creating a persistent behavioral profile that could expose language patterns, topics, or other sensitive personal traits.
The skill adds behavior for learning and persisting a user's writing profile from their posts and comments, but this data collection and local storage is not clearly surfaced in the top-level declared purpose. Hidden or under-disclosed profiling increases privacy risk because users may not realize the skill is creating a persistent behavioral profile that could expose language patterns, topics, or other sensitive personal traits.
The skill adds behavior for learning and persisting a user's writing profile from their posts and comments, but this data collection and local storage is not clearly surfaced in the top-level declared purpose. Hidden or under-disclosed profiling increases privacy risk because users may not realize the skill is creating a persistent behavioral profile that could expose language patterns, topics, or other sensitive personal traits.
The skill adds behavior for learning and persisting a user's writing profile from their posts and comments, but this data collection and local storage is not clearly surfaced in the top-level declared purpose. Hidden or under-disclosed profiling increases privacy risk because users may not realize the skill is creating a persistent behavioral profile that could expose language patterns, topics, or other sensitive personal traits.
The skill adds behavior for learning and persisting a user's writing profile from their posts and comments, but this data collection and local storage is not clearly surfaced in the top-level declared purpose. Hidden or under-disclosed profiling increases privacy risk because users may not realize the skill is creating a persistent behavioral profile that could expose language patterns, topics, or other sensitive personal traits.
The manifest description says to use the skill for 'any LinkedIn task,' which is an overly broad trigger for a high-risk automation capability. Broad invocation language can cause the agent to route unrelated or sensitive requests into a skill that can post, edit, delete, scrape, and auto-publish, increasing the chance of inappropriate automation or abuse.
The documentation explicitly says not to scrape other users' data, yet it advertises an activity command for scraping someone else's profile activity. This contradiction is dangerous because it normalizes prohibited behavior while giving users a misleading sense that the skill is policy-compliant, increasing the chance of privacy violations, account restrictions, and intentional misuse.
The function performs irreversible comment deletion based only on a text fragment match and immediately confirms the delete flow, with no user confirmation, preview, or strong verification that the targeted comment is the intended one. In a LinkedIn automation context, this increases the chance of accidental or automated deletion of the wrong content, causing reputational damage, loss of records, and abuse if invoked by an untrusted workflow or prompt chain.
find_menu_option searches broad element types by text and clicks the first textual match, including potentially destructive options such as delete. In this skill context, that can trigger irreversible account actions like deleting comments or operating on the wrong target when DOM structure, language, or surrounding menu content differs from expectations.
The skill documents behaviors that imply access to environment variables and local file writes, but it does not declare any explicit tool scope or allowed-tools boundary. In an automation skill that uses persistent browser profiles, local state files, debug screenshots, and webhook configuration, missing scope declarations weakens least-privilege controls and can enable broader-than-expected access to sensitive local data.
The skill is framed as personal-account productivity automation, but it also exposes a command to scrape another person's activity. That expands the skill from self-management into third-party data collection, raising privacy, platform-policy, and abuse risk, especially when combined with browser automation and persistent sessions.
The content calendar section describes webhook-driven approval handling and automatic posting via cron, but it does not place a prominent warning at that location about autonomous public actions. In a skill that can publish on a real LinkedIn account, understated warnings around auto-posting increase the risk of accidental or premature posting, especially if webhook inputs or schedule state are wrong.
This markdown file describes automatically publishing LinkedIn posts once scheduled time has passed and installing a webhook as a systemd service, both of which can affect external accounts and system state. The document explains how the workflow works, but it does not include an explicit warning about unintended posting, account impact, or changes to the host system.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Install as systemd service
sudo cp cc-webhook.service /etc/systemd/system/
sudo systemctl enable --now cc-webhook
# Nginx proxy (optional)
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Install as systemd service
sudo cp cc-webhook.service /etc/systemd/system/
sudo systemctl enable --now cc-webhook
# Nginx proxy (optional)
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# Install as systemd service
sudo cp cc-webhook.service /etc/systemd/system/
sudo systemctl enable --now cc-webhook
# Nginx proxy (optional)
location /api/actions {
This markdown file documents DOM targets for comment menus, delete/edit menu items, and confirmation dialogs, including "Löschen/Delete/Ja" buttons. Because markdown files should warn about behaviors that could affect user data or system integrity, the absence of any warning about destructive actions creates a missing-user-warning issue.
The webhook accepts unauthenticated POST and PUT requests and directly appends to action logs and modifies cc-data.json, including post text and status, with permissive CORS enabled. In the context of a LinkedIn automation/content approval workflow, this allows unauthorized parties or malicious web pages to alter publishing decisions, inject or rewrite content, and trigger downstream automation without any approval enforcement.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
'timestamp': data.get('timestamp', datetime.now().isoformat())
})
try:
with open(WAKE_FILE, 'w') as wf:
json.dump({
'type': 'edit', 'postId': post_id,
'note': note, 'timestamp': datetime.now().isoformat()
The helper saves screenshots of the live LinkedIn page to /tmp on failures, which can capture sensitive page contents such as account data, private messages, comments, feeds, or draft content without any explicit disclosure or retention controls. In a browser automation skill using a persistent logged-in profile, these artifacts can expose user data to other local users, processes, or later forensic collection if the files are not promptly removed.
This code navigates a logged-in LinkedIn session, extracts post text and engagement metrics, and returns the collected data, but the implementation provides no confirmation prompt, print/log notice, or warning comment/docstring that clearly discloses the scope of data collection. Because it accesses and processes account-specific activity data from an authenticated session, a user-visible warning would improve transparency.
The function opens the LinkedIn dashboard and extracts profile views, impressions, search appearances, and follower counts, which are account-specific analytics data. While the docstring states the function purpose, there is no visible confirmation prompt or user-facing notice in the code indicating that authenticated profile statistics will be read from the account session.
The file sets LOCALE = "de-DE", which forces a specific language/locale for all browser sessions. Under the policy, locale restrictions should either be user-selectable or clearly justified as region-specific; neither is present here.
This function programmatically reads a user's LinkedIn feed and returns post author names, post text, and URLs without any built-in notice, consent check, or data-minimization guardrail. Because feed contents can include personal data, sensitive business information, or private contextual signals, silent collection and downstream exposure increase privacy and compliance risk, especially in an automation skill designed for broad LinkedIn tasks.
This code persistently stores LinkedIn activity-derived data (seen_likes and timestamps) to a local file with no disclosure, consent, retention control, or access protection. In the context of a LinkedIn automation skill that tracks engagement, this creates privacy and compliance risk because user behavioral data is silently retained and may be readable by other local users or processes.
No suspicious patterns detected.