uriparser / uriparser

:hocho: Strictly RFC 3986 compliant URI parsing and handling library written in C89; moved from SourceForge to GitHub

Home Page:https://uriparser.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[CVE-2024-34402, CVE-2024-34403] uriComposeQueryMallocExMmW Bug Report

YancyLii opened this issue · comments

During fuzz testing of the uriparser library, we discovered a few potential security vulnerabilities that could impact the robustness and security of the software. These issues were identified in functions URI_FUNC(ComposeQueryEngine) and URI_FUNC(ComposeQueryMallocExMm) within the URI parsing logic. We recommend prompt attention to these matters to prevent possible exploits that could lead to buffer overflows, integer overflows, and denial of service.

Detailed Explanation and Source Code Snippets:

Integer Overflow Vulnerability:Location:
File: UriQuery.c
Function: URI_FUNC(ComposeQueryEngine)
Description:
This function calculates required space for query string composition. There's a potential integer overflow when the length of keys or values is sufficiently large, which can result in incorrect memory allocations or operations based on malformed size calculations.Vulnerable Code:
c
Copy code
const int worstCase = (normalizeBreaks == URI_TRUE ? 6 : 3);
const int keyLen = (key == NULL) ? 0 : (int)URI_STRLEN(key);
const int valueLen = (value == NULL) ? 0 : (int)URI_STRLEN(value);

if ((keyLen >= INT_MAX / worstCase) || (valueLen >= INT_MAX / worstCase)) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
Impact:
This could allow attackers to cause a denial of service or potentially execute arbitrary code via specially crafted input.
Buffer Overflow Vulnerability:Location:
File: UriQuery.c
Function: URI_FUNC(ComposeQueryEngine)
Description:
This function handles the construction of query strings and may write beyond the allocated buffer if the total size of the composed query string exceeds the bounds specified by maxChars.Vulnerable Code:

if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
Impact:
This flaw can lead to buffer overflow conditions, where memory adjacent to the buffer may be overwritten, potentially leading to code execution or corruption of data.
Null Pointer Dereference Vulnerability:Location:
File: UriQuery.c
Function: URI_FUNC(ComposeQueryEngine)
Description:
The function may attempt to dereference a NULL pointer if charsWritten is NULL but dest is not, which occurs after attempting to write the string terminator.Vulnerable Code:

if (dest != NULL) {
write[0] = _UT('\0');
if (charsWritten != NULL) {
*charsWritten = (int)(write - dest) + 1; // for terminator
}
}
Impact:
This could cause the application to crash, leading to a denial of service.
Recommendations:

We advise reviewing these sections of code to add more robust boundary checks and input validation. Consider employing safer string manipulation methods that include boundary checks inherently. Furthermore, testing for extreme boundary

Hi @YancyLii,

thanks for the report! While I consider myself part of "team security" in the sense that I consider security both important and interesting and that I'd be the first to help fixing even the smallest vulnerability rather than trying to argue it away, there is one problem though: dumping your report right into the public puts me under stress now to fix it in time (assuming there is something to fix, I have not yet had time for a closer look). That's not how security issues are supposed to be reported, please remember that next time with any project, not just uriparser. I made the same mistake once at pypi/warehouse#2940 myself. Usually criticism should be shared in private, but the issue is public so some public response is needed, and a response not bringing that criticism (and statement below) would be incomplete and misleading. I hope that's considered fair, I'm still glad to meet you and this is zero percent personal.

My past months had a crazy deadline and related overtime at work, and libexpat also takes my spare time these very days as replies to my call-for-help banner (added in libexpat/libexpat@8548bc0) and additional pro-active mails to companies start coming in. So I will not let this potential now-public vulnerability add more stress to me right now.

Whoever sees this post and would like to speed up analysis and a fix, coordinated help is welcome, let's jump on a voice call in German or English to increase efficiency. My profile has my e-mail address to co-ordinate a time that works for everyone.

Thanks for your patience and understanding, and thanks again for being a whitehat and the report 🙏

@YancyLii I had a chance at a first closer look now, and will answer in detail below:

During fuzz testing of the uriparser library, we discovered a few potential security vulnerabilities that could impact the robustness and security of the software. These issues were identified in functions URI_FUNC(ComposeQueryEngine) and URI_FUNC(ComposeQueryMallocExMm) within the URI parsing logic.

Your report points out three things about ComposeQueryEngine but none about ComposeQueryMallocExMm. Did you post the complete report?

I'll address the three findings for ComposeQueryEngine in detail below.

I created pull request #186 now for my own integer overflow findings in ComposeQueryMallocExMm. Review would be appreciated.

We recommend prompt attention to these matters to prevent possible exploits that could lead to buffer overflows, integer overflows, and denial of service.

Definitely something worth fixing, yes.

Integer Overflow Vulnerability

Location

File: UriQuery.c

Function

URI_FUNC(ComposeQueryEngine)

Description

This function calculates required space for query string composition. There's a potential integer overflow when the length of keys or values is sufficiently large, which can result in incorrect memory allocations or operations based on malformed size calculations.

