5 文件操作

5.1 【必须】避免路径穿越问题

在进行文件操作时,需要判断外部传入的文件名是否合法,如果文件名中包含 ../ 等特殊字符,则会造成路径穿越,导致任意文件的读写。

错误:

  1. void Foo() {
  2. char file_path[PATH_MAX] = "/home/user/code/";
  3. // 如果传入的文件名包含../可导致路径穿越
  4. // 例如"../file.txt",则可以读取到上层目录的file.txt文件
  5. char name[20] = "../file.txt";
  6. memcpy(file_path + strlen(file_path), name, sizeof(name));
  7. int fd = open(file_path, O_RDONLY);
  8. if (fd != -1) {
  9. char data[100] = {0};
  10. int num = 0;
  11. memset(data, 0, sizeof(data));
  12. num = read(fd, data, sizeof(data));
  13. if (num > 0) {
  14. write(STDOUT_FILENO, data, num);
  15. }
  16. close(fd);
  17. }
  18. }

正确:

  1. void Foo() {
  2. char file_path[PATH_MAX] = "/home/user/code/";
  3. char name[20] = "../file.txt";
  4. // 判断传入的文件名是否非法,例如"../file.txt"中包含非法字符../,直接返回
  5. if (strstr(name, "..") != NULL){
  6. // 包含非法字符
  7. return;
  8. }
  9. memcpy(file_path + strlen(file_path), name, sizeof(name));
  10. int fd = open(file_path, O_RDONLY);
  11. if (fd != -1) {
  12. char data[100] = {0};
  13. int num = 0;
  14. memset(data, 0, sizeof(data));
  15. num = read(fd, data, sizeof(data));
  16. if (num > 0) {
  17. write(STDOUT_FILENO, data, num);
  18. }
  19. close(fd);
  20. }
  21. }

关联漏洞:

高风险-逻辑漏洞

5.2 【必须】避免相对路径导致的安全问题(DLL、EXE劫持等问题)

在程序中,使用相对路径可能导致一些安全风险,例如DLL、EXE劫持等问题。

例如以下代码,可能存在劫持问题:

  1. int Foo() {
  2. // 传入的是dll文件名,如果当前目录下被写入了恶意的同名dll,则可能导致dll劫持
  3. HINSTANCE hinst = ::LoadLibrary("dll_nolib.dll");
  4. if (hinst != NULL) {
  5. cout<<"dll loaded!" << endl;
  6. }
  7. return 0;
  8. }

针对DLL劫持的安全编码的规范:

1)调用LoadLibrary,LoadLibraryEx,CreateProcess,ShellExecute等进行模块加载的函数时,指明模块的完整(全)路径,禁止使用相对路径,这样就可避免从其它目录加载DLL。 2)在应用程序的开头调用SetDllDirectory(TEXT(“”)); 从而将当前目录从DLL的搜索列表中删除。结合SetDefaultDllDirectories,AddDllDirectory,RemoveDllDirectory这几个API配合使用,可以有效的规避DLL劫持问题。这些API只能在打了KB2533623补丁的Windows7,2008上使用。

关联漏洞:

中风险-逻辑漏洞

5.3 【必须】文件权限控制

在创建文件时,需要根据文件的敏感级别设置不同的访问权限,以防止敏感数据被其他恶意程序读取或写入。

错误:

  1. int Foo() {
  2. // 不要设置为777权限,以防止被其他恶意程序操作
  3. if (creat("file.txt", 0777) < 0) {
  4. printf("文件创建失败!\n");
  5. } else {
  6. printf("文件创建成功!\n");
  7. }
  8. return 0;
  9. }

关联漏洞:

中风险-逻辑漏洞