Back to skill

Security audit

Expo Mobile Dev

Security checks for vulnerabilities and agentic risk

Overview

This Expo scaffolding skill is not plainly malicious, but it installs many unpinned remote agent skills for future sessions and includes sensitive credential-generation steps that can expose secrets in logs.

Install only if you are comfortable with a workflow that can scaffold an Expo app, install packages, fetch current docs, and add many remote AI skills that influence future agent sessions. Review and pin each remote skill source before running Step 4, and run credential-generation steps in a local environment where terminal output, shell history, and CI logs are not retained or exposed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T08 · Insecure Dependencies

Error
Location
SKILL.md:221
Finding

Unpinned Remote Agent Skills and Package Runner Create a Mutable Supply-Chain Boundary

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:221-260
Additional Location: references/china-deployment.md:158-161
Vulnerability Type: Unpinned third-party Agent Skills and package execution
Risk Level: High

Vulnerable Code

bash
npx skills add https://github.com/expo/skills expo-tailwind-setup
npx skills add https://github.com/expo/skills expo-cicd-workflows
npx skills add https://github.com/expo/skills expo-deployment
npx skills add https://github.com/expo/skills expo-dev-client
npx skills add https://github.com/expo/skills expo-api-routes
npx skills add https://github.com/expo/skills building-native-ui
npx skills add https://github.com/expo/skills native-data-fetching
npx skills add https://github.com/expo/skills upgrading-expo
npx skills add https://github.com/expo/skills use-dom
npx skills add https://github.com/expo/skills expo-module
npx skills add https://github.com/expo/skills expo-ui-swiftui

npx skills add https://github.com/tanstack-skills/tanstack-skills --skill tanstack-query
npx skills add https://github.com/tanstack-skills/tanstack-skills --skill tanstack-form

npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-native-skills

npx skills add https://github.com/expo/skills eas-update-insights

npx skills add reactnativecn/react-native-update-skill --skill react-native-update

The China deployment reference repeats the mutable installation flow:

