✓ProveIt
Examples / Report #1954658 Saved analysis

CVE-2023-28322: more POST-after-PUT confusion

curl · 2023-04-1916.8s analysis · $0.017 in model calls

What the report claims

CVE-2022-32221 only fixed CURLOPT_POST but not CURLOPT_POSTFIELDS, which may be used instead, leading to potential misuse and security issues.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2023-28322 more POST-after-PUT confusion

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • The provided curl source excerpts (CMakeLists.txt and curl_setup_once.h) do not contain the option handling code for CURLOPT_POST, CURLOPT_POSTFIELDS, CURLOPT_MIMEPOST, CURLOPT_COPYPOSTFIELDS, or CURLOPT_HTTPPOST where the alleged flaw would exist.
  • The deterministic checks confirm these symbols exist in the codebase at the target revision, but the implementing code is not in the provided excerpts.
  • The proof-of-concept is detailed and demonstrates a plausible state-confusion bug (PUT state persisting into a subsequent POST request when CURLOPT_POST is not explicitly set), which matches the pattern of CVE-2022-32221.
  • A human reviewer needs to examine the actual option handling code (likely in lib/easy.c or lib/setopt.c) to verify whether CURLOPT_POSTFIELDS and related options correctly set data->set.upload = FALSE.
What still needs checking
  • Source code for option handling (CURLOPT_POSTFIELDS, CURLOPT_MIMEPOST, CURLOPT_COPYPOSTFIELDS, CURLOPT_HTTPPOST) from the target revision
  • Source code for CURLOPT_POST handling (for comparison with the CVE-2022-32221 fix)
  • The data->set.upload field definition and usage in the transfer state machine
How this analysis ran 6 claims · 5 citations verified

Checked against curl master on 2023-04-19 (6b1e4dc6cdd2). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
grounded
no model · 6 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
6 claims · 2139 tokens · $0.0002
3 · Evidence
3 code snippets
real curl source at 6b1e4dc6cdd2 · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
11124 tokens · 14.1s · $0.0164
5 · Receipts
5 of 6 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the detailed report and proof-of-concept. The issue you describe (POST-after-PUT confusion when CURLOPT_POST is not explicitly set) is plausible and matches the pattern of CVE-2022-32221. However, the source code excerpts provided for triage do not include the option handling implementation (likely in lib/easy.c or lib/setopt.c) where CURLOPT_POSTFIELDS, CURLOPT_MIMEPOST, and CURLOPT_COPYPOSTFIELDS are processed. Could you point to the specific file and function where these options are handled, or provide the relevant code sections? This will allow us to verify whether they correctly set data->set.upload = FALSE as CURLOPT_POST does.

Inspect all claims and source code 6 claims · 3 code excerpts

Report claims

C1flaw not verifiable

CURLOPT_POST is not necessarily used when sending data with the POST method

Read the reasoning

The provided curl source excerpts only show CMakeLists.txt and curl_setup_once.h. The actual implementation of CURLOPT_POST, CURLOPT_POSTFIELDS, and related options (likely in lib/easy.c or lib/setopt.c) is not included, so the claim cannot be verified against the provided code.

C2flaw not verifiable

CURLOPT_POSTFIELDS does not set a FALSE on data->set.upload

Read the reasoning

The claim concerns whether CURLOPT_POSTFIELDS sets data->set.upload to FALSE. The provided source does not include the option processing code where this would be implemented.

C3flaw not verifiable

CURLOPT_POST is not used in the CURLOPT_MIMEPOST usage example

Read the reasoning

The provided source does not include the implementation of CURLOPT_MIMEPOST or its interaction with CURLOPT_POST.

C4flaw not verifiable

Users may not use CURLOPT_POST when using CURLOPT_POSTFIELDS

Read the reasoning

This claim about user behavior patterns cannot be verified from the provided source code excerpts.

C5flaw not verifiable

The statement on the official website implies that using CURLOPT_POSTFIELDS sets CURLOPT_POST to 1

Read the reasoning

The external source E1 (pipermail archive) was retrieved but the provided excerpt does not contain the specific statement 'Using CURLOPT_POSTFIELDS implies setting CURLOPT_POST to 1'. The claim about documentation content cannot be confirmed from the provided excerpt.

E1:0
C6flaw not verifiable

Some users do not use CURLOPT_POST

Read the reasoning

This claim about user behavior cannot be verified from the provided source code.

What the report says about other projects

not addressed Using CURLOPT_POSTFIELDS implies setting CURLOPT_POST to 1

Read the original report (excerpt)

Full report on HackerOne ↗

## Summary: CVE-2022-32221 fixes is insufficient. In CVE-2022-32221, only CURLOPT_POST was corrected. However, CURLOPT_POST is not necessarily used when sending data with the POST method. CURLOPT_POST is not used in the CURLOPT_POSTFIELDS usage example on the official website. ``` CURL *curl = curl_easy_init(); if(curl) { const char *data = "data to send"; curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); /* size of the POST data */ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L); /* pass in a pointer to the data - libcurl will not copy */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_perform(curl); } ``` Also on this page is the following statement. >Using CURLOPT_POSTFIELDS implies setting CURLOPT_POST to 1. https://curl.se/libcurl/c/CURLOPT_POSTFIELDS.html I think it means that some users do not use CURLOPT_POST. Just to be clear, CURLOPT_POSTFIELDS does not set a `FLASE` on `data->set.upload`. CURLOPT_POST is not used in the CURLOPT_MIMEPOST usage example either. https://curl.se/libcurl/c/CURLOPT_MIMEPOST.html Based on the above, I think we need to modify the following to assign `FALSE` to `data->set.upload` if we use the following. * CURLOPT_POSTFIELDS * CURLOPT_COPYPOSTFIELDS * CURLOPT_MIMEPOST We could not determine the deprecated CURLOPT_HTTPPOST. ## Steps To Reproduce: Almost the same source as #1704017. The difference is that line 52 is commented out. ``` #include <stdio.h> #include <string.h> #include <curl/curl.h> typedef struct { char *buf; size_t len; } put_buffer; static size_t put_callback(char *ptr, size_t size, size_t nmemb, void *stream) { put_buffer *putdata = (put_buffer *)stream; size_t totalsize = size * nmemb; size_t tocopy = (putdata->len < totalsize) ? putdata->len : totalsize; memcpy(ptr, putdata->buf, tocopy); putdata->len -= tocopy; putdata->buf += tocopy; return tocopy; } int main() { CURL *curl = NULL; put_buffer pbuf = {}; char *otherdata = "This is some other data"; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); // PUT curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_READFUNCTION, put_callback); pbuf.buf = strdup("This is highly secret and sensitive data"); pbuf.len = strlen(pbuf.buf); curl_easy_setopt(curl, CURLOPT_READDATA, &pbuf); curl_ …

Source code

lib/CMakeLists.txtlines 24–143 · definition of set
24set(LIB_NAME libcurl)
C1: Provided source does not contain option handling code for CURLOPT_POST or CURLOPT_POSTFIELDS
C2: Provided source does not contain option handling code for CURLOPT_POSTFIELDS or data->set.upload
C3: Provided source does not contain CURLOPT_MIMEPOST handling code
C4: Provided source does not contain user-facing option handling code
C6: Provided source does not contain user behavior evidence
25set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
26add_definitions(-DBUILDING_LIBCURL)
27
28if(BUILD_SHARED_LIBS)
29 set(CURL_STATICLIB NO)
30else()
31 set(CURL_STATICLIB YES)
32endif()
33
34# Use:
35# * CURL_STATICLIB
36configure_file(curl_config.h.cmake
37 ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
38
39transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
40include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
41
42list(APPEND HHEADERS
43 ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
44 )
45
46if(WIN32 AND NOT CURL_STATICLIB)
47 list(APPEND CSOURCES libcurl.rc)
48endif()
49
50# The rest of the build
51
52include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
53include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
54include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
55include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
56include_directories(${CMAKE_CURRENT_SOURCE_DIR})
57include_directories(${CMAKE_CURRENT_BINARY_DIR})
58if(USE_ARES)
59 include_directories(${CARES_INCLUDE_DIR})
60endif()
61
62add_library(
63 ${LIB_NAME}
64 ${HHEADERS} ${CSOURCES}
65 )
66
67add_library(
68 ${PROJECT_NAME}::${LIB_NAME}
69 ALIAS ${LIB_NAME}
70 )
71
72if(NOT BUILD_SHARED_LIBS)
73 set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
74endif()
75
76target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
77
78transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
79include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
80
81set_target_properties(${LIB_NAME} PROPERTIES
82 COMPILE_DEFINITIONS BUILDING_LIBCURL
83 OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
84 )
85
86if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
87 CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
88 CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
89 CMAKE_SYSTEM_NAME STREQUAL "SunOS" OR
90 CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR
91
92 # FreeBSD comes with the a.out and elf flavours
93 # but a.out was supported up to version 3.x and
94 # elf from 3.x. I cannot imagine someone running
95 # CMake on those ancient systems
96 CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
97
98 CMAKE_SYSTEM_NAME STREQUAL "Haiku")
99
100 math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}")
101 set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}")
102
103 set_target_properties(${LIB_NAME} PROPERTIES
104 VERSION ${CMAKEVERSION}
105 SOVERSION ${CMAKESONAME}
106 )
107
108endif()
109
110
111if(HIDES_CURL_PRIVATE_SYMBOLS)
112 set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
113 set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
114endif()
115
116# Remove the "lib" prefix since the library is already named "libcurl".
117set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
118set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
119
120if(CURL_HAS_LTO)
121 set_target_properties(${LIB_NAME} PROPERTIES
122 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
123 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
124endif()
125
126if(WIN32)
127 if(BUILD_SHARED_LIBS)
128 if(MSVC)
129 # Add "_imp" as a suffix before the extension to avoid conflicting with
130 # the statically linked "libcurl.lib"
131 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
132 endif()
133 endif()
134else()
135 # on not-Windows, check for writable argv[]
136 include(CheckCSourceRuns)
137 check_c_source_runs("
138int main(int argc, char **argv)
139{
140 (void)argc;
141 argv[0][0] = ' ';
142 return (argv[0][0] == ' ')?0:1;
143}"
lib/CMakeLists.txt@curl-8_0_1lines 24–151 · definition of set as in release curl-8_0_1; differs from master
24set(LIB_NAME libcurl)
25set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
26add_definitions(-DBUILDING_LIBCURL)
27
28if(BUILD_SHARED_LIBS)
29 set(CURL_STATICLIB NO)
30else()
31 set(CURL_STATICLIB YES)
32endif()
33
34# Use:
35# * CURL_STATICLIB
36configure_file(curl_config.h.cmake
37 ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
38
39transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
40include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
41
42list(APPEND HHEADERS
43 ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
44 )
45
46if(WIN32 AND NOT CURL_STATICLIB)
47 list(APPEND CSOURCES libcurl.rc)
48endif()
49
50# The rest of the build
51
52include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
53include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
54include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
55include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
56include_directories(${CMAKE_CURRENT_SOURCE_DIR})
57include_directories(${CMAKE_CURRENT_BINARY_DIR})
58if(USE_ARES)
59 include_directories(${CARES_INCLUDE_DIR})
60endif()
61
62add_library(
63 ${LIB_NAME}
64 ${HHEADERS} ${CSOURCES}
65 )
66
67add_library(
68 ${PROJECT_NAME}::${LIB_NAME}
69 ALIAS ${LIB_NAME}
70 )
71
72if(NOT BUILD_SHARED_LIBS)
73 set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
74endif()
75
76target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
77
78transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
79include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
80
81set_target_properties(${LIB_NAME} PROPERTIES
82 COMPILE_DEFINITIONS BUILDING_LIBCURL
83 OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
84 )
85
86if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
87 CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
88 CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
89 CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR
90
91 # FreeBSD comes with the a.out and elf flavours
92 # but a.out was supported up to version 3.x and
93 # elf from 3.x. I cannot imagine someone running
94 # CMake on those ancient systems
95 CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
96
97 CMAKE_SYSTEM_NAME STREQUAL "Haiku")
98
99 math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}")
100 set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}")
101
102 set_target_properties(${LIB_NAME} PROPERTIES
103 VERSION ${CMAKEVERSION}
104 SOVERSION ${CMAKESONAME}
105 )
106
107endif()
108
109
110if(HIDES_CURL_PRIVATE_SYMBOLS)
111 set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
112 set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
113endif()
114
115# Remove the "lib" prefix since the library is already named "libcurl".
116set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
117set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
118
119if(CURL_HAS_LTO)
120 set_target_properties(${LIB_NAME} PROPERTIES
121 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
122 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
123endif()
124
125if(WIN32)
126 if(BUILD_SHARED_LIBS)
127 if(MSVC)
128 # Add "_imp" as a suffix before the extension to avoid conflicting with
129 # the statically linked "libcurl.lib"
130 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
131 endif()
132 endif()
133endif()
134
135target_include_directories(${LIB_NAME} INTERFACE
136 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
137 $<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
138
139if(CURL_ENABLE_EXPORT_TARGET)
140 install(TARGETS ${LIB_NAME}
141 EXPORT ${TARGETS_EXPORT_NAME}
142 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
143 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
144 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
145 )
146
147 export(TARGETS ${LIB_NAME}
148 FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
149 NAMESPACE ${PROJECT_NAME}::
150 )
151endif()
lib/curl_setup_once.hlines 273–273 · definition of FALSE
Show 1 lines (not cited by the judge)
273#define FALSE false