Back to Blog
critical SEVERITY5 min read

How Remote Configuration Injection happens in JavaScript fetch() and how to fix it

A critical vulnerability in `js/config.js` allowed attackers to inject malicious configuration data through DNS spoofing or man-in-the-middle attacks. The application fetched remote JSON configuration from GitHub without validating the response structure, enabling arbitrary code execution through crafted payloads. A single validation check now ensures only properly-formed configuration objects are accepted.

O
By Orbis AppSec
Published July 24, 2026Reviewed July 24, 2026

Answer Summary

Remote Configuration Injection (CWE-20) occurs in JavaScript when fetch() retrieves external JSON configuration without validating the response structure. In this case, `js/config.js` fetched remote `info.json` files and only checked HTTP status codes, not data integrity. The fix adds type validation (`typeof remoteInfo !== 'object' || remoteInfo === null || Array.isArray(remoteInfo)`) to reject malformed or malicious payloads before processing.

Vulnerability at a Glance

cweCWE-20 (Improper Input Validation)
fixAdded type checking to ensure remoteInfo is a valid non-null, non-array object
riskAttackers can inject malicious configuration through MITM or DNS spoofing attacks
languageJavaScript
root causeMissing validation of fetched JSON structure before processing
vulnerabilityRemote Configuration Injection via Unvalidated JSON Response

Introduction

The js/config.js file in this application handles dynamic configuration loading, fetching remote info.json files from GitHub raw content URLs to check for updates. However, a critical flaw at line 49 created a dangerous security gap: the code only verified that the HTTP response returned successfully (res.ok), but never validated that the returned data was actually a legitimate configuration object.

This oversight meant that an attacker who could intercept network traffic—through DNS hijacking, ARP spoofing, or compromising an upstream server—could inject arbitrary JSON payloads that the application would blindly trust and process. The remoteInfo variable would accept any valid JSON, including arrays, primitives, or objects with malicious properties that could corrupt application state or trigger unintended behavior.

The Vulnerability Explained

Let's examine the vulnerable code path:

const remoteInfo = await fetch(
    'https://raw.githubusercontent.com/...'
).then(res => {
    if (!res.ok) throw new Error('获取远程info.json失败');
    return res.json();
});
const remoteTime = String(remoteInfo.lastEditTime || '');
const localTime = String(lib.extensionPack['活动武将'].lastEditTime || '');

The code fetches a remote JSON file and immediately accesses properties like lastEditTime without verifying that remoteInfo is actually a valid configuration object. Here's what's missing:

  1. No type validation: The response could be an array [], a string "malicious", a number 42, or null
  2. No schema validation: Even if it's an object, it might contain unexpected properties
  3. No integrity verification: There's no cryptographic signature or hash to verify the content hasn't been tampered with

Attack Scenario

Imagine an attacker performing DNS spoofing on a corporate network:

  1. The attacker intercepts DNS queries for raw.githubusercontent.com
  2. Requests are redirected to an attacker-controlled server
  3. The malicious server responds with HTTP 200 and a crafted payload:
["__proto__", {"polluted": "true"}]

Or even more dangerously:

{
    "lastEditTime": "2099-12-31",
    "constructor": {"prototype": {"admin": true}}
}

Since the application only checks res.ok, this malicious payload passes through. Depending on how the configuration is processed downstream, this could lead to:

  • Prototype pollution attacks if object properties are merged unsafely
  • Application state corruption causing crashes or undefined behavior
  • Logic bypass if configuration values control security-sensitive features
  • Denial of service if the application expects specific data types

The Fix

The fix adds a single but crucial validation line at js/config.js:53:

Before (Vulnerable)

const remoteInfo = await fetch(
    'https://raw.githubusercontent.com/...'
).then(res => {
    if (!res.ok) throw new Error('获取远程info.json失败');
    return res.json();
});
const remoteTime = String(remoteInfo.lastEditTime || '');

After (Secure)

const remoteInfo = await fetch(
    'https://raw.githubusercontent.com/...'
).then(res => {
    if (!res.ok) throw new Error('获取远程info.json失败');
    return res.json();
});
if (typeof remoteInfo !== 'object' || remoteInfo === null || Array.isArray(remoteInfo)) 
    throw new Error('远程info.json数据无效');
const remoteTime = String(remoteInfo.lastEditTime || '');

This validation ensures:

Check Purpose
typeof remoteInfo !== 'object' Rejects primitives (strings, numbers, booleans)
remoteInfo === null Rejects null (which has typeof "object" in JavaScript)
Array.isArray(remoteInfo) Rejects arrays (which are also objects in JavaScript)

If any of these conditions are true, the application throws an error with the message "远程info.json数据无效" (Remote info.json data invalid), preventing malicious payloads from being processed.

Prevention & Best Practices

1. Always Validate External Data Structure

// Good: Validate before use
const data = await response.json();
if (!isValidConfigObject(data)) {
    throw new Error('Invalid configuration format');
}

function isValidConfigObject(obj) {
    return (
        typeof obj === 'object' &&
        obj !== null &&
        !Array.isArray(obj) &&
        typeof obj.lastEditTime === 'string'
    );
}

2. Consider Schema Validation Libraries

For complex configurations, use libraries like Zod, Yup, or JSON Schema:

import { z } from 'zod';

const ConfigSchema = z.object({
    lastEditTime: z.string(),
    version: z.string().optional(),
});

const remoteInfo = ConfigSchema.parse(await response.json());

3. Implement Integrity Verification

For sensitive configurations, consider:

  • Subresource Integrity (SRI): Hash-based verification
  • Digital signatures: Sign configuration files and verify signatures
  • Certificate pinning: Prevent MITM attacks at the TLS level