Vulnerable Code

const int worstCase = (normalizeBreaks == URI_TRUE ? 6 : 3);
const int keyLen = (key == NULL) ? 0 : (int)URI_STRLEN(key);
const int valueLen = (value == NULL) ? 0 : (int)URI_STRLEN(value);

if ((keyLen >= INT_MAX / worstCase) || (valueLen >= INT_MAX / worstCase)) {
  return URI_ERROR_OUTPUT_TOO_LARGE;
} 

Impact

This could allow attackers to cause a denial of service or potentially execute arbitrary code via specially crafted input.

Addressed by pull request #185, review is appreciated.

Buffer Overflow Vulnerability

Location

File: UriQuery.c

Function

URI_FUNC(ComposeQueryEngine)

Description

This function handles the construction of query strings and may write beyond the allocated buffer if the total size of the composed query string exceeds the bounds specified by maxChars.

Vulnerable Code

if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) {
 return URI_ERROR_OUTPUT_TOO_LARGE;
}

Impact

This flaw can lead to buffer overflow conditions, where memory adjacent to the buffer may be overwritten, potentially leading to code execution or corruption of data.

Parameter maxChars is under control of the application using uriparser, and the user of the function needs to ensure that the content matches the reality of URI_CHAR * dest. I see no vulnerability here, and my understanding is that you needed to point out this potential risk as part of your analysis. If there is an attack vector beyond that, please help me see it. Thanks!

Null Pointer Dereference Vulnerability

Location

File: UriQuery.c

Function

URI_FUNC(ComposeQueryEngine)

Description

The function may attempt to dereference a NULL pointer if charsWritten is NULL but dest is not, which occurs after attempting to write the string terminator.

Vulnerable Code

if (dest != NULL) {
  write[0] = _UT('\0');
  if (charsWritten != NULL) {
    *charsWritten = (int)(write - dest) + 1; // for terminator
  }
}

Impact

This could cause the application to crash, leading to a denial of service.

write is only NULL when dest is. I don't see a NULL dereference here, not with the mentioned condition and not any other way. Please help me see the issue if there is one. Thanks!

Recommendations

We advise reviewing these sections of code to add more robust boundary checks and input validation.

I believe that pull requests #185 and #186 cover that. Do you agree?

Consider employing safer string manipulation methods that include boundary checks inherently.

I don't see how that would apply here or which functions to use instead where, given that we are still dealing with zero-terminated C strings. Please help me understand the idea.

Furthermore, testing for extreme boundary

Will need a sponsor or external reports like yours. uriparser is used in the industry — see https://uriparser.github.io/doc/users/#hardware — so these users would be best to come forward to support further hardening.

After review I would request two CVEs from Mitre for this. I would want to use your name for Mitre-internal discovery credit for the finding that pull request #185 fixes. Is "Yancy Lii" what I should use for your name?

Firstly, I apologize for directly submitting bug report on Github last time, which caused you significant work pressure. I am a freshman, and this is my first time participating in software testing and bug reporting. I am truly sorry.

Secondly, I believe there is no problem with your modifications to ComposeQuery Engine and ComposeQuery MallocExMm. Your modifications to the code looks good to me. As for the null Pointer Dereference Vulnerability issue I mentioned, it was submitted due to my analysis error. Your analysis is not a problem, so I apologize again.

I really hope that your project can become safer and more robust .Meanwhile, thank you for being willing to apply for two CVEs for my issue. My actual name is Yan Li, thank you very much!

Thanks for your kind reply! I will need to call it a day for today, I'll send updates here soon…

