Difference between revisions of "Secure programming"

From Lazarus wiki
Jump to navigationJump to search
m
Line 1: Line 1:
 
== General Info ==
 
== General Info ==
When developing a program, most likely that it will interact with the user in some way, even if that mean only reading files in the system and report the data.
+
When developing a program, it is likely that it will interact with the user in some way, even if that means only reading files in the system and reporting the data.
  
Usually at schools and at university's when one start to write programs, that person learn how to receive input, while teachers usually say to that person “assume that the data you receive is valid�?. Thats when the problems begin.
+
Usually at schools and at universities when one starts to write programs, that person learns how to receive input, while teachers usually say to that person “assume that the data you receive is valid�?. That's when the problems begin.
  
From the second that a program receives an input, we can not trust any unknown input that we can not control it.  
+
From the second that a program receives an input, we can not trust any unknown input that we can not control.  
  
 
Reading from a file is an untrusted input, and so does reading users input, or accepting input from a network for example.
 
Reading from a file is an untrusted input, and so does reading users input, or accepting input from a network for example.
Line 13: Line 13:
 
An input can be from a key stroke, and mouse movement or mouse button clicks, or from reading and accepting information from many other ways like a data stream or even system functions.
 
An input can be from a key stroke, and mouse movement or mouse button clicks, or from reading and accepting information from many other ways like a data stream or even system functions.
  
It does not matter what is the type of input, because the user can give us wrong input, and the reasons can be intentionally or by mistake. You can not control this input, and the main reason is that you can't guess what will be the input that the user will provide.
+
It does not matter what is the type of input, because the user can give us wrong input, and the reasons can be intentional or a mistake. You can not control this input, and the main reason is that you can't guess what will the input be.
  
The result could be an empty (NULL) “data�? that the user provide us, an out of range number or bigger amount of chars we expected, or even an attempt to change the address of the variable that accept the input from the user. We just can not know what will the user is going to do to us.
+
The result could be an empty (NULL) “data�? that the user provide us, an out of range number or bigger amount of chars we expected, or even an attempt to change the address of the variable that accepts the input from the user. We just can not know what the user is going provide.
  
 
Any “unsafe�? handle of the user input can cause for retrieving vital information that the user must not accept, and could not accept, or modification of data that the user could not do any other way, or even break the program itself.
 
Any “unsafe�? handle of the user input can cause for retrieving vital information that the user must not accept, and could not accept, or modification of data that the user could not do any other way, or even break the program itself.
Line 37: Line 37:
 
In this example we can see that for the open array of iNums we gave the ability to accept only 10 numbers, while we entered to the variable a content of 21 numbers.
 
In this example we can see that for the open array of iNums we gave the ability to accept only 10 numbers, while we entered to the variable a content of 21 numbers.
  
If the user will try to execute an arbitrary code in one of our attempts he or she will succeed in doing so, because we went outside the buffer that was given to us. And thats a buffer overflow.
+
If the user will try to execute an arbitrary code in one of our attempts he or she will succeed in doing so, because we went outside the buffer that was given to us. And that's a buffer overflow.
  
 
====DoS Attack====
 
====DoS Attack====
Line 48: Line 48:
 
       Recurse;<br>
 
       Recurse;<br>
 
     '''end''';<br>
 
     '''end''';<br>
  '''end'''; <br>
+
  '''end'''; <br>
  
This procedure will run until the system will be out of resources to allocate more stack memory to run, and will cause the system to stop responding, or even to crush.
+
This procedure will run until the system will be out of resources to allocate more stack memory to run, and will cause the system to stop responding, or even to crash.
Alto some systems like Linux, will try to give you the ability to stop running the program, it will take a lot of time from you to do it.
+
Altho some systems like Linux, will try to give you the ability to stop running the program, it will take a lot of time from you to do it.
  
 
Please note that this is also a static example only, but we made a DoS attack on a system that will run the code.
 
Please note that this is also a static example only, but we made a DoS attack on a system that will run the code.
Line 66: Line 66:
 
         OurPtr := Something;<br>
 
         OurPtr := Something;<br>
 
     '''end''';<br>
 
     '''end''';<br>
'''end'''.<br>
+
  '''end'''.<br>
  
This example display a memory allocation (Getmem is like the C malloc), but we exist the execution without freeing the memory at the end of it's use.
+
This example displays a memory allocation (Getmem is like the C malloc), but we exit the execution without freeing the memory at the end of it's use.

Revision as of 18:51, 4 March 2005

General Info

When developing a program, it is likely that it will interact with the user in some way, even if that means only reading files in the system and reporting the data.

Usually at schools and at universities when one starts to write programs, that person learns how to receive input, while teachers usually say to that person “assume that the data you receive is valid�?. That's when the problems begin.

From the second that a program receives an input, we can not trust any unknown input that we can not control.

Reading from a file is an untrusted input, and so does reading users input, or accepting input from a network for example.

Why can't I trust an input ?

In order to understand why an input is dangerous, we first need to understand what is an input.

An input can be from a key stroke, and mouse movement or mouse button clicks, or from reading and accepting information from many other ways like a data stream or even system functions.

It does not matter what is the type of input, because the user can give us wrong input, and the reasons can be intentional or a mistake. You can not control this input, and the main reason is that you can't guess what will the input be.

The result could be an empty (NULL) “data�? that the user provide us, an out of range number or bigger amount of chars we expected, or even an attempt to change the address of the variable that accepts the input from the user. We just can not know what the user is going provide.

Any “unsafe�? handle of the user input can cause for retrieving vital information that the user must not accept, and could not accept, or modification of data that the user could not do any other way, or even break the program itself.

What type of problems can we expect ?

On every type of bug you probably will find a type of attack, but I wish to give a small list of very common type of attacks, instead of writing a lot of the attack types.

The most common attack types are:

Buffer Overflow

When a given data overflows the amount of memory that was allocated for it:

var
iNums : array of integer;
....
SetLength (iNums, 10);
FillChar (iNums[-1], 100, #0); ....
for i := -10 to 10 do
readln (iNums[i]);
....

In this example we can see that for the open array of iNums we gave the ability to accept only 10 numbers, while we entered to the variable a content of 21 numbers.

If the user will try to execute an arbitrary code in one of our attempts he or she will succeed in doing so, because we went outside the buffer that was given to us. And that's a buffer overflow.

DoS Attack

Denial of Service is not only a network problem, but can exists also in many other way:

procedure Recurse;
begin
while (True) do
begin
Recurse;
end;
end;

This procedure will run until the system will be out of resources to allocate more stack memory to run, and will cause the system to stop responding, or even to crash. Altho some systems like Linux, will try to give you the ability to stop running the program, it will take a lot of time from you to do it.

Please note that this is also a static example only, but we made a DoS attack on a system that will run the code.


Another known DoS attack is the lack of freeing system resources such as memory, sockets, file descriptors etc...

For example:

 ...
begin
while (True) do
begin
Getmem (OurPtr, 10);
OurPtr := Something;
end;
end.

This example displays a memory allocation (Getmem is like the C malloc), but we exit the execution without freeing the memory at the end of it's use.