text
- **Library**: `react-native-update` — https://github.com/reactnativecn/react-native-update
- **Service**: Pushy — https://pushy.reactnative.cn/ (sign up, create an app, get an app key)
- **Skill**: `npx skills add reactnativecn/react-native-update-skill --skill react-native-update` — installs the Claude skill that knows the Pushy CLI, version semantics, and rollout commands.
- **Always check the official docs first** — Pushy's CLI flags, version-channel model, and config schema
...[truncated 2407 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the skills package runner to an exact reviewed version rather than invoking an unversioned package through npx.
  2. Pin every Git-based Skill dependency to an audited commit SHA. Do not rely on mutable default branches.
  3. Record expected hashes or signatures for downloaded Skill content and verify them before installation.
  4. Download and review each Skill locally before allowing it to affect an Agent session.
  5. Maintain an allowlist of approved repositories, maintainers, versions, and commit hashes.
  6. Require explicit user confirmation before installing any behavior-changing Agent Skill.
  7. Vendor security-critical Skill content into a controlled repository when reproducible installation is required.
  8. Re-audit dependencies before updating pinned revisions.
  9. Run Skill installation and review in a restricted environment without production credentials.

T09 · Insecure Skill Coding Practices

Warning
Location
assets/generate-apple-client-secret.ts:36
Finding

Apple OAuth Client Secret Is Printed to Standard Output and Secrets Are Passed Through Command Arguments

Content
View full analysis

Vulnerability Details

File Location: assets/generate-apple-client-secret.ts:36-45
Additional Locations: references/auth.md:105-120, references/eas-recipes.md:74-77
Vulnerability Type: Plaintext sensitive-data exposure through terminal output, logs, and command history
Risk Level: Medium

Vulnerable Code

ts
const clientSecret = await new SignJWT({})
  .setProtectedHeader({ alg, kid: keyId })
  .setIssuer(teamId)
  .setIssuedAt(now)
  .setExpirationTime(exp)
  .setAudience("https://appleid.apple.com")
  .setSubject(clientId)
  .sign(privateKey);

console.log(`APPLE_CLIENT_SECRET:\n${clientSecret}`);

The authentication guide explicitly expects the complete secret in terminal output:

bash
pnpm tsx scripts/generate-apple-client-secret.ts
text
APPLE_CLIENT_SECRET:
eyJhbGciOiJFUzI1NiIsImtpZCI6IlhZWjc4OTAxMjMifQ.eyJpc3MiOi...

The EAS recipe also recommends placing a secret directly in a command argument:

bash
eas secret:create --scope project --name SENTRY_AUTH_TOKEN --value <token>
eas secret:list

Technical Analysis

The Apple OAuth generator signs a client-secret JWT using the developer’s private Apple key and then prints the complete resulting credential to standard output. Although generation of this JWT is required for Apple OAuth, disclosing it through stdout is not required.

Standard output may be retained by terminal recorders, CI systems, remote development environments, shell transcripts, support bundles, or centralized log collectors. The generated token remains sensitive until expiration or revocation.

The documentation additionally recommends passing secrets through the --value command-line argument. Depending on the shell and operating system, this can place the secret in shell history and may temporarily expose it through process metadata. Sending the credential to the intended secret-management service is legit ...[truncated 1833 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not print generated secrets by default. Require an explicit option such as --show-secret and display a clear warning before emitting sensitive output.
  2. Prefer writing the generated JWT directly to a permission-restricted file created with mode 0600.
  3. Where supported, pipe the credential directly into a secret manager through standard input without printing or storing it in command history.
  4. Prefer interactive hidden input or stdin-based secret ingestion over a --value command-line argument.
  5. Disable shell history for unavoidable secret-entry commands, or document a shell-safe procedure that does not persist the credential.
  6. Enable secret masking in CI and ensure the value is registered for masking before any command can emit it.
  7. Avoid verbose or debug modes while handling credentials.
  8. Restrict access to CI logs, terminal recordings, and centralized logging systems, and configure short retention periods.
  9. Use the shortest practical credential lifetime and rotate any credential that may have appeared in logs or history.
  10. Add automated checks that reject accidental logging of variables whose names contain SECRET, TOKEN, PASSWORD, or private-key material.
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (33)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared skill purpose is app scaffolding, but the bundled references extend into sensitive auth setup by generating Apple OAuth client_secret JWTs from local key material and environment configuration. This mismatch can cause operators to underestimate the sensitivity of the skill and expose secrets or signing operations in a context they did not expect.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger description is extremely broad and says to default to this skill for generic mobile-related language, which can cause over-activation in loosely related contexts. In practice, that increases the chance an agent performs package installation, network access, or project scaffolding when the user only wanted advice or a narrow code change.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/auth.md (reported line 79)May include surrounding context.

gitignore
# Apple Sign-In private key — never commit
AuthKey_*.p8
.env

Generating the client_secret JWT

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill instructs the agent to run many networked commands, install packages, and fetch external docs, but it does not declare an explicit tool scope or allowed-tools policy. In a skill that can access environment data and execute shell/package-manager operations, missing scope increases the chance of unintended capability use and weakens reviewability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill directs the agent to fetch external docs and install many third-party remote skills, but it does not pair those actions with a prominent user-facing warning that content may change and that network pulls introduce supply-chain risk. Users may therefore authorize powerful bootstrap actions without understanding they are ingesting mutable external instructions and artifacts.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The skill tells the agent to execute npx skills add against a remote repository without pinning a version, tag, or commit. That creates a supply-chain risk where upstream changes could alter installed code or prompts between runs, leading to unexpected or malicious behavior.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This command pulls a remote skill via npx skills add with no pinned revision. Unpinned remote dependencies allow silent upstream changes and make the agent ingest mutable third-party content at execution time.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The skill installation command relies on mutable upstream content and does not constrain the exact version fetched. In this context, that means future sessions may load different guidance or code than what was reviewed.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

Installing a remote skill without a pinned version exposes the workflow to supply-chain compromise or accidental breaking changes. Because the skill is intended to be run automatically during project setup, the blast radius includes every new project created with it.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The command fetches and installs a third-party skill dynamically with no version pinning. That makes behavior non-reproducible and allows hostile or compromised upstream changes to be consumed by the agent.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This line references remote mutable content via npx skills add without an immutable revision. In an agent skill, loading unreviewed updated prompts/tools can meaningfully change downstream execution and recommendations.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

Unpinned remote skill installation creates a trust-on-first-use problem and weakens provenance guarantees. If the upstream repo is changed or hijacked, future executions may pull malicious or unsafe instructions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The skill uses npx skills add to ingest remote content without specifying a fixed version. That is dangerous because it introduces mutable third-party behavior into an otherwise deterministic scaffold process.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This line installs a remote skill from GitHub with no commit or release pin. The lack of pinning permits unnoticed drift, dependency confusion, or malicious content updates to affect users at install time.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The workflow pulls mutable remote skill content without constraining the exact artifact. In a security-sensitive agent context, that can change future model behavior and recommended commands without any local diff or review.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

npx skills add without pinning introduces an avoidable supply-chain and reproducibility risk. Because this skill encourages repeated use, a single upstream compromise could propagate broadly across projects and sessions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This remote TanStack skill installation is unpinned and therefore mutable. A changed upstream repository could alter the guidance loaded into later sessions or introduce malicious prompt content.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The command dynamically installs a named skill from a third-party repository without pinning the repo state. That creates the same supply-chain and integrity risks as unpinned code dependencies.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The Vercel skill is fetched through npx skills add with no immutable version reference. That leaves the workflow exposed to upstream compromise, drift, and non-reproducible behavior over time.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This npx skills add command for the Expo OTA skill does not pin the remote content. As a result, later runs may install materially different instructions or code than the reviewed version.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The China OTA skill installation references a remote third-party source without any version pinning. This is particularly risky because it influences native update workflows and could steer users toward unsafe commands or compromised tooling.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · references/app-config.md (reported line 35)May include surrounding context.

md
ios: {
      bundleIdentifier: isDev ? 'com.example.myapp.dev' : 'com.example.myapp',
      supportsTablet: true,
      infoPlist: {
        NSCameraUsageDescription: 'Take photos for your profile.',
        NSLocationWhenInUseUsageDescription: 'Show nearby content.',
      },

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · references/app-config.md (reported line 100)May include surrounding context.

Plugins

Most native config that used to require editing Info.plist / AndroidManifest.xml is now handled by config plugins:

ts
plugins: [

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · references/app-config.md (reported line 118)May include surrounding context.

Plugins

Most native config that used to require editing Info.plist / AndroidManifest.xml is now handled by config plugins:

ts
plugins: [

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · references/app-config.md (reported line 124)May include surrounding context.

Plugins

Most native config that used to require editing Info.plist / AndroidManifest.xml is now handled by config plugins:

ts
plugins: [

Static analysis

No suspicious patterns detected.