传递给第三方 API 时的 C++ const std:string& 安全性

Posted

技术标签:

【中文标题】传递给第三方 API 时的 C++ const std:string& 安全性【英文标题】:C++ const std:string& security when passing to a third-party API 【发布时间】:2016-04-01 22:29:19 【问题描述】:

我有一个第三方 API,希望我通过引用传递 std::string。它说它正在接受const。这几乎没有任何意义,因为它可以将内存指针转换为非常量 char* 并修改我的字符串。

通过示例检查下面的代码。

我是否应该担心/怀疑第三方 API 要求我传递 const std::string&(通过 const 引用)而不是 std::string(通过值)?

他们告诉我这是因为他们想避免字符串复制,因为字符串可能很长。我是偏执狂还是有道理?

class Blah 

public:
    static void testBlah(const string& s) 
        char* blah = (char*) s.c_str(); // cast away from const char*
        blah[1] = 'b';
    
;

int main() 

    cout << "!!!Hello There !!!" << endl; // prints !!!Hello World!!!

    const string s = "xxx"; // NOTE THE CONST !!!

    Blah::testBlah(s);

    cout << s << endl; // prints "xbx"

    return 0;

【问题讨论】:

Const correctness 在 C++ 中很重要。如果一个函数说它需要一个参数作为常量,那么你必须相信它。如果它做了一些愚蠢的事情,比如抛弃恒定性并修改数据,它将导致未定义的行为并破坏整个程序。如果发生这种情况,您应该大声向函数/库的创建者大喊(最好公开地),然后立即停止使用它。 不要在我们的计算机上执行您不信任的代码。 API 请求 CONST 引用,因此它们可能不会更改您的字符串,但如果您不信任它们,您可以在代码中复制字符串并将其传递给函数. C++ 本质上不是类型安全的,因此 API 理论上可以对你给它的东西做很多讨厌的事情。但是,如果 API 说它通过 const 引用接受参数,则您必须信任它或执行@Sandro 建议的操作。直言不讳,我确实认为您对此有点偏执。 @Sandro 至少这次是个好问题 :) 随意投票:P 【参考方案1】:

只需将其包装在您自己的受信任类中即可:

#include <iostream>

class Blah 

public:
    static void testBlah(const std::string& s)
    
        char* blah = (char*)s.c_str(); // cast away from const char*
        blah[1] = 'b';
    
;

class Safe_Blah 
public:
    static void testBlah(const std::string s)
    
        Blah::testBlah(s);
    
;

int main()


    std::cout << "!!!Hello There !!!" << std::endl; // prints !!!Hello World!!!

    const std::string s = "xxx"; // NOTE THE CONST !!!

    //Blah::testBlah(s);
    Safe_Blah::testBlah(s);

    std::cout << s.c_str() << std::endl; // now prints "xxx"

    return 0;

【讨论】:

这几乎是在做@Sandro 在 cmets 中建议的事情,对吧?可能最好只是在将字符串传递给 API 时克隆它。 这有什么帮助?假设 API 函数在可访问的进程内存中搜索相同字符串数据的其他副本并修改它们。 @DavidSchwartz 哦,天哪,我没想到...请向我保证,你只会永远使用你的力量。【参考方案2】:

接受const&amp; 对象的API 承诺不修改该对象。虽然,是的,图书馆可能是邪恶的并且无论如何都要修改它,但这样做会违背承诺。如果您传递给它的对象被定义为const,那么修改它将是未定义的行为。从库开发人员的角度来看,这将是非常糟糕的。基本上,图书馆开发人员会邀请 Chutulhu 来以任意、随机、未指定和不可预测的方式破坏他们的用户应用程序。

说到不信任你的图书馆,你就输了。就控制您调用的库的攻击者的安全性而言,C++ API 以任何可以想象的方式都不是“安全的”。当您调用库中的函数时,您会将执行控制权传递给该库。然后,该库将有权读取和写入您的应用程序的所有内存,并且如果它选择了,可以用它自己的东西替换整个内存。所以如果你担心图书馆在你背后做坏事,那你就很倒霉了。

【讨论】:

以上是关于传递给第三方 API 时的 C++ const std:string& 安全性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中将 id 从另一个 const 传递给另一个 const?

通过引用传递使用 const 有啥意义? C++ [重复]

Python 的 C API 的 const 正确性

将 std::string_view 传递给执行 const std::string& 的 API

如何使用 swig 将 const 字符串参数从 perl 传递到 c++

小白学习C++ 教程八在C++指针传递引用和Const关键字