HIGH prototype pollutionazure

Prototype Pollution on Azure

How Prototype Pollution Manifests in Azure

Prototype pollution in Azure environments typically occurs through deserialization of untrusted data, particularly when handling configuration files, API requests, or user-supplied parameters that interact with Azure services. This vulnerability allows attackers to modify JavaScript object prototypes, potentially leading to denial of service, information disclosure, or remote code execution.

In Azure Functions, prototype pollution often emerges when processing HTTP triggers that accept JSON payloads. Consider this vulnerable Azure Function code:

module.exports = async function (context, req) {
const config = JSON.parse(req.body);
const { options } = config;
// Vulnerable: options could be polluted
return {
status: 200,
body: processOptions(options)
};
};

The issue arises because Node.js allows prototype chain manipulation through objects. An attacker could send:

{
"options": {
"__proto__.isAdmin": true
}
}

This would add an isAdmin property to Object.prototype, affecting all objects in the application.

Azure App Service applications face similar risks when using Express middleware for request parsing. The built-in body-parser middleware can be vulnerable if not properly configured:

const express = require('express');
const app = express();

app.use(express.json()); // Vulnerable by default

app.post('/azure-config', (req, res) => {
const config = req.body;
// If config contains __proto__ or constructor properties,
// prototype pollution occurs
applyAzureConfig(config);

Azure Logic Apps that process JSON payloads from HTTP triggers can also be affected. When Logic Apps use custom connectors or HTTP actions to call APIs, malicious payloads can exploit prototype pollution in downstream services.

Azure API Management policies sometimes inadvertently introduce prototype pollution when transforming JSON payloads. Consider this policy:

<policies>
<on-error>
<set-variable name="error" value="@{(string)context.LastError.Message}" />
</on-error>
<return-response>
<set-status code="@((int)context.Response.StatusCode)" />
<set-body>
{
"message": "@context.Variables["error"]",
"__proto__.polluted": true
}
</set-body>
</return-response>
</policies>

While this example shows the vulnerability in policy definition, the actual risk comes from how the response is processed by client applications.

Azure Service Bus message processing can also be vulnerable. When applications deserialize messages from Service Bus queues without proper validation, prototype pollution can occur:

const { ServiceBusClient } = require('@azure/service-bus');

const client = new ServiceBusClient(connectionString);
const receiver = client.createReceiver(queueName);

const processMessage = async (message) => {
const data = JSON.parse(message.body);
// No validation of data properties
applyConfiguration(data);
};

The common thread across these Azure services is the lack of input validation and sanitization when processing untrusted JSON data that could contain prototype pollution payloads.

Azure-Specific Detection

Detecting prototype pollution in Azure environments requires both static code analysis and dynamic runtime scanning. For Azure Functions and App Services, the middleBrick API security scanner can identify prototype pollution vulnerabilities by analyzing the attack surface and testing for common pollution patterns.

middleBrick's black-box scanning approach tests Azure endpoints without requiring credentials or source code access. The scanner sends specially crafted payloads to detect prototype pollution:

POST /api/azure-function HTTP/1.1
Host: example.azurewebsites.net
Content-Type: application/json

{
"test": {
"__proto__.polluted": "prototype pollution test",
"constructor.prototype.polluted": "constructor pollution"
}
}

The scanner then analyzes the response to determine if the payload successfully modified object prototypes. middleBrick tests for 12 security categories including Authentication, BOLA/IDOR, and Input Validation, with prototype pollution falling under the broader input validation category.

For Azure Logic Apps, detection involves examining HTTP trigger configurations and any custom connectors that process JSON data. The middleBrick CLI tool can scan Logic App endpoints:

npx middlebrick scan https://example.azurewebsites.net/api/logicapp-trigger

Azure API Management policies can be analyzed using middleBrick's OpenAPI/Swagger spec analysis. The scanner resolves $ref definitions and identifies policy configurations that might introduce prototype pollution risks.

Static analysis tools specific to Node.js can also detect prototype pollution patterns in Azure Functions code. Tools like ESLint with the no-prototype-builtins rule can catch unsafe prototype usage:

// .eslintrc.js
module.exports = {
rules: {
'no-prototype-builtins': 'error'
}
};

Runtime detection in Azure environments can be implemented using middleware that validates incoming JSON payloads:

const hasPrototypePollution = (obj) => {
const dangerousKeys = ['__proto__', 'constructor', 'prototype'];
const stack = [obj];

while (stack.length) {
const current = stack.pop();
for (const key of Object.keys(current)) {
if (dangerousKeys.includes(key)) {
return true;
}
if (typeof current[key] === 'object' && current[key] !== null) {
stack.push(current[key]);
}
}
}
return false;
};

Azure Application Insights can be configured to log and alert on prototype pollution attempts by monitoring for unusual object property patterns in incoming requests.

For Azure Service Bus, message validation middleware should inspect payloads before processing:

const validateMessage = (message) => {
if (typeof message.body !== 'object' || message.body === null) {
return false;
}
return !hasPrototypePollution(message.body);
};

middleBrick's continuous monitoring capability (available in Pro and Enterprise tiers) can regularly scan Azure endpoints to detect newly introduced prototype pollution vulnerabilities as code changes over time.

Azure-Specific Remediation

Remediating prototype pollution in Azure environments requires a multi-layered approach combining input validation, safe parsing, and secure coding practices. For Azure Functions and App Services, the primary defense is validating and sanitizing all incoming JSON data.

Using a secure JSON parser that prevents prototype pollution is the first line of defense:

const safeJSONParse = (str) => {
try {
const parsed = JSON.parse(str, (key, value) => {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
throw new Error('Prototype pollution attempt detected');
}
return value;
});
return parsed;
} catch (error) {
throw new Error('Invalid JSON or prototype pollution attempt');
}
};

Apply this safe parsing in Azure Functions:

module.exports = async function (context, req) {
let config;
try {
config = safeJSONParse(req.body);
} catch (error) {
return {
status: 400,
body: { error: 'Invalid input' }
};
}
// Safe to use config
};

For Azure Logic Apps, use the built-in schema validation to define strict input formats:

<triggers>
<http-request>
<schema>
{
"type": "object",
"properties": {
"username": { "type": "string" },
"settings": {
"type": "object",
"properties": {
"theme": { "type": "string" }
},
"additionalProperties": false
}
},
"additionalProperties": false
}
</schema>
</http-request>
</triggers>

Azure API Management can use validate-jwt policies to ensure only expected properties are present:

<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="https://example.com/.well-known/openid-configuration" />
<required-claims>
<claim name="aud" match="any">
<value>expected-audience</value>
</claim>
</required-claims>
</validate-jwt>

For Azure Service Bus, implement message validation before processing:

const validateAzureServiceBusMessage = (message) => {
const schema = {
type: 'object',
properties: {
userId: { type: 'string' },
action: { type: 'string', enum: ['create', 'update', 'delete'] }
},
required: ['userId', 'action'],
additionalProperties: false
};

return validate(schema, message.body);
};

Using TypeScript in Azure Functions provides compile-time protection against prototype pollution:

interface AzureConfig {
userId: string;
settings?: {
theme?: string;
notifications?: boolean;
};
}

const processConfig = (config: AzureConfig) => {
// TypeScript ensures only defined properties exist
};

For Azure App Service, implement Express middleware that sanitizes request bodies:

const prototypePollutionSanitizer = (obj) => {
const dangerousKeys = ['__proto__', 'constructor', 'prototype'];

const sanitize = (currentObj) => {
if (Array.isArray(currentObj)) {
return currentObj.map(sanitize);
} else if (typeof currentObj === 'object' && currentObj !== null) {
const sanitized = {};
for (const [key, value] of Object.entries(currentObj)) {
if (dangerousKeys.includes(key)) {
continue; // Skip dangerous keys
}
sanitized[key] = sanitize(value);
}
return sanitized;
}
return currentObj;
};

return sanitize(obj);
};

Azure Application Gateway WAF rules can be configured to block requests containing prototype pollution patterns:

# Azure Application Gateway WAF Policy
<Rule>
<Match>
<MatchVariable>RequestBodyJson</MatchVariable>
<Operator>Contains</Operator>
<Value>__proto__</Value>
</Match>
<Action>Block</Action>
</Rule>

Regular security scanning with middleBrick (Pro tier includes continuous monitoring) ensures prototype pollution vulnerabilities are detected as they're introduced during development.

Frequently Asked Questions

How does prototype pollution in Azure Functions differ from traditional Node.js applications?
Azure Functions have unique characteristics that affect prototype pollution. The serverless nature means functions may share runtime instances, allowing prototype pollution to persist across invocations. Additionally, Azure Functions often process external data from various Azure services (Service Bus, Event Grid, HTTP triggers), each with different serialization behaviors. The cold start behavior can also impact how prototype pollution manifests, as polluted prototypes may persist in warm instances but not in cold starts.
Can middleBrick detect prototype pollution in Azure Logic Apps?
Yes, middleBrick can scan Azure Logic App endpoints through their HTTP trigger URLs. The scanner sends test payloads containing prototype pollution patterns and analyzes the responses to determine if the Logic App processes them unsafely. For Logic Apps that call downstream APIs, middleBrick can also scan those endpoints to identify prototype pollution vulnerabilities in the complete workflow. The Pro tier's continuous monitoring can regularly scan Logic App endpoints as part of your security posture management.