@YancyLii I have requested two CVEs from Mitre (through filling form https://cveform.mitre.org/) now. I did not pay as much attention when filling the forms as with fixing the issue itself, but it should be good enough. Also please note that the description that gets publish may be post-processed and not be what I entered into the form verbatim. Let's see what we get.

PS: Here's the raw quick scope analysis I did while filling the forms:

Reverse call tree

ComposeQueryEngine                        <-- (1)
    ComposeQueryCharsRequiredEx    PUBLIC
        ComposeQueryCharsRequired  PUBLIC
        ComposeQueryMallocExMm     PUBLIC <-- (2)
            ComposeQueryMallocEx   PUBLIC
                ComposeQueryMalloc PUBLIC
    ComposeQueryEx PUBIC
        ComposeQuery PUBIC
        ComposeQueryMallocExMm     PUBLIC <-- (2)

Public API affected

  • #185
    • ComposeQueryCharsRequired
    • ComposeQueryCharsRequiredEx
    • ComposeQueryMalloc
    • ComposeQueryMallocEx
    • ComposeQueryMallocExMm
  • #186
    • ComposeQueryMalloc
    • ComposeQueryMallocEx
    • ComposeQueryMallocExMm

@YancyLii this is the reply that I got back from Mitre, some text adjusted by them, some my unchanged input:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256


> [Suggested description]
> An issue was discovered in uriparser through 0.9.7.
> ComposeQueryEngine in UriQuery.c has an integer overflow via long keys or values, with a resultant buffer overflow.
> 
> ------------------------------------------
> 
> [Vulnerability Type]
> Buffer Overflow
> 
> ------------------------------------------
> 
> [Vendor of Product]
> uriparser
> 
> ------------------------------------------
> 
> [Affected Product Code Base]
> uriparser - Fixed in upcoming 0.9.8, all prior releases affected.
> 
> ------------------------------------------
> 
> [Affected Component]
> Internal functions family ComposeQueryEngine, public functions family ComposeQuery*
> 
> ------------------------------------------
> 
> [Attack Type]
> Remote
> 
> ------------------------------------------
> 
> [Impact Code execution]
> true
> 
> ------------------------------------------
> 
> [Impact Denial of Service]
> true
> 
> ------------------------------------------
> 
> [Attack Vectors]
> Crafted URI input that is longer than INT_MAX characters.
> 
> ------------------------------------------
> 
> [Reference]
> https://github.com/uriparser/uriparser/pull/185
> https://github.com/uriparser/uriparser/issues/183
> 
> ------------------------------------------
> 
> [Has vendor confirmed or acknowledged the vulnerability?]
> true
> 
> ------------------------------------------
> 
> [Discoverer]
> Yan Li

Use CVE-2024-34402.


> [Suggested description]
> An issue was discovered in uriparser through 0.9.7.
> ComposeQueryMallocExMm in
> UriQuery.c has an integer overflow via a long string.
> 
> ------------------------------------------
> 
> [Additional Information]
> Heap buffer overwrite in function ComposeQueryMallocExMm through
> integer overflow (and functions calling that function)
> 
> ------------------------------------------
> 
> [Vulnerability Type]
> Buffer Overflow
> 
> ------------------------------------------
> 
> [Vendor of Product]
> uriparser
> 
> ------------------------------------------
> 
> [Affected Product Code Base]
> uriparser - Fixed in upcoming 0.9.8, all prior releases affected.
> 
> ------------------------------------------
> 
> [Affected Component]
> Public functions family ComposeQueryMalloc*
> 
> ------------------------------------------
> 
> [Attack Type]
> Remote
> 
> ------------------------------------------
> 
> [Impact Code execution]
> true
> 
> ------------------------------------------
> 
> [Impact Denial of Service]
> true
> 
> ------------------------------------------
> 
> [Attack Vectors]
> Crafted URI input that is longer than INT_MAX / 6 - 1 characters.
> 
> ------------------------------------------
> 
> [Reference]
> https://github.com/uriparser/uriparser/pull/186
> https://github.com/uriparser/uriparser/issues/183
> 
> ------------------------------------------
> 
> [Has vendor confirmed or acknowledged the vulnerability?]
> true
> 
> ------------------------------------------
> 
> [Discoverer]
> Yan Li

Use CVE-2024-34403.


- -- 
CVE Assignment Team
M/S M300, 202 Burlington Road, Bedford, MA 01730 USA
[ A PGP key is available for encrypted communications at
  https://cve.mitre.org/cve/request_id.html ]
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEWDhf/nspQtINboAej/vgNEiM5UoFAmY0MVsACgkQj/vgNEiM
5Up9Xw/+K+BDwML5ffDTJq4XHnHi2HCRa+fu5ctCos1T19O3b2rC1nyIxvv91Qah
Kfzht9t5duakvgNduhulAxyUdCs6qzx75/KmWvcUSjzwt/M5DPqygsIXru47Vm/J
scU7ccqchnlXcxpQwdhES7sRAd8VkAIF3A2xGc8soEaE47qPsMD2bdIjq3VIi6KN
iXUkfVfvUl4v+sM4LOGqEb/pQXZzF8BWnrvzUoWsIJY81cmXmEmXLpKiopazX55N
x1QkcpuYew3jmZyIKY67Ba4kS/eRUddBo9XALNj4RX6Q7oRzuT5N5GnsyptL+pB3
0Lg5eqAAUeDitOxt6QAcDaIO0SFjbGTrANZ+dLEAzSlJ9mm1qPPdjrb7T0rENFb7
3vJm/Vr8dh8YzreFN+tzWmhL74fTG6OQbuHWcg03CD3mY3L9PGNKzaTu0ScvD3ca
QoYYcCMEmK3dnMzAwuaWIlhOlUKSkpQa1yVLNTU0xee4dB4Dm1OCzk31zcbUOBWN
5akZxxypblAy5lEVjobBvRUarydExKhlrmdK//YN4H7bNkXGifVDHDST3AqUzat+
QQJvQNdGYmQrSuYsSbxVo6yhyYuozsShAUVyUkLFdBpYmBAUjnNPgb7yGQnC9yDF
HnFUl6ysFHAOote2u/hNim7NeyLnvpK9tdGl3BF6I2X/M7Or5WQ=
=dxlD
-----END PGP SIGNATURE-----

So we got two CVEs now:

Next step for me is to make a pull request with the version bump, the change log and anything more needed to make a release.