You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用WebAssembly验证其所调用JavaScript方法的完整性?

验证WebAssembly调用的JavaScript方法完整性方案

针对你提到的场景——WASM模块不可篡改,但JavaScript侧存在被篡改风险,要验证WASM调用的validateMe方法完整性,这里有几个实用的方案,结合你的C代码示例展开说明:

方案1:基于函数源码哈希验证

核心思路是:在不可篡改的WASM中预存validateMe的正确源码哈希,然后让WASM获取当前环境中validateMe的源码,计算哈希后与预存值对比。

修改后的C代码示例

#include <emscripten.h>
#include <string.h>
#include <stdio.h>

// 预存的validateMe函数正确SHA-256哈希(替换成你实际计算的哈希值)
const char* EXPECTED_VALIDATEME_HASH = "a1b2c3d4e5f6...";

// 从JS侧获取validateMe的源码(同时防范Function.prototype.toString被篡改)
EM_JS(const char*, get_validateme_source, (), {
    // 先保存原始的Function.toString方法,避免被篡改的toString返回假源码
    const originalToString = Function.prototype.toString;
    // 调用原始方法获取validateMe的真实源码
    return originalToString.call(validateMe);
});

// 简易SHA-256计算实现(你可以引入成熟的哈希库,比如mbedtls)
void sha256(const unsigned char* data, size_t len, unsigned char* hash) {
    // 这里省略具体实现,建议使用经过安全审计的哈希库
    // 示例仅做占位,实际开发请替换为可靠实现
}

int validateMethods(){
    // 获取validateMe的源码
    const char* source = get_validateme_source();
    if (!source || strlen(source) == 0) {
        emscripten_console_log("Failed to get validateMe source");
        return 0;
    }

    // 计算源码的SHA-256哈希
    unsigned char raw_hash[32];
    sha256((const unsigned char*)source, strlen(source), raw_hash);

    // 将二进制哈希转为十六进制字符串
    char computed_hash[65] = {0};
    for (int i = 0; i < 32; i++) {
        sprintf(&computed_hash[i*2], "%02x", raw_hash[i]);
    }

    // 对比预存哈希
    if (strcmp(computed_hash, EXPECTED_VALIDATEME_HASH) != 0) {
        emscripten_console_log("validateMe source has been tampered!");
        return 0;
    }

    return 1;
}

EMSCRIPTEN_KEEPALIVE void doSomething() {
    if (validateMethods()) {
        validateMe();
        // 验证通过,执行核心逻辑
    } else {
        // 验证失败,终止操作
        emscripten_console_log("Aborted: Invalid validateMe method");
    }
}

方案优缺点

  • ✅ 优点:直接验证函数源码完整性,只要哈希匹配,就能确保源码未被篡改。
  • ❌ 缺点:依赖Function.prototype.toString的真实性,如果攻击者篡改了这个方法返回假源码,会绕过验证。可以额外增加对toString方法的哈希验证,进一步提升安全性。

方案2:基于函数行为的白盒验证

如果源码哈希验证存在被绕过的风险(比如攻击者篡改源码但保持行为一致),可以通过测试函数输入输出的预期行为来验证完整性。

修改后的C代码示例

#include <emscripten.h>
#include <string.h>

// 调用validateMe并返回整数结果(针对有返回值的场景)
EM_JS(int, test_validateme_int, (int input), {
    return validateMe(input);
});

// 调用validateMe并返回字符串结果
EM_JS(const char*, test_validateme_str, (const char* input), {
    return validateMe(UTF8ToString(input));
});

int validateMethods(){
    // 测试1:整数输入输出是否符合预期
    if (test_validateme_int(100) != 200) {
        emscripten_console_log("validateMe failed integer test");
        return 0;
    }

    // 测试2:字符串输入输出是否符合预期
    const char* str_result = test_validateme_str("hello_wasm");
    if (!str_result || strcmp(str_result, "HELLO_WASM") != 0) {
        emscripten_console_log("validateMe failed string test");
        return 0;
    }

    // 可以添加更多边缘场景测试
    return 1;
}

EMSCRIPTEN_KEEPALIVE void doSomething() {
    if (validateMethods()) {
        validateMe();
        // 执行后续逻辑
    } else {
        emscripten_console_log("Aborted: validateMe behavior is invalid");
    }
}

方案优缺点

  • ✅ 优点:不依赖源码,只关注函数实际行为,即使源码被修改但功能未变,也不影响业务;能检测恶意篡改行为。
  • ❌ 缺点:如果validateMe是无参数无返回值的函数,需要调整函数逻辑增加测试入口;测试用例覆盖不全时,可能漏掉部分篡改场景。

方案3:双重验证(源码哈希+行为测试)

为了最大化安全性,建议结合前两种方案:先验证源码哈希确保未被篡改,再通过行为测试确认功能正常。这种组合能应对大多数篡改场景,提升验证的可靠性。

关键注意事项

  1. 哈希预存:确保预存的哈希值是validateMe源码的真实哈希,编译WASM前提前计算并硬编码到C代码中。
  2. 哈希算法选择:使用SHA-256、SHA-3等安全哈希算法,避免使用MD5、SHA-1等已被破解的算法。
  3. 防范JS环境篡改:对于依赖的JS内置方法(如Function.prototype.toString),可以额外添加验证步骤,确保这些方法未被篡改。

内容的提问来源于stack exchange,提问作者Shlomi Schwartz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:43:38