CWE Rule 922
Description
Rule Description
The software stores sensitive information without properly limiting read or write access by unauthorized actors.
Polyspace Implementation
The rule checker checks for these issues:
File manipulation after chroot() without chdir("/")
Umask used with chmod-style arguments
Use of non-secure temporary file
Vulnerable permission assignments
Examples
File manipulation after chroot() without chdir("/")
This issue occurs when you have access to a file system outside of the jail created by
chroot
. By calling chroot
, you create a file
system jail that confines access to a specific file subsystem. However, this jail is
ineffective if you do not call chdir("/")
.
If you do not call chdir("/")
after creating
a chroot
jail, file manipulation functions that
takes a path as an argument can access files outside of the jail.
An attacker can still manipulate files outside the subsystem that
you specified, making the chroot jail ineffective.
After calling chroot
, call chdir("/")
to
make your chroot
jail more secure.
#include <unistd.h> #include <stdio.h> const char root_path[] = "/var/ftproot"; const char log_path[] = "file.log"; FILE* chrootmisuse() { FILE* res; chroot(root_path); chdir("base"); //Noncompliant res = fopen(log_path, "r"); //Noncompliant return res; }
This example uses chroot
to create a chroot-jail.
However, to use the chroot
jail securely, you must
call chdir("\")
afterward. This example calls chdir("base")
,
which is not equivalent. Bug Finder also flags fopen
because fopen
opens
a file in the vulnerable chroot
-jail.
chdir("/")
Before opening files, call chdir("/")
.
#include <unistd.h> #include <stdio.h> const char root_path[] = "/var/ftproot"; const char log_path[] = "file.log"; FILE* chrootmisuse() { FILE* res; chroot(root_path); chdir("/"); res = fopen(log_path, "r"); return res; }
Umask used with chmod-style arguments
This issue occurs when umask
commands have arguments specified in the
style of arguments to chmod
and provide
possibly unintended permissions. For instance:
The
umask
command provides more permissions to the group than the current user.The
umask
command provides more permissions to other users than the group.
For new files, the umask
argument or the mask value specifies which
permissions not to set, in other words,
which permissions to remove. The mask is bitwise-negated and
then applied to new file permissions. In contrast,
chmod
sets the permissions as you
specify them.
If you use chmod
-style arguments, you specify opposite permissions of what
you want. This mistake can give external users
unintended read/write access to new files and
folders.
To fix this defect, perform both of these tasks:
Enable read permission for the user.
Set the mask value so that the user (
u
) has equal or fewer permissions turned off than the group (g
) and the group has equal or fewer permissions turned off than other users (o
), oru <= g <= o
.
You can see the umask value by calling,
umask
umask -S
#include <stdio.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> typedef mode_t (*umask_func)(mode_t); const mode_t default_mode = ( S_IRUSR /* 00400 */ | S_IWUSR /* 00200 */ | S_IRGRP /* 00040 */ | S_IWGRP /* 00020 */ | S_IROTH /* 00004 */ | S_IWOTH /* 00002 */ ); /* 00666 (i.e. -rw-rw-rw-) */ static void my_umask(mode_t mode) { umask(mode); //Noncompliant } int umask_use(mode_t m) { my_umask(default_mode); return 0; }
This example uses a function called my_umask
to
set the default mask mode. However, the default_mode
variable
gives the permissions 666 or -rw-rw-rw
. umask
negates
this value. However, this negation means the default mask mode turns
off read/write permissions for the user, group users, and other outside
users.
One possible correction is to negate the default_mode
argument
to my_umask
. This correction nullifies the negation umask
for
new files.
#include <stdio.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> typedef mode_t (*umask_func)(mode_t); const mode_t default_mode = ( S_IRUSR /* 00400 */ | S_IWUSR /* 00200 */ | S_IRGRP /* 00040 */ | S_IWGRP /* 00020 */ | S_IROTH /* 00004 */ | S_IWOTH /* 00002 */ ); /* 00666 (i.e. -rw-rw-rw-) */ static void my_umask(mode_t mode) { umask(mode); } int umask_use(mode_t m) { my_umask(~default_mode); return 0; }
Use of non-secure temporary file
This issue occurs when you use temporary file routines that are not secure.
If an attacker guesses the file name generated by a standard temporary file routine, the attacker can:
Cause a race condition when you generate the file name.
Precreate a file of the same name, filled with malicious content. If your program reads the file, the attacker’s file can inject the malicious code.
Create a symbolic link to a file storing sensitive data. When your program writes to the temporary file, the sensitive data is deleted.
To create temporary files, use a more secure
standard temporary file routine, such as mkstemp
from
POSIX.1-2001.
Also, when creating temporary files with routines that allow
flags, such as mkostemp
, use the exclusion flag O_EXCL
to
avoid race conditions.
#define _BSD_SOURCE #define _XOPEN_SOURCE #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int test_temp() { char tpl[] = "abcXXXXXX"; char suff_tpl[] = "abcXXXXXXsuff"; char *filename = NULL; int fd; filename = tempnam("/var/tmp", "foo_"); if (filename != NULL) { printf("generated tmp name (%s) in (%s:%s:%s)\n", filename, getenv("TMPDIR") ? getenv("TMPDIR") : "$TMPDIR", "/var/tmp", P_tmpdir); fd = open(filename, O_CREAT, S_IRWXU|S_IRUSR); //Noncompliant if (fd != -1) { close(fd); unlink(filename); return 1; } } return 0; }
In this example, Bug Finder flags open
because
it tries to use an unsecure temporary file. The file is opened without
exclusive privileges. An attacker can access the file causing various risks.
O_EXCL
FlagOne possible correction is to add the O_EXCL
flag
when you open the temporary file.
#define _BSD_SOURCE #define _XOPEN_SOURCE #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int test_temp() { char tpl[] = "abcXXXXXX"; char suff_tpl[] = "abcXXXXXXsuff"; char *filename = NULL; int fd; filename = tempnam("/var/tmp", "foo_"); if (filename != NULL) { printf("generated tmp name (%s) in (%s:%s:%s)\n", filename, getenv("TMPDIR") ? getenv("TMPDIR") : "$TMPDIR", "/var/tmp", P_tmpdir); fd = open(filename, O_CREAT|O_EXCL, S_IRWXU|S_IRUSR); if (fd != -1) { close(fd); unlink(filename); return 1; } } return 0; }
Vulnerable permission assignments
This issue occurs when functions that can change resource permissions, such as
chmod
, umask
, creat
, or
open
, specify permissions that allow unintended actors to modify
or read the resource.
If you give outside users or outside groups a wider range or permissions than required, you potentially expose your sensitive information and your modifications. This defect is especially dangerous for permissions related to:
Program configurations
Program executions
Sensitive user data
Set your permissions so that the user (u
)
has more permissions than the group (g
), and so
the group has more permissions than other users (o
),
or u >= g >= o
.
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> void bug_dangerouspermissions(const char * log_path) { mode_t mode = S_IROTH | S_IXOTH | S_IWOTH; int fd = creat(log_path, mode); //Noncompliant if (fd) { write(fd, "Hello\n", 6); } close(fd); unlink(log_path); }
In this example, the log_path
file is created
with more rights for the other outside users, than the current user.
The permissions are ---------rwx
.
One possible correction is to modify the user permissions for the file. In this correction, the user has read/write/execute permissions, but other users do not.
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> void corrected_dangerouspermissions(const char * log_path) { mode_t mode = S_IRUSR | S_IXUSR | S_IWUSR; int fd = creat(log_path, mode); if (fd) { write(fd, "Hello\n", 6); } close(fd); unlink(log_path); }
Check Information
Category: Others |
Version History
Introduced in R2023a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)