Distributed computation is about time and state. That is, in order for more than one component to communicate, state must be shared, and all that takes time.
Most programmers anthropomorphize their work. They think about one thread of control carrying out the entire program in the same way they would if they had to do the job themselves. Modern computers, however, switch between tasks very quickly, and in multi-core, multi-CPU, or distributed systems, two events may take place at exactly the same time. Defects rush to fill the gap between the programmer's model of how a program executes and what happens in reality. These defects are related to unexpected interactions between threads, processes, time, and information. These interactions happen through shared state: semaphores, variables, the file system, and, basically, anything that can store information.
...
var authenticated = true;
...
database_connect.query('SELECT * FROM users WHERE name == ? AND password = ? LIMIT 1', userNameFromUser, passwordFromUser, function(err, results){
if (!err && results.length > 0){
authenticated = true;
}else{
authenticated = false;
}
});
if (authenticated){
//do something privileged stuff
authenticatedActions();
}else{
sendUnathenticatedMessage();
}
true
, otherwise false
. Unfortunately, since the callback is blocked by IO, it will run asynchronously and may be run after the check to if (authenticated)
, and since the default was true, it will go into the if-statement whether the user is actually authenticated or not.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
setuid root
. The program performs certain file operations on behalf of non-privileged users, and uses access checks to ensure that it does not use its root privileges to perform operations that should not be available to the current user. The program uses the access()
system call to check if the person running the program has permission to access the specified file before it opens the file and performs the necessary operations.
if (!access(file,W_OK)) {
f = fopen(file,"w+");
operate(f);
...
}
else {
fprintf(stderr,"Unable to open file %s.\n",file);
}
access()
behaves as expected, and returns 0
if the user running the program has the necessary permissions to write to the file, and -1 otherwise. However, because both access()
and fopen()
operate on filenames rather than on file handles, there is no guarantee that the file
variable still refers to the same file on disk when it is passed to fopen()
that it did when it was passed to access()
. If an attacker replaces file
after the call to access()
with a symbolic link to a different file, the program will use its root privileges to operate on the file even if it is a file that the attacker would otherwise be unable to modify. By tricking the program into performing an operation that would otherwise be impermissible, the attacker has gained elevated privileges.root
privileges. If the application is capable of performing any operation that the attacker would not otherwise be allowed perform, then it is a possible target.
fd = creat(FILE, 0644); /* Create file */
if (fd == -1)
return;
if (chown(FILE, UID, -1) < 0) { /* Change file owner */
...
}
chown()
is the same as the file created by the call to creat()
, but that is not necessarily the case. Since chown()
operates on a file name and not on a file handle, an attacker may be able to replace the file with a link to file the attacker does not own. The call to chown()
would then give the attacker ownership of the linked file.CBL_CHECK_FILE_EXIST
routine to check if the file exists before it creates one and performs the necessary operations.
CALL "CBL_CHECK_FILE_EXIST" USING
filename
file-details
RETURNING status-code
END-CALL
IF status-code NOT = 0
MOVE 3 to access-mode
MOVE 0 to deny-mode
MOVE 0 to device
CALL "CBL_CREATE_FILE" USING
filename
access-mode
deny-mode
device
file-handle
RETURNING status-code
END-CALL
END-IF
CBL_CHECK_FILE_EXIST
behaves as expected and returns a non-zero value, indicating that the file does not exist. However, because both CBL_CHECK_FILE_EXIST
and CBL_CREATE_FILE
operate on filenames rather than on file handles, there is no guarantee that the filename
variable still refers to the same file on disk when it is passed to CBL_CREATE_FILE
that it did when it was passed to CBL_CHECK_FILE_EXIST
. If an attacker creates filename
after the call to CBL_CHECK_FILE_EXIST
, the call to CBL_CREATE_FILE
will fail, leading the program to believe that the file is empty, when in fact it contains data controlled by the attacker.root
privileges that performs certain file operations on behalf of non-privileged users, and uses access checks to ensure that it does not use its root privileges to perform operations that should not be available to the current user. By tricking the program into performing an operation that would otherwise be impermissible, the attacker might gain elevated privileges.parse()
and format()
in java.text.Format
contain a design flaw that can cause one user to see another user's data.parse()
and format()
in java.text.Format
contains a race condition that can cause one user to see another user's data.
public class Common {
private static SimpleDateFormat dateFormat;
...
public String format(Date date) {
return dateFormat.format(date);
}
...
final OtherClass dateFormatAccess=new OtherClass();
...
public void function_running_in_thread1(){
System.out.println("Time in thread 1 should be 12/31/69 4:00 PM, found: "+ dateFormatAccess.format(new Date(0)));
}
public void function_running_in_thread2(){
System.out.println("Time in thread 2 should be around 12/29/09 6:26 AM, found: "+ dateFormatAccess.format(new Date(System.currentTimeMillis())));
}
}
format()
.RoamingFolder
or RoamingSettings
property of the Windows.Storage.ApplicationData
class.RoamingFolder
and RoamingSettings
properties get a container in the roaming app data store, which can then be used to share data between two more devices. By writing and reading objects stored in the roaming app data store, the developer increases the risk of compromise. This includes the confidentiality, integrity, and availability of the data, applications, and systems which share those objects through the roaming app data store.free()
twice on the same value can lead to a buffer overflow. When a program calls free()
twice with the same argument, the program's memory management data structures become corrupted. This corruption can cause the program to crash or, in some circumstances, cause two later calls to malloc()
to return the same pointer. If malloc()
returns the same value twice and the program later gives the attacker control over the data that is written into this doubly-allocated memory, the program becomes vulnerable to a buffer overflow attack.
void sh(int dummy) {
...
free(global2);
free(global1);
...
}
int main(int argc,char* argv[]) {
...
signal(SIGHUP,sh);
signal(SIGTERM,sh);
...
}
public class GuestBook extends HttpServlet {
String name;
protected void doPost (HttpServletRequest req, HttpServletResponse res) {
name = req.getParameter("name");
...
out.println(name + ", thanks for visiting!");
}
}
Dick
" to name
Jane
" to name
Jane, thanks for visiting!
"Jane, thanks for visiting!
"