Enterprise EditionProfessional
Example server-side prototype pollution check
-
Last updated: April 18, 2024
-
Read time: 3 Minutes
This BCheck tests for server-side prototype pollution. It works by attempting to pollute the status property of Object.prototype
, changing the value of that property to a specific value.
metadata:
language: v2-beta
name: "Server-side prototype pollution"
description: "Server-side prototype pollution using the status technique"
author: "Gareth Heyes"
tags: "Server-Side Prototype Pollution"
define:
payload = `,"__proto__":\{"status\":510\}\}`
nullify = `,"__proto__":\{"status\":0\}\}`
issueDetail = "Server-Side Prototype Pollution was found on this web site."
issueRemediation = "Ensure that property keys, such as __proto__, constructor, and prototype are correctly filtered when merging objects. When creating objects, we recommend using the Object.create(null) API to ensure that your object does not inherit
from the Object.prototype and therefore won't be vulnerable to prototype pollution."
given request then
if {base.request.body} matches "^[{]" then
send request called inject_sspp:
method: "POST"
body: {regex_replace({base.request.body}, "[}]$", {payload})}
send request called check_sspp:
method: "POST"
body: "{,}"
if {latest.response.body} matches "\"statusCode\":510" or {latest.response.status_code} is "510" then
send request called clean_sspp:
method: "POST"
body: {regex_replace({base.request.body}, "[}]$", {nullify})}
send request called followup_check_sspp:
method: "POST"
body: "{,}"
if not({followup_check_sspp.response.body} matches "\"statusCode\":510" or {followup_check_sspp.response.status_code} is "510") then
report issue:
severity: high
confidence: firm
detail: `{issueDetail}`
remediation: `{issueRemediation}`
end if
end if
end if
Step 1: Add metadata
metadata:
language: v2-beta
name: "Server-side prototype pollution"
description: "Server-side prototype pollution using the status technique"
author: "Gareth Heyes"
tags: "Server-Side Prototype Pollution"
The definition starts with a metadata
block. For more information on available metadata properties, see the reference documentation.
Step 2: Declare variables
define:
payload = `,"__proto__":\{"status\":510\}\}`
nullify = `,"__proto__":\{"status\":0\}\}`
issueDetail = "Server-Side Prototype Pollution was found on this web site."
issueRemediation = "Ensure that property keys, such as __proto__, constructor, and prototype are correctly filtered when merging objects. When creating objects, we recommend using the Object.create(null) API to ensure that your object does not inherit
from the Object.prototype and therefore won't be vulnerable to prototype pollution."
The next step is to declare the following variables:
payload
attempts to pollute the prototype by changing its error status code to510
.nullify
changes the prototype's error status code to0
.issueDetail
defines informational text that can be called when required.issueRemediation
defines remediation text that can be called when required.
Step 3: Attempt to inject SSPP
given request then
if {base.request.body} matches "^[{]" then
send request called inject_sspp:
method: "POST"
body: {regex_replace({base.request.body}, "[}]$", {payload})}
The next step is to send the initial polluting request.
Burp Scanner first uses an if
statement to check for JSON requests. Where it finds a JSON request (identified by an opening curly brace character), Burp Scanner sends a request that uses the regex_replace
function to add the contents of the payload
variable to the end of the JSON object.
Step 4: Force an error to check for SSPP
send request called check_sspp:
method: "POST"
body: "{,}"
The next step is to send a second request to test whether the prototype was successfully polluted. Burp Scanner does this by using an invalid JSON object to force an error.
Step 5: Evaluate results and send follow-up request
if {latest.response.body} matches "\"statusCode\":510" or {latest.response.status_code} is "510" then
send request called clean_sspp:
method: "POST"
body: {regex_replace({base.request.body}, "[}]$", {nullify})}
The next step is to evaluate the error response sent and potentially send a follow-up request.
Burp Scanner uses an if
statement to check whether the response's status is now 510
. If this is the case, then it sends a follow up request using the nullify
variable to reset the status code to 0
.
Step 6: Do a second check for SSPP
send request called followup_check_sspp:
method: "POST"
body: "{,}"
The next step is to send another request to check the object's status code. Again, Burp Scanner does this by using an invalid JSON object to force an error.
Step 7: Report issues
if not({followup_check_sspp.response.body} matches "\"statusCode\":510" or {followup_check_sspp.response.status_code} is "510") then
report issue:
severity: high
confidence: firm
detail: `{issueDetail}`
remediation: `{issueRemediation}`
The final step is to report issues where required.
Burp Scanner uses an if statement to check whether the object's status code is still 510
. If it is not, it is likely that the prototype can be polluted. Burp Scanner reports an issue with firm
confidence.
Test this BCheck
You can test this BCheck out on the Privilege escalation via server-side prototype pollution Web Security Academy lab.