Talos Vulnerability Report


ArduPilot APWeb cgi.c unescape memory corruption vulnerability

April 14, 2022
CVE Number



A memory corruption vulnerability exists in the cgi.c unescape functionality of ArduPilot APWeb master branch 50b6b7ac - master branch 46177cb9. A specially-crafted HTTP request can lead to memory corruption. An attacker can send a network request to trigger this vulnerability.

Tested Versions

ArduPilot APWeb master commit 50b6b7ac - master commit 46177cb9

Product URLs

APWeb - https://github.com/ArduPilot/APWeb

CVSSv3 Score

5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N


CWE-20 - Improper Input Validation


APWeb is the web server for ArduPilot.

The ArduPilot’s APWeb component, has a file named cgi.c that contains CGI helper functions. One of these functions is unescape:

void unescape(char *p)
    unsigned v;

    while (*p) {                                                                                        [1]
        if (*p == '+') *p = ' ';
        if (*p == '%' && sscanf(p+1, "%02x", &v) == 1) {                                                [2]
            *p = (char)v;                                                                               [3]
            memcpy(p+1, p+3, strlen(p+3)+1);                                                            [4]

This function takes as argument a string. If the string is URL-encoded, this function will decode it. The while loop, starting at [1], will traverse the input searching for the characters % or +. When the % character is found, at [2], the following two characters are converted from hex values to a single character. At [3] the converted character replaces the % character. At [4], the string after the just-parsed URL-encoded character is moved left by two positions. This will replace the parsed characters. A string like “A…B%41%42” would go through the following steps:

|A|...|B|%|4|1|%|4|2|NULL|           at    [1]/[2]
|A|...|B|A|4|1|%|4|2|NULL|           after [3]
|A|...|B|A|%|4|2|NULL|2|NULL|        after [4]

Eventually, after a second iteration of the loop we would end up like this:

|A|...|B|A|B|NULL|2|NULL|2|NULL|     after [4]

The unescape function assumes, wrongly, that after a % there are always at least two characters. If this is not the case, the instruction at [4] would cause a out-of-bounds read, and could cause an out-of-bounds and write.

Vendor Response

This fixes a vulnerability in unescape which can lead to memory overwrite



2022-04-11 - Vendor Disclosure
2022-04-11 - Vendor Patch Release
2022-07-27 - Public Release


Discovered by Francesco Benvenuto of Cisco Talos.