4. Use Content Security Policy

Restrict which domains can be fetched:

// In your CSP headers
connect-src 'self' https://raw.githubusercontent.com;

Key Takeaways

  • Never trust res.ok alone: HTTP status codes don't guarantee content integrity
  • The typeof operator returns "object" for both null and arrays: Always check explicitly with === null and Array.isArray()
  • Remote configuration endpoints are high-value targets: They can affect application behavior without modifying code
  • The remoteInfo.lastEditTime access assumed valid object structure: Defensive programming requires validating assumptions
  • One line of validation prevented a critical attack vector: Simple input validation is often the most effective defense

How Orbis AppSec Detected This

  • Source: Remote JSON data fetched from https://raw.githubusercontent.com/... via fetch() API
  • Sink: Direct property access on remoteInfo.lastEditTime at js/config.js:53 without type validation
  • Missing control: No validation that the parsed JSON response was a valid configuration object (non-null, non-array object type)
  • CWE: CWE-20 (Improper Input Validation)
  • Fix: Added type checking (typeof remoteInfo !== 'object' || remoteInfo === null || Array.isArray(remoteInfo)) to reject malformed responses before processing

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

This vulnerability demonstrates a common but dangerous pattern: trusting that external data will conform to expected formats. The fix—a single validation line—shows that effective security doesn't always require complex solutions. By validating that remoteInfo is a proper object before accessing its properties, the application now rejects malicious payloads that could have been injected through network-level attacks.

When working with remote data sources, always validate the structure and type of received data before processing. This is especially critical for configuration data that can influence application behavior. Remember: in JavaScript, typeof null === 'object' and arrays are objects too—explicit checks are essential.

References

Frequently Asked Questions

What is Remote Configuration Injection?

Remote Configuration Injection occurs when an application fetches configuration data from external sources without validating its structure or authenticity, allowing attackers to inject malicious settings that alter application behavior.

How do you prevent Remote Configuration Injection in JavaScript?

Validate all fetched JSON responses by checking data types, required fields, and value ranges. Use integrity checks like Subresource Integrity (SRI) hashes, implement certificate pinning, and consider signing configuration files cryptographically.

What CWE is Remote Configuration Injection?

Remote Configuration Injection typically falls under CWE-20 (Improper Input Validation), though it may also relate to CWE-494 (Download of Code Without Integrity Check) when the configuration can influence code execution.

Is checking HTTP status codes enough to prevent configuration injection?

No. HTTP status codes only indicate whether the server responded successfully, not whether the response content is legitimate. Attackers performing MITM attacks can return valid 200 responses with malicious payloads.

Can static analysis detect Remote Configuration Injection?

Yes. Static analyzers can identify patterns where fetch() or similar APIs retrieve external data that flows into sensitive operations without validation. Tools like Semgrep can flag missing input validation on network responses.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #230

Related Articles

critical

How arbitrary code execution via injected protobuf definition type fields happens in Node.js and how to fix it

A critical arbitrary code execution vulnerability (CVE-2026-41242) was discovered in protobufjs versions prior to 7.5.5 and 8.0.1, allowing attackers to inject malicious code through crafted protobuf definition type fields. The fix upgrades the dependency from the vulnerable version 6.11.4 to 7.5.5, which properly sanitizes type field inputs during protobuf parsing. This vulnerability is especially dangerous because protobufjs is widely used in Node.js applications for serialization, meaning a s

high

How command injection happens in Node.js child_process and how to fix it

A high-severity command injection vulnerability was discovered in `bootstrap.js` at line 34, where the `exec()` function was used to run shell commands constructed from a `folder` variable. By replacing `exec()` with `execFile()` and passing arguments as an array, the fix eliminates the shell interpolation entirely, closing the door on command injection attacks that could have affected all downstream consumers of this Node.js library.

high

How unsafe pickle deserialization happens in NumPy's np.load() and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `tools/ardy-engine/retarget.py` where `np.load()` was called with `allow_pickle=True`, enabling attackers to embed malicious pickle payloads in `.npz` files. The fix was a single-character change—switching `allow_pickle=True` to `allow_pickle=False`—that eliminates the deserialization attack vector while preserving the file's legitimate array data loading functionality.

high

How SSRF and Credential Leakage via Absolute URLs happens in axios and how to fix it

A high-severity vulnerability (CVE-2025-27152) in axios versions prior to 1.8.2 allowed Server-Side Request Forgery (SSRF) attacks and credential leakage when making HTTP requests with absolute URLs. This vulnerability was fixed by upgrading from axios 1.7.4 to 1.8.2 in both package.json and package-lock.json, eliminating the attack vector that could have exposed authentication tokens and enabled unauthorized server-side requests.

high

How pickle-based arbitrary code execution happens in PyTorch and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `scripts/export_joyvasa_audio.py` where `torch.load()` was called with `weights_only=False`, allowing any pickle-serialized Python object — including malicious code — to execute during checkpoint loading. The fix switches to `weights_only=True` and explicitly allowlists only the two non-standard classes the checkpoint actually requires: `argparse.Namespace` and `pathlib.PosixPath`. This closes a real code execution path tha

critical

How WebSocket protocol length header abuse happens in Node.js and how to fix it

A critical vulnerability (CVE-2026-54466) in websocket-driver versions prior to 0.7.5 allows attackers to corrupt WebSocket messages by manipulating protocol length headers. This can lead to data integrity issues, denial of service, or potentially arbitrary code execution in affected Node.js applications. The fix involves upgrading the websocket-driver dependency to version 0.7.5.