---
name: security
description: Review React Native code for secret handling, secure storage, transport security, PII in logs, deep-link validation, input validation, and privacy compliance. Use when handling auth, payments, personal data, or before a security review.
version: 1.2.0
platforms: [ ios, android ]
react-native-version: 0.76+
tags: [ react-native, security, privacy, compliance ]
title: security
canonical_url: https://skilld.dev/gh/neha/rn-developer-skills/security
last_updated: 2026-10-01T00:04:32.000Z
---

> **Skill from skilld.dev.** Follow the instructions below for this session. You do not need to install anything.
>
> If the user asked to install this Skill, run `npx skilld install neha/rn-developer-skills/security`. Install writes the Skill files into the project, so every session loads them.

# Security Skill

## Applicability

- **Platforms:** iOS and Android
- **React Native:** 0.76+ (New Architecture interop assumed unless a checklist item says otherwise)

## When to Use

- Handling authentication, tokens, or payments
- Storing or transmitting personal or sensitive data
- Adding or reviewing deep links
- Preparing for a security or privacy review

## Severity

- **Merge-blocking:** a secret or token in the client bundle, payment credentials stored on the device, or a link target this diff adds that is not an allowed route.
- **Should-fix:** pinning, retention copy, and SDK log review.

## Guidance

### Secrets & Storage

A secret does not belong in the client. Environment variables in React Native are compiled into the JavaScript bundle.

- [ ] No private keys, tokens, or shared secrets in source, native projects, or env values that ship in the bundle
- [ ] A public host or a publishable key may come from an env var
- [ ] Sensitive data stored in the Keychain (iOS) / Keystore (Android), not plain storage
- [ ] Payment credentials never stored locally (PCI)

**Incorrect:**
```tsx
const apiSecret = process.env.API_SECRET;
```

**Correct:**
```tsx
const apiHost = process.env.API_HOST;
```

### Transport

- [ ] Pin transport for payments or auth only when the threat model requires it, and document how the pin rotates. Do not pin local debug builds
- [ ] Client-side validation is never trusted alone — the server validates too

### Logging & PII

- [ ] No PII (names, emails, payment info) logged to console or crash reports
- [ ] Third-party SDK log output audited (SDKs may log sensitive data internally)

**Incorrect:**
```tsx
console.log('Payment response:', JSON.stringify(paymentResult));
// Logs a card token to console; ends up in crash reports
```

**Correct:**
```tsx
logger.info('Payment completed', {
  transactionId: paymentResult.id,
  status: paymentResult.status,
});
// Only non-sensitive identifiers
```

### Deep Links & Input

Missing route params that crash are owned by [architecture](../architecture/SKILL.md). This skill checks the target.

- [ ] The link target is one of the routes the app allows (prevent open redirect)
- [ ] Input validated on the client (in addition to, not instead of, the server)

### Auth Lifecycle

Startup order and the navigation reset on sign-out are owned by [architecture](../architecture/SKILL.md).

- [ ] Token refresh handled silently on 401, without losing form state
- [ ] Sign-out deletes the session token from secure storage

### Privacy & Compliance

Permission prompt timing is owned by [native-integration](../native-integration/SKILL.md).

- [ ] No analytics or device-data collection before user consent (ATT on iOS, GDPR)
- [ ] The product has a path for export and deletion; this screen does not have to invent one unless the diff is that path
- [ ] User data not retained beyond the retention policy

## Pitfalls

- Crash and analytics tools often capture `console.log` by default — disable or filter them so PII does not leak.
- Third-party SDKs may log sensitive payloads internally; verify their output, not just your own.
- Client validation is a UX nicety, not a security control — the server is the source of truth.
- An unvalidated deep link can redirect users into unintended or authenticated content; validate params first.
