Preface
This article is a record and study note of the author learning PortSwigger's API Test type vulnerability
The tools used are Burp Suite Pro
Vulnerability Introduction
What is API
API stands for Application Interface, which is the interface that applications provide to the outside world. Currently, there are mainly three API styles, namely JSON style API, RESTful style API, and Graphic style API
JSON style

Request for user information
POST /api/getUser HTTP/1.1
Host: example.com
Content-Type: application/json
{
"userId": 1
}
RESTful style
Request for user information
GET /api/users/1 HTTP/1.1
Host: example.com
Request to modify user information
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
Graphic style
Request for user information
POST /graphql HTTP/1.1
Host: example.com
Content-Type: application/json
{
"query": "{ user(id: 1) { id, name, email } }"
}
What is API testing
This type of API vulnerability mainly includes tests ofthe destruction of the expected running logic of open APIsandDetection and invocation of unopened APIswhich may lead to hazards such as sensitive information leakage and changes in application behavior
This article mainly discusses JSON and RESTful APIs
When testing an API, pay attention to the following points:
The data received and processed by the API, including required and optional
The types of requests accepted by the API, including request methods and media formats
rate limiting and authentication mechanisms
to interact with
Use different request methods
HTTP/1.0 defined three request methods: GET, POST, and HEAD
GET
Request a representation of a specified resource usingGET
The request should only be used to retrieve data.HEAD
Request a representation of a specified resource usingGET
Request a response with the same response, but without a response body.POST
Used to submit an entity to the specified resource, usually resulting in a state change or side effect on the server.
HTTP/1.1 introduced six new request methods: OPTIONS, PUT, DELETE, TRACE, CONNECT, and PATCHOPTIONS
Used to describe communication options for the target resource.PUT
Request a payload to replace all current representations of the target resource.DELETE
Delete the specified resource.TRACE
Execute a message loopback test along the path to the target resource.CONNECT
Establish a tunnel to the server identified by the target resource.PATCH
The method is used to apply partial modifications to resources.
Use different Content-Type
The following are the most commonly used 10 types of Content-Typeapplication/json
Purpose: Used for JSON data transmission, commonly used in RESTful APIs.
text/html
Purpose: Used for HTML data transmission, commonly used in web page responses.
application/x-www-form-urlencoded
Purpose: Used for encoding HTML form submissions, encoding form data into key-value pairs.
multipart/form-data
Purpose: Used for encoding file upload forms, allowing the upload of files and other data simultaneously.
text/plain
Purpose: Used for plain text data transmission, without special formatting requirements.
application/xml
Purpose: Used for XML data transmission.
application/javascript
Purpose: Used for transmitting JavaScript code.
application/octet-stream
Purpose: Used for transmitting binary data, without specifying a specific file format, usually used for file downloads.
image/jpeg
Purpose: Used for transmitting JPEG image files.
image/png
Purpose: Used for transmitting PNG image files.
Labs
lab1
lab address:Exploiting an API endpoint using documentation
This lab is the most basic, the pass condition is to delete the user carlos's account
Log in to the website, try to find all the functions, and then observe the burpsuite's HTTP History to find a method of PATCH requests, API endpoint is/api/user/wiener
Directly try to modify the HTTP request method to delete and make a request to the user carlos
lab2
lab address:Exploiting server-side parameter pollution in a query string
The focus of this lab is parameter pollution in the request string, the pass condition is to log in to the administrator's account and delete the carlos account
Customarily, perform all operations first and observe the burpsuite's HTTP history
Send the POST request to /fogot-password for research on the repeater
Send the request to the intruder module to brute force the value of the field parameter
Brute force shows the correct result
Set the value of field to email and send the original POST request, found that the response is the same as not setting the field, then check the http history to see if there are other possible values
FoundGET /static/js/forgotPassword.js
The JavaScript file content is as follows
let forgotPwdReady = (callback) => {
if (document.readyState !== "loading") callback();
else document.addEventListener("DOMContentLoaded", callback);
}
function urlencodeFormData(fd){
let s = '';
function encode(s){ return encodeURIComponent(s).replace(/%20/g,'+'); }
for(let pair of fd.entries()){
if(typeof pair[1]=='string'){
s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
}
}
return s;
}
const validateInputsAndCreateMsg = () => {
try {
const forgotPasswordError = document.getElementById("forgot-password-error");
forgotPasswordError.textContent = "";
const forgotPasswordForm = document.getElementById("forgot-password-form");
const usernameInput = document.getElementsByName("username").item(0);
if (usernameInput && !usernameInput.checkValidity()) {
usernameInput.reportValidity();
return;
}
const formData = new FormData(forgotPasswordForm);
const config = {
method: "POST",
headers: {
"Content-Type": "x-www-form-urlencoded",
,
body: urlencodeFormData(formData)
});
fetch(window.location.pathname, config)
.then(response => response.json())
.then(jsonResponse => {
if (!jsonResponse.hasOwnProperty("result"))
{
forgotPasswordError.textContent = "Invalid username";
}
else
{
forgotPasswordError.textContent = `Please check your email: "${jsonResponse.result}"`;
forgotPasswordForm.className = "";
forgotPasswordForm.style.display = "none";
}
});
.catch(err => {
forgotPasswordError.textContent = "Invalid username";
});
}) catch (error) {
console.error("Unexpected Error:", error);
}
}
const displayMsg = (e) => {
e.preventDefault();
validateInputsAndCreateMsg(e);
});
forgotPwdReady(() => {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const resetToken = urlParams.get('reset-token');
if (resetToken)
{
window.location.href = `/forgot-password?reset_token=${resetToken}`;
}
else
{
const forgotPasswordBtn = document.getElementById("forgot-password-btn");
forgotPasswordBtn.addEventListener("click", displayMsg);
}
});
The most critical piece of code is:
forgotPwdReady(() => {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const resetToken = urlParams.get('reset-token');
if (resetToken)
{
window.location.href = `/forgot-password?reset_token=${resetToken}`;
}
else
{
const forgotPasswordBtn = document.getElementById("forgot-password-btn");
forgotPasswordBtn.addEventListener("click", displayMsg);
}
});
The code involves a parameterreset_token
, try to set the field toreset_token
, the response has changed
According to/forgot-password?reset_token=${resetToken}
, rebuild the get request
Then set a new password and delete the carlos account
lab3
lab address:Finding and exploiting an unused API endpoint
This lab focuses on finding and testing unused API endpoints, and the通关 condition is to purchase a product
First try all the functions and find that it is impossible to recharge, the balance is 0, my idea is to modify the price of the product or bypass the payment process
Observe the brupsuite's http history and find:GET /api/products/1/price HTTP/2
, send it to repeater for study
First change the http method to OPTION and find that GET and patch methods are allowed
Build a request for the patch method
Construct data in a specified format, the data is guessed, but it is relatively easy to guess
After that, you can buy for free and pass the level
lab4
lab address:Exploiting a mass assignment vulnerability
This lab focuses on mass assignment vulnerabilities, and the通关 condition is to purchase a product, or the previous idea
As a matter of course, I first tried all the functions and then checked the burpsuite's http history
I found two interesting requests:POST /api/checkout HTTP/2
andGET /api/checkout HTTP/2
When clicking the payment button, a POST request is sent first, with the list of purchased products as the data, including product ID and quantity
{"chosen_products":[{"product_id":"1","quantity":1}]}
A GET request will return the relevant information of this transaction, as shown in the following figure:
The first attempt was to modify the price of the product, but it did not succeed
Then modify the field representing the discount and the purchase will be successful immediately after sending the request
lab5
lab address:Exploiting server-side parameter pollution in a REST URL
This lab is similar to lab2 in terms of thought, with the focus on changing the behavior of server-side requests, but with many more defensive measures, which require more skills to combine, and the passing conditions are the same as lab2
Firstly, use the test techniques used in lab2, and then speculate that the server-side request may place the username content in the path part of the url after testing
Construct username as:https://www.freebuf.com/articles/es/administrator
Read the configuration file and find the url path:/api/api/internal/v1/users/{username}/field/{field}
Change the username parameter toadministrator/field/x#
, trying to rewrite field
Like lab2, checkGET /static/js/forgotPassword.js
Construct username as:administrator/field/passwordResetToken#
Specify the version through path traversal
Construct a GET request to send
Then change the password, delete the carlos account, and pass the level
How to defend against vulnerabilities caused by APIs
Firstly, it is best to consider security factors from the beginning when designing the system
Secondly, it is best to follow the following guidelines
If you don't want your api to be publicly accessible, keep your documentation secure
Ensure that your documentation is comprehensive enough to allow legitimate testers to collect a comprehensive attack surface
Set the allowed HTTP methods
Verify that the received request or response is in the expected format
Use common error messages to avoid leaking valuable information
Set defensive measures for all versions of the api, not just the current main version
List the attributes that users can modify in the whitelist, and the sensitive attributes that users cannot modify in the blacklist

评论已关闭