首页 > 解决方案 > 如何从进程内存中清除使用 Curl 下载的数据?

问题描述

Curl我使用以下代码从我的数据库中下载/读取数据:

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}
    
    

void Url(std::string& data, std::string url, std::string mode, std::string json)
{
    CURLcode ret;
    CURL* curl;
    struct curl_slist* slist1;

    curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);


    if (!json.empty()) 
    {

        slist1 = NULL;
        slist1 = curl_slist_append(slist1, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
        //curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.38.0");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1);
    }

    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, mode.c_str());
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);

    ret = curl_easy_perform(curl);

    curl_easy_cleanup(curl);
    curl = NULL;

    if (!json.empty()) 
    {
        curl_slist_free_all(slist1);
        slist1 = NULL;
    }

}



// ...
std::string data = "";
Url(data, "", "POST", "{\"key\": \"test\"}")

// ...
// Zeroes the data.
RtlSecureZeroMemory(const_cast<char*>(data.data()), data.size());

当我进入调用上述代码并从中创建转储文件的进程时,我可以Curl在转储文件内部找到调用中的所有数据,即使发送的密钥的内容也是可读的"test"

这是它在转储文件中的外观:

Server: Cowboy
Connection: keep-alive
Vary: Origin
Content-Type: text/plain; charset=utf-8
Content-Length: 43
Date: Thu, 14 Oct 2021 16:14:45 GMT
Via: 1.1 vegur
   
   < the data received >

   < the API path > HTTP/1.1
Host: ....herokuapp.com
Accept: */*
Content-Type: application/json
Content-Length: 23

{"key":"test"}  

我正在使用 Heroku 和 MongoDB,Curl我正在连接到 Heroku 中的 API 路径,例如: https://....herokuapp.com/api/...

在路径后面的转储文件中,有一个HTTP https://i.imgur.com/UaPin1i.png

根据建议,我也尝试呼吁SecureZeroMemory. 但是转储文件、API 路径、json 密钥、发送/接收的内容、服务器名称等中的所有信息仍然是可读的。

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
    // userp is a pointer to a std::string
    // -> cast to std::string* and store in variable for ease of use
    std::string* str = reinterpret_cast<std::string*>(userp);

    // size of current data
    std::size_t bak_size = str->size();

    char* bak = new char[bak_size]; // temporary buffer
    str->copy(bak, str->size());    // copy current data into temporary buffer

    // Zeroes current data
    RtlSecureZeroMemory(const_cast<char*>(str->data()), str->size());

    // Resize the string (userp), this causes reallocation
    // -> the memory must be zeroed before because the old data may still be in memory
    //    after it is discarded for the string to allocate new blocks
    str->resize(str->size() + (size * nmemb));
    RtlCopyMemory(const_cast<char*>(str->data()), bak, bak_size); // Copy from temporary buffer into new address
    RtlCopyMemory(const_cast<char*>(str->data()) + bak_size, contents, size * nmemb); // Append the new content

    // Zeroes and frees the temporary buffer.
    RtlSecureZeroMemory(bak, bak_size);
    delete[] bak;
    bak = nullptr;

    //((std::string*)userp)->append((char*)contents, size * nmemb);
    //memset(contents, 0, size * nmemb);

    // Zeroes the content
    RtlSecureZeroMemory(contents, size * nmemb);
    return size * nmemb;
}

想问一下我能做些什么来避免它变得如此容易阅读。如果有可能以某种方式将其从内存中清除。

标签: c++windowslibcurl

解决方案


推荐阅读