Back to skill

Security audit

Skylight

Security checks for vulnerabilities and agentic risk

Overview

This Skylight integration is mostly coherent, but it handles account credentials and broad tokens in ways that need careful review before installation.

Install only if you are comfortable giving the skill access to your Skylight household account. Keep `SKYLIGHT_URL` pinned to the official Skylight host, avoid proxy-capturing live tokens unless you fully understand the risk, use a dedicated least-privilege account if possible, and treat exported bearer tokens like passwords.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get-access-token.sh:5
Finding

Unrestricted API base URL can redirect credentials and authorization data to an attacker-controlled server

Content
View full analysis
/dev/null ``` ```bash headers="$(curl -fsS -i \ "$BASE_URL/auth/session" \ -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ "${COMMON_HEADERS[@]}" \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Origin: https://app.ourskylight.com' \ -H 'Referer: https://app.ourskylight.com/auth/session/new' \ --data-urlencode "authenticity_token=$authenticity_token" \ --data-urlencode "email=$SKYLIGHT_EMAIL_VALUE" \ --data-urlencode "password=$SKYLIGHT_PASSWORD_VALUE")" ``` The authorization code is also submitted to an endpoint derived from the same configurable base URL: ```bash at_response="$(curl -fsS "$BASE_URL/oauth/token" \ -H 'content-type: application/x-www-form-urlencoded' \ -H 'origin: https://ourskylight.com' \ -H 'referer: https://ourskylight.com/' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id=skylight-mobile' \ --data-urlencode 'scope=everything' \ --data-urlencode "skylight_api_client_device_fingerprint=$DEVICE_FINGERPRINT" \ --data-urlencode 'skylight_api_client_device_platform=web' \ --data-urlencode 'skylight_api_client_device_name=unknown' \ --data-urlencode 'skylight_api_client_device_os_version=10.15.7' \ --data-urlencode 'skylight_api_clie ...[truncated 2857 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get-access-token.sh:7
Finding

Static OAuth state and missing state validation weaken authorization-response binding

Content
View full analysis
/dev/null ``` The redirect parser extracts only the authorization code and does not compare the returned state with the state sent in the authorization request: ```bash code="$(python3 -c ' import sys, urllib.parse url = sys.argv[1] qs = urllib.parse.parse_qs(urllib.parse.urlparse(url).query) print(qs.get("code", [""])[0]) ' "$second_location")" if [[ -z "$code" ]]; then echo "No OAuth code found in redirect" >&2 exit 1 fi ``` ### Technical Analysis OAuth `state` is intended to be an unpredictable, single-use value that binds an authorization response to the client request that initiated it. This implementation defaults to the constant value `Ko5P20HH4D` and never checks the state returned in the redirect. Because only the `code` parameter is extracted, the helper cannot determine whether the response corresponds to the current invocation. The externally configurable state also makes the binding dependent on potentially untrusted environment configuration. This weakens protection against authorization-response substitution and account-confusion attacks. Exploitation generally requires influence over redirects, endpoint configuration, an intermediary, or another part of the OAuth exchange; therefore, the issue is assessed as m ...[truncated 1370 chars]
Remediation
View remediation
&2 exit 1 fi ``` 5. Treat each state value as single-use and never persist or reuse it across invocations. 6. Validate the redirect URI's scheme, hostname, and expected path before parsing its query parameters. 7. Add negative tests covering missing state, mismatched state, duplicated query parameters, malformed redirects, and substituted authorization codes. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description focuses on calendar and household management, but the skill also performs credential-based authentication, retrieves OAuth tokens, and accesses 1Password-backed secrets. This mismatch can mislead users and calling systems about the true privilege level of the skill, causing them to authorize or invoke it without understanding that it can mint broad API access tokens.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The skill accesses credentials and can obtain a reusable OAuth bearer token, including via 1Password references and a service account token present in the environment. Even though the document advises not to print or persist secrets, the design still centralizes sensitive credential handling inside the skill, raising the risk of token exposure, misuse, or overbroad account access if the skill is invoked improperly or logs are captured.

Content

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

Authentication

Use the bundled OAuth helper to get an access token. With 1Password, store only references in env/config. If using a 1Password service-account/access token, make OP_SERVICE_ACCOUNT_TOKEN available to the Gateway process:

bash
export OP_SERVICE_ACCOUNT_TOKEN='ops_...'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
export SKYLIGHT_TOKEN="$(./scripts/get-access-token.sh)"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
export SKYLIGHT_TOKEN="$(./scripts/get-access-token.sh)"

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

The script performs network requests to a configurable BASE_URL before and during authentication, and that value can be overridden via the SKYLIGHT_URL environment variable. If an attacker can influence that variable, the script could send session cookies, login form data, and credentials to an attacker-controlled endpoint, making this materially more dangerous in a credential-handling skill.

Content

Scanner excerpt · scripts/get-access-token.sh (reported line 59)May include surrounding context.

sh
# Skylight's web/mobile OAuth flow currently accepts this random challenge value.
code_challenge="$(openssl rand -hex 20)"

curl -fsS -c "$COOKIE_JAR" \
  "${COMMON_HEADERS[@]}" \
  -H 'referer: https://ourskylight.com/' \
  "$BASE_URL/oauth/authorize?code_challenge=$code_challenge&prompt=login&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fourskylight.com%2Fwelcome&client_id=skylight-mobile&response_type=code&state=$STATE&scope=everything" \

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

The token exchange is sent to the same configurable BASE_URL, meaning an attacker-controlled override could capture the OAuth authorization code and return a fake token response. Because this skill is specifically meant to manage a family calendar/display account, compromise of the OAuth flow could expose account-wide access and persistent API credentials.

Content

Scanner excerpt · scripts/get-access-token.sh (reported line 141)May include surrounding context.

sh
exit 1
fi

at_response="$(curl -fsS "$BASE_URL/oauth/token" \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://ourskylight.com' \
  -H 'referer: https://ourskylight.com/' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly instructs users to capture authentication tokens using an HTTPS proxy, which encourages interception of live session credentials and may expose usernames, passwords, tokens, cookies, and other sensitive account data. In the context of a family calendar and household management skill using an unofficial reverse-engineered API, this is especially risky because the captured token could grant access to private household schedules, chores, and related personal data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill requires shell and network-capable binaries but does not declare any explicit tool scope or permissions boundary. That makes the effective capability broader than what a user or orchestrator can easily reason about, increasing the chance of unintended command execution or outbound requests during normal use.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
emoji: 📅
    requires:
      bins:
        - curl
        - openssl
        - python3
      env:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill includes multiple write operations such as creating chores and task box items, but it does not clearly warn that these actions modify real user data. In an agent setting, silent write capabilities can lead to unintended state changes, especially if a user believes the skill is only for viewing or querying information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script reads sensitive secrets for SKYLIGHT_EMAIL and SKYLIGHT_PASSWORD either directly from environment variables or via 1Password references. The file does not include any warning, prompt, or descriptive comment informing users that it will access credential material from their environment or secret manager.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This shell script posts the resolved email and password to the remote authentication endpoint, which is a safety-relevant network operation involving sensitive data. While there is error handling, the file provides no confirmation prompt, user-facing notice, or comment warning that credentials will be transmitted over the network.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.