File upload security vulnerability (in example code), CivetWeb V1.8-V1.14

374 views
Skip to first unread message

civetweb

unread,
Oct 18, 2021, 4:38:47 PM10/18/21
to civetweb

File upload vulnerability
(in examples/embedded_c/embedded_c.c code sample)

The embedded_c example exposes a security vulnerability in the form file upload code.
The sample code for a file upload form took the unsanitized filename from the user, without stripping any path supplied by the client.
Thus, a malicious request could store a file outside the intended directory.

This vulnerability can only exists if an additional code from (or similar to) the embedded_c.c example is compiled together with the main components (civetweb.c, *.inl). It existed since V1.8 (addition of form handler) to including V1.14 and was closed in V1.15.

You are not affected if at least one of these is true:
  • You are using the pre-built Windows executable from SourceForge or GitHub releases (no CivetWeb version is affected)
  • You are using "make" (for Linux) or "cmake" in the civetweb root directory to build the server on your own.
  • You are building only using files from src/ and include/ but not examples/.
  • You do not have html form handlers, that allow file upload.
  • You updated to CivetWeb V1.15 (the vulnerability is fixed there).

You might be affected:
  • If you used directly used examples/embedded_c/embedded_c.c in your program (note: this should not be done anyway)
  • If you copied the field_found() function from this example into your own code, and used it in mg_handle_form_request()
  • If you wrote a similar field_found() function that copies/appends the "filename" argument to "path" without sanity check

The vulnerability can be exploited using command line tools like curl or wget, using web debug tools or by programming.
As to my knowledge, the vulnerability cannot be exploited by regular use in a web browser (without developer tools/plugins activated), since the web browser will never provide a file path for form file uploads.

How to fix this:
The vulnerability was fixed in two independent files in V1.15 (embedded.c and handle_form.inl). Either fix alone will avoid the problem.
  • The embedded_c example was updated, so a filename provided by the client will be sanitized in file_found().  
https://github.com/civetweb/civetweb/blob/master/examples/embedded_c/embedded_c.c
  • The handle_form.inl function now sanitizes the "path" argument before calling file_found(). You will get this file when updating to CivetWeb V1.15
https://github.com/civetweb/civetweb/blob/master/src/handle_form.inl
  • Apply an isolated patch to handle_form:
https://github.com/civetweb/civetweb/commit/b2ed60c589172b37f3d705c69d84313eeb8348b1

Reported by:

Thanks to Denys and Shachar from JFrog for reporting this issue.


General note on Security:

If you think you might have discovered a vulnerability, please report it according to the security policy in https://github.com/civetweb/civetweb/blob/master/SECURITY.md#reporting-a-vulnerability

Different security policies apply to different files and folders in files in the CivetWeb project.
- The most strict security applies to the core components (in src/) - these modules are written with security in mind.
- The examples are not updated for every version. Some of them are kept for several years for reference only. Some examples are written with simplicity in mind and omit tests that would be advised. Please have a look at the individual statements for each example.
- Test code is not intended to be secure. Some tests even introduce security leaks on purpose. Do not copy test code from the project into your production code, unless you fully understood what this code does and made your own security considerations.


Reply all
Reply to author
Forward
0 new messages