How to cleanse (overwrite with random bytes) std::string internal buffer?

It is probably safe. But not guaranteed.

However, since C++11, a std::string must be implemented as contiguous data so you can safely access its internal array using the address of its first element &secretString[0].

if(!secretString.empty()) // avoid UB
{
    char* modifiable = &secretString[0];
    OpenSSL_cleanse(modifiable, secretString.size());
}

The standard explicitly says you must not write to the const char* returned by data(), so don't do that.

There are perfectly safe ways to get a modifiable pointer instead:

if (secretString.size())
  OpenSSL_cleanse(&secretString.front(), secretString.size());

Or if the string might have been shrunk already and you want to ensure its entire capacity is wiped:

if (secretString.capacity()) {
  secretString.resize(secretString.capacity());
  OpenSSL_cleanse(&secretString.front(), secretString.size());
}

std::string is a poor choice to store secrets. Since strings are copyable and sometimes copies go unnoticed, your secret may "get legs". Furthermore, string expansion techniques may cause multiple copies of fragments (or all of) your secrets.

Experience dictates a movable, non-copyable, wiped clean on destroy, unintelligent (no tricky copies under-the-hood) class.