Skip to main content
interlace
Plugin: browser-securityRules

no-allow-arbitrary-loads

Prevents disabling App Transport Security (ATS) by detecting NSAllowsArbitraryLoads: true in an Expo/React Native config.

Prevents disabling App Transport Security (ATS) by detecting NSAllowsArbitraryLoads: true in an Expo / React Native JavaScript config.

⚠️ This rule errors by default in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-295 (Improper Certificate Validation)
OWASP MobileM5: Insecure Communication
SeverityHigh
CategorySecurity

Rule Details

App Transport Security (ATS) enforces secure connections for iOS/macOS applications. Setting NSAllowsArbitraryLoads: true disables this protection entirely, allowing insecure HTTP connections and weakening certificate validation.

The rule matches Apple's own key names, by exact membership:

NSAllowsArbitraryLoads, NSAllowsArbitraryLoadsInWebContent, NSAllowsArbitraryLoadsForMedia, NSAllowsLocalNetworking, NSExceptionAllowsInsecureHTTPLoads, NSThirdPartyExceptionAllowsInsecureHTTPLoads.

It previously matched allowArbitraryLoads — lowercase, unprefixed — which is a key in no Expo, React Native, Capacitor or Cordova schema. That made the rule vacuous in both directions: it could not fire on any real ATS opt-out, and anything it did fire on was somebody's own unrelated config key.

The JavaScript surface these keys really appear on is an Expo app.config.js / app.config.ts. Info.plist itself is XML and ESLint never sees it — see Known False Negatives.

Examples

❌ Incorrect

// app.config.js — disabling ATS entirely, DANGEROUS
export default {
  ios: {
    infoPlist: {
      NSAppTransportSecurity: {
        NSAllowsArbitraryLoads: true, // Allows all insecure connections
      },
    },
  },
};

// The narrower opt-outs are opt-outs too
const plist = {
  NSAppTransportSecurity: {
    NSAllowsArbitraryLoadsInWebContent: true,
    NSAllowsLocalNetworking: true,
  },
};

// A per-domain exception that re-permits cleartext
const ats = {
  NSExceptionDomains: {
    'legacy.example.com': { NSExceptionAllowsInsecureHTTPLoads: true },
  },
};

✅ Correct

// Keep ATS enabled (default)
const config = {
  NSAppTransportSecurity: {
    NSAllowsArbitraryLoads: false, // Or omit entirely
  },
};

// Allow exceptions only for specific domains
const config = {
  NSAppTransportSecurity: {
    NSExceptionDomains: {
      'legacy-api.example.com': {
        NSTemporaryExceptionAllowsInsecureHTTPLoads: true,
      },
    },
  },
};

Error Message Format

When triggered, this rule produces:

🔒 CWE-295 | App Transport Security is disabled: "NSAllowsArbitraryLoads: true" lets the app load cleartext HTTP, so any network attacker can read and rewrite its traffic. | HIGH
   Fix: Remove the opt-out and serve over HTTPS, or scope it to one host with NSExceptionDomains. | https://cwe.mitre.org/data/definitions/295.html

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Dynamic Configuration

Why: Configuration values set dynamically at runtime cannot be traced.

// ❌ NOT DETECTED - Dynamic value
const enableInsecure = process.env.ALLOW_INSECURE === 'true';
const config = { NSAllowsArbitraryLoads: enableInsecure };

Mitigation: Never use environment variables to control security settings.

Configuration in External Files

Why: Rule only checks JavaScript/TypeScript, not Info.plist XML.


<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Mitigation: Use plist linting tools for native iOS configuration.

When Not To Use It

  • In development environments with local HTTP servers (use domain exceptions instead)
  • When targeting iOS 8 or earlier (ATS was introduced in iOS 9)

Further Reading


Category: Mobile Security
Type: Problem
Recommended: Yes

⚙️ Options

OptionTypeDefaultDescription
insecureLoadKeysstring[]["NSAllowsArbitraryLoads","NSAllowsArbitraryLoadsInWebContent","NSAllowsArbitraryLoadsForMedia","NSAllowsLocalNetworking","NSExceptionAllowsInsecureHTTPLoads","NSThirdPartyExceptionAllowsInsecureHTTPLoads"]Configuration keys that disable transport security; replaces the Apple ATS vocabulary

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.