<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stephan W.</title>
    <description>The latest articles on DEV Community by Stephan W. (@stephanww).</description>
    <link>https://dev.to/stephanww</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4092954%2F4a37b8c3-95b7-4b60-90dd-7fcdbc2fa0d9.png</url>
      <title>DEV Community: Stephan W.</title>
      <link>https://dev.to/stephanww</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stephanww"/>
    <language>en</language>
    <item>
      <title>The React Native Developer's Security Guide</title>
      <dc:creator>Stephan W.</dc:creator>
      <pubDate>Tue, 25 Aug 2026 18:09:18 +0000</pubDate>
      <link>https://dev.to/stephanww/you-secured-the-app-whos-securing-you-the-react-native-developers-security-guide-m39</link>
      <guid>https://dev.to/stephanww/you-secured-the-app-whos-securing-you-the-react-native-developers-security-guide-m39</guid>
      <description>&lt;p&gt;&lt;em&gt;(Work in progress — same as the project it's about. More on that below)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Almost everything written about React Native security is about protecting your &lt;strong&gt;users&lt;/strong&gt;: the shipped app, the phone it runs on. Almost nothing is written about protecting &lt;strong&gt;you&lt;/strong&gt;, the React Native developer.&lt;/p&gt;

&lt;p&gt;A React Native project is at least five distinct programming runtimes stitched together. Most developers can name one. The primary target has already shifted: it's no longer your customer, but you and your CI. Your MacBook's security model was never built to protect developers from their own tech stack.&lt;/p&gt;

&lt;p&gt;You're the one holding the npm publish token, the GitHub PAT, the iOS distribution cert, the Android upload keystore, the App Store Connect key, and (increasingly) an AI agent with shell access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your MacBook is not a walled garden for your own repo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;yarn install&lt;/code&gt;&lt;/strong&gt; runs untrusted code with your full user privileges. No sandbox, before you've read a single line of it. It can read &lt;code&gt;~/.ssh&lt;/code&gt;, your keychain, every &lt;code&gt;.env&lt;/code&gt; file on disk — the single most exploited primitive in the JS supply chain, and it's on by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;metro.config.js&lt;/code&gt;, &lt;code&gt;babel.config.js&lt;/code&gt;, &lt;code&gt;app.config.js&lt;/code&gt;&lt;/strong&gt; aren't config: they're Node programs that execute on your machine every time you start the bundler. A malicious Babel plugin runs at build time &lt;em&gt;and&lt;/em&gt; controls your app's AST on the way into the bundle. Expo config plugins go further; they can silently edit &lt;code&gt;project.pbxproj&lt;/code&gt; and inject a persistent build script that never shows up in a diff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your Podfile&lt;/strong&gt; is a Ruby program with shell access, evaluated at &lt;code&gt;pod install&lt;/code&gt;. Its &lt;code&gt;script_phase&lt;/code&gt; hook doesn't just run once — it injects a build-phase script that fires on &lt;em&gt;every future build&lt;/em&gt;, including your CI, with your release credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Xcode scheme pre-actions&lt;/strong&gt; run before the build even starts, so they fire even when the build fails. They're also buried three menus deep somewhere almost no developer has ever opened. A default RN project has zero of these. Any hit is a five-alarm fire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;build.gradle&lt;/code&gt; executes on sync, not on build:&lt;/strong&gt; opening the project, switching branches, even a dry run triggers it, handing an attacker the entire JVM standard library instead of just a shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opening the folder in your editor can be the compromise.&lt;/strong&gt; &lt;code&gt;"runOn": "folderOpen"&lt;/code&gt; in &lt;code&gt;.vscode/tasks.json&lt;/code&gt; is zero-click, invisible code execution. Your AI agent's MCP servers are worse: over 30% of surveyed MCP servers carry an exploitable vulnerability, and "tool poisoning" has already been used to trick agents into reading a user's private SSH key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is hypothetical. nx/s1ngularity turned install hooks into an AI-agent-assisted credential hunt. Shai-Hulud self-propagated through compromised npm packages. GlassWorm hid its payload in invisible Unicode that renders as &lt;em&gt;nothing&lt;/em&gt; (in your editor, in the GitHub diff) and still compromised seven OpenVSX extensions with 35,800 downloads before anyone noticed. Your code review can't catch what your eyes can't render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this actually came from
&lt;/h2&gt;

&lt;p&gt;I didn't sit down one day and decide to write a book. I've been doing dev and devops on React Native projects for years, and somewhere in there I'd built up the unglamorous kind of knowledge nobody publishes: a warning to a teammate not to &lt;code&gt;pod install&lt;/code&gt; blind on an unfamiliar repo, a note-to-self that &lt;code&gt;build.gradle&lt;/code&gt; executes on &lt;em&gt;sync&lt;/em&gt;, a half-remembered incident writeup I could never find again when I actually needed it. It was real, hard-won, and scattered across Teams/Slack, sticky notes, half-organized MD files, and my own memory.&lt;/p&gt;

&lt;p&gt;So I sat down with Claude and turned the pile into something structured. &lt;/p&gt;

&lt;h2&gt;
  
  
  This is not finished, and I don't want it to be a solo project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/stephanww/rn-dev-security-guide" rel="noopener noreferrer"&gt;The React Native Developer's Security Guide&lt;/a&gt;&lt;/strong&gt; is 33 chapters on this threat model so far. Every attack in it is real, dated and sourced. Its companion, &lt;strong&gt;&lt;a href="https://github.com/stephanww/rn-dev-security-guide-opengrep" rel="noopener noreferrer"&gt;an opengrep rule set&lt;/a&gt;&lt;/strong&gt;, turns every "here's the command to catch this" into something you can point at a repo or wire into CI. &lt;strong&gt;A finding is a reason to look, not a verdict.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both are actively moving. Let's make this the place where scattered React Native developer-security knowledge gets consolidated.  If you've hit one of these attacks, know a technique that's missing, or can tighten a rule in the companion set, please Open an issue, create a PR.&lt;/p&gt;

&lt;p&gt;Your app was never the whole attack surface. Go find out where your React Native stack's weak points are, before somebody else does.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>devsec</category>
    </item>
  </channel>
</rss>
