☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

敏感数据不可被系统外界感知

1.2 ID_secretLeak
目录 › next › previous

敏感数据出入软件系统时需采用有效的保护措施。

示例:

void foo(User* u) {
    log("username: %s, password: %s", u->name, u->pw);   // Non-compliant
}

显然,将敏感数据直接输出到界面、日志或其他外界可感知的介质中是不安全的,需避免敏感数据的有意外传,除此之外,还需要落实具体的保护措施。

保护措施包括但不限于:

  • 避免用明文或弱加密方式传输敏感数据
  • 避免敏感数据从内存交换到外存
  • 避免敏感数据写入内存转储文件
  • 应具备反调试机制,使外界无法获得程序的内部数据
  • 应具备反注入机制,使外界无法篡改程序的行为

下面以 Windows 平台为例,给出阻止敏感数据从内存交换到外存的示例:

class SecretBuf {
    size_t len = 0;
    unsigned char* buf = nullptr;

public:
    SecretBuf(size_t size) {
        auto* tmp = (unsigned char*)VirtualAlloc(
            0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE
        );
        if (VirtualLock(tmp, size)) {   // The key point
            buf = tmp;
            len = size;
        } else {
            VirtualFree(tmp, 0, MEM_RELEASE);
        }
    }

   ~SecretBuf() {
        SecureZeroMemory(buf, len);   // Clear the secret content
        VirtualUnlock(buf, len);
        VirtualFree(buf, 0, MEM_RELEASE);
        len = 0;
        buf = nullptr;
    }

    size_t size() const { return len; }
    unsigned char* ptr() { return buf; }
    const unsigned char* ptr() const { return buf; }
};

例中 SecretBuf 是一个缓冲区类,其申请的内存会被锁定在物理内存中,不会与外存交换,可在一定程度上防止其他进程的恶意嗅探,保障缓冲区内数据的安全。SecretBuf 在构造函数中通过 VirtualLock 锁定物理内存,在析构函数中通过 VirtualUnlock 解除锁定,解锁之前有必要清除数据,否则解锁之后残留数据仍有可能被交换到外存,进一步可参见 ID_unsafeCleanup。

SecretBuf 的使用方法如下:

void foo() {
    SecretBuf buf(256);
    if (buf.ptr()) {
        ....             // Do something secret using buf.ptr()
    } else {
        ....             // Handle memory error
    }
}

在 Linux 等系统中可参见如下有相似功能的接口:

int mlock(const void* addr, size_t len);     // In <sys/mman.h>
int munlock(const void* addr, size_t len);
int mlockall(int flags);
int munlockall(void);

相关

ID_unsafeCleanup

参考

CWE-528 CWE-591 SEI CERT MEM06-C
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.