Fuzzing Multiple C-based Parsers
I’ve done a lot of dynamic program analysis on hardware wallet software in the last years. In June, I decided to spend some time on analyzing a few popular open source C parser projects to have a change of scenery and see if I could find interesting security issues there. One goal of this research was to get more experience with a variety of different codebases for fuzzing and develop a better understanding of related challenges.
This article describes some results of this research.
Contents
Consulting
I’m a freelance Security Consultant and currently available for new projects. If you are looking for assistance to secure your projects or organization, contact me.
Analyzed Projects
Methodology: to select interesting, unexplored and somewhat “relevant” open source software to fuzz, I picked
- half a dozen parser projects
- written in pure C
- with a high number of GitHub stars
- no visible fuzzer usage
Summary
Project | Description | Maintenance status | Security issues | Non-security issues |
---|---|---|---|---|
gpmf-parser | Metadata parsing for GoPro cameras | active | see separate article | GH101, GH102, GH103, GH104 |
iniparser | Configuration file parser library | active - last commit 2019 | GH125 - full disclosure on maintainer request | - |
libconfuse | Configuration file parser library | active | #1 - fix released with v3.3 | - |
libinjection | SQL and JS injection detection library | maintainer change | - | GH150 - out of bounds read based on a documentation problem, undefined behavior |
minmea | Simple GPS parser library | active - last commit 2019 | - | GH56 - undefined behavior |
nanosvg | Simple SVG parser | “not actively maintained” | GH178 - no maintainer feedback, public after 90 days, fixed | - |
tinyexpr | Evaluation engine for math expressions | active - last commit 2018 | GH62 - full disclosure on maintainer request | undefined behavior, see GH62 |
Selection of Discovered Issues
Here are two exemplary bugs that I found:
iniparser Library DOS
When attempting to fetch a Boolean configuration flag from a specially prepared .ini
file, the library will crash due to incorrect error handling.
Relevant code:
If the key entry is not found then c == NULL
, leading to a segfault on the c[0]
read access.
libconfuse Library DOS
When attempting to parse a specially prepared .conf
file, the library will loop forever in cfg_getopt_secidx()
due to incorrect program logic.
Here is the shortened program section (GBD view) that the program is stuck on:
Relevant state:
The string processing never advances since len == 0
. An example input file which causes this is "="
(three characters).
Recommendation for Developers
Similar to the recommendations section in base64 C parser issues, here are some words of advice to developers:
- Writing parsers in C without introducing security issues is hard. If possible, pick a safer language to do this.
- For hardening, you should really consider fuzzing as an extension to unit tests.
- Unless your parser was extensively fuzzed or audited, it will likely have at least some denial of service issue when parsing arbitrary input data.
- Fuzzing will also help you to spot and remove undefined behavior problems from your code. It is better to do this before the compiler introduces weird bugs into your binaries.
Recommendation for Maintainers
General advice for popular open source projects:
- Clearly document the current project maintenance status. This simplifies the life of everyone involved.
- List a dedicated security contact email address or contact method, for example in your README.md or SECURITY.md .
- If you have a PGP key for confidential reports, please list it together with the security contact.
- If you want to restrict security reports (and CVEs) to some parts of your project then clearly describe the intended scope in a public place.
- Acknowledge the receipt of disclosure emails within a few work days, even if you don’t have time to read their contents. Among other things, this rules out unfortunate “outdated email address” / “aggressive spam filter” situations, which is helpful.
In short: make proper reporting of a confidential issue as straightforward and unambiguous as possible. This will increase the chances that people will actually take the time and effort to report issues confidentially - or at all.
Disclosure Timelines
gpmf-parser
See the separate GPMF-parser article.
iniparser
Date | information |
---|---|
2020-06-18 | Private disclosure to the maintainers with PGP |
2020-06-18 | Retransmission of the private report without PGP |
2020-06-18 | Maintainer replies and requests full disclosure |
2020-06-19 | Full disclosure via public GitHub issue |
2020-06-22 | Additional communication about security considerations |
libconfuse
Date | information |
---|---|
2020-06-18 | Private disclosure to the maintainers with PGP |
2020-06-20 | Discussion of the issue |
2020-06-21 | Public patch on GitHub |
2020-06-25 | Release v3.3 includes the patch, changelog describes the underlying issue |
libinjection
Date | information |
---|---|
2020-06-18 | Private disclosure to the maintainer |
2020-06-25 | Followup request to the maintainer for a reply |
2020-08-01 | Public GitHub issue with high-level issue description and request for feedback |
2020-08-03 | Public feedback and indications for maintainer switch |
2020-08-04 | Private disclosure to new maintainer |
2020-08-07 | Internal discussion of proposed patches |
2020-08-17 | Documentation issue is detected, security assessment changes |
2020-08-27 | Public GitHub notice about documentation issue |
nanosvg
Date | information |
---|---|
2020-06-17 | Private disclosure to the maintainer |
2020-08-01 | Public GitHub issue with high-level issue description and request for feedback |
2020-08-17 | Developer from the Tk project requests more information |
2020-08-23 | Private email to two Tk developers |
2020-08-25 | Tk developer relays private email contents to public mailing list |
2020-08-25 | Termination of private disclosure to the Tk developers |
2020-09-16 | Public disclosure of POC input on GitHub after 90 days |
2020-09-16 | Public patch proposal by Tk developers |
2020-09-21 | Fix adopted upstream |
tinyexpr
Date | information |
---|---|
2020-06-17 | Private disclosure to the maintainer |
2020-06-25 | Followup request to the maintainer for a reply |
2020-06-25 | Maintainer replies and requests full disclosure |
2020-06-25 | Full disclosure via public GitHub issue |