Plain logs in .bin file

rocotocloc
Posts: 23
Joined: Tue May 07, 2024 5:47 am

Plain logs in .bin file

Postby rocotocloc » Tue May 20, 2025 9:23 am

Hello,

Consider the next simple program that just connects to a wifi network and open an HTTPS connection for testing purposes:

Code: Select all

/*
 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: CC0-1.0
 */

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include <esp_log.h>
#include "esp_http_client.h"
#include <esp_wifi_types.h>
#include <esp_wifi.h>
#include "esp_crt_bundle.h"
#include "nvs.h"
#include "nvs_flash.h"

static const char *FIRMWARE_REMOTE_UPGRADE_URL = "https://www.lavnetremote.com/rest/utils/download-firmware?fileToDownload=MY-FIRMWARE.bin&username=MY-USERNAME&password=MY-PASSWORD";
static const int FIRMWARE_REMOTE_UPGRADE_TIMEOUT = 5000; // 5 seconds
static const char *TAG = "test-http";

static void ip_event_handler(void *arg, esp_event_base_t event_base,
                             int32_t event_id, void *event_data)
{
    if (event_id == IP_EVENT_STA_GOT_IP)
    {
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
    }
}

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data)
{
    if (event_id == WIFI_EVENT_STA_START)
    {
        ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
    }
    else if (event_id == WIFI_EVENT_STA_CONNECTED)
    {
        ESP_LOGI(TAG, "sta connected to ssid");

        vTaskDelay(3000 / portTICK_PERIOD_MS);

        esp_http_client_config_t config = {
            .url = FIRMWARE_REMOTE_UPGRADE_URL,
            .crt_bundle_attach = esp_crt_bundle_attach,
            .timeout_ms = FIRMWARE_REMOTE_UPGRADE_TIMEOUT,
            .keep_alive_enable = true,
        };

        esp_http_client_handle_t client = esp_http_client_init(&config);
        if (client == NULL)
        {
            ESP_LOGE(TAG, "Failed to initialise HTTP connection");
        }
        esp_err_t err = esp_http_client_open(client, 0);
        if (err != ESP_OK)
        {
            ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
        }
        esp_http_client_fetch_headers(client);
    }
    else if (event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        ESP_LOGI(TAG, "connect to the AP failed");
    }
}

static void init_nvs(void)
{
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);

    nvs_handle_t handle;
    ESP_ERROR_CHECK(nvs_open("NVS_NAMESPACE", NVS_READWRITE, &handle));
}

static void init_wifi(void)
{
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_init());
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_loop_create_default());
    esp_netif_t *sta = esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_instance_register(WIFI_EVENT,
                                                                      ESP_EVENT_ANY_ID,
                                                                      &wifi_event_handler,
                                                                      NULL,
                                                                      NULL));
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_instance_register(IP_EVENT,
                                                                      IP_EVENT_STA_GOT_IP,
                                                                      &ip_event_handler,
                                                                      NULL,
                                                                      NULL));

    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_start());

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = "wifi-ssid",
            .password = "wifi-password",
        },
    };
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcpc_start(sta));
    esp_wifi_connect();
}

void app_main(void)
{
    init_nvs();
    init_wifi();
}

This works fine but I have the following problem.

As you can see the URL has embedded the user and password for server verification:

Code: Select all

static const char *FIRMWARE_REMOTE_UPGRADE_URL = "https://www.lavnetremote.com/rest/utils/download-firmware?fileToDownload=MY-FIRMWARE.bin&username=MY-USERNAME&password=MY-PASSWORD";
The problem is the generated .bin file contains some kind of logs at the beginning with the result of a failing connection and someone could reveal the user and password.

I've tried to set log level to NONE or playing with the ".username" and ".password" properties of the http connection but the URL with this data is still in the .bin file.

Could you please let me know how to handle this?

Thank you.
Attachments
test-http-bin-file.zip
(581.43 KiB) Downloaded 11 times
2025-05-20 11 19 00.png
2025-05-20 11 19 00.png (82.14 KiB) Viewed 120 times

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Plain logs in .bin file

Postby MicroController » Tue May 20, 2025 1:50 pm

The problem is the generated .bin file contains some kind of logs at the beginning with the result of a failing connection and someone could reveal the user and password.
Well, not quite. That section of the .bin contains, in no particular order, all string constants/literals used anywhere in the application, including strings used in log messages and your URL string. The URL string being located near logging strings in the .bin doesn't mean that the URL is used in any log messages. (You should find at least one byte of 0x00 between the URL and the surrounding strings.)

rocotocloc
Posts: 23
Joined: Tue May 07, 2024 5:47 am

Re: Plain logs in .bin file

Postby rocotocloc » Tue May 20, 2025 3:01 pm

Thank you MicroController.

Yes, you're right, just trying to understand what's really included in the .bin file.

Any ideas on how to overcome this? I mean I want to hide somehow the credentials in the .bin file because I will be distributing this .bin file to final users so they can update through OTA (using UART or local wifi in facilities with no Internet access to perform HTTPS OTA)

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Plain logs in .bin file

Postby MicroController » Tue May 20, 2025 3:42 pm

You could encrypt the .bin file prior to distribution and decrypt it on the ESP during OTA.
You could also statically 'encrypt' only the URL string and 'decrypt' it to RAM at runtime ("obfuscation"). Not very secure (everything required for the 'decryption' (code + any 'key') would also be in the .bin file somewhere), but it prevents the secret from being easily spotted at a cursory glance.

rocotocloc
Posts: 23
Joined: Tue May 07, 2024 5:47 am

Re: Plain logs in .bin file

Postby rocotocloc » Wed May 21, 2025 5:15 am

Thanks a lot for the help, I'll dig into the encryption topic.

Who is online

Users browsing this forum: DuckDuckGo [Bot], Google [Bot] and 1 guest