Developer:security

From Wzdftpd

Jump to: navigation, search

Contents


Work In Progress

Threats

This is just an overview of the most commonly used vulnerabilities. As a worker and researcher in security, the author believes that any error like a crash or a dangling pointer can be exploited and thus must be considered as a security problem.

Buffer overflows

This is the most common problem when programming in C.

Format vulnerabilities

Input manipulation

  • SQL injections
  • Shell injections

Exemple: popen() and similar

  • etc.

Double free

Denials of service using resources leaks

  • memory leaks
  • file descriptor leaks

Multithread problems

  • concurrent access

Initial value: i = 0;

Thread 1:

i = i + 1;

Thread 2:

if (i-- > 0)
  do_some_action(i);

-> possible interaction: the behaviour is unpredictable. The only solution is to use a mutex.

  • Time of check, time of use (TOCTOU)
if (!access(fname,W_OK))
  f = fopen(fname,"w+);

-> this is a typical race condition

  • double lock
  • deadlock
  • sleeping in a lock

Parts of solution

An FTP server is a critical application, so there is no place for errors. Yet everybody makes errors, so some actions must be taken:

Document your code

At the time your write the code, it may (and really should) be clear for you. This won't necessarily be the case a few weeks after, or when other people will read it.

The code itself must be easy to read (function names must be meaningful, as well as variables). Avoid 1000-lines functions (this means your code was not thought properly), and write comments to give a clear overview of what the code does and the important points if needed.

To be extended in a real code quality section

Write unit tests

A unit test is a procedure used to verify that a particular module of source code is working properly. The idea about unit tests is to write test cases for all functions and methods so that whenever a change causes a regression, it can be quickly identified and fixed. Ideally, each test case is separate from the others; constructs such as mock objects can assist in separating unit tests.

Automated tests are here to help ! Use them to test all functions, for every possible path in the code (this can be evaluated as the code test coverage). Unit tests will spare you many hours if you decide to change the parameters or the behaviour of a function without really understanding the consequences of your changes (thus causing regressions). It can also help to ensure the portability of your code, since even standard functions like snprintf can work differently on different platforms.

Review code

To ensure the quality, the code must be reviewed. It should be reviewed by different people, as each person has its own way of understanding things.

When you review the code, add a mention on the top of the file (just after the license) to indicate that the code has been read and found ok. This is not an absolute indicator of quality, but will greatly help. Exemple: /* reviewed by your_name Jul, 21 2005 */.

Check your code

Code analysis can be done on different levels:

  • static analysis, using tools like rats, splint. This kinf of analysis is very limited.
  • runtime analysis, using memory checkers or debuggers. The most important tools here are gdb (and frontends) and valgrind.

Some completely different tests should also be done regularly:

  • stress the server using tools like dkftpbench or hand-written tools, in order to check that the server is working correctly under hard conditions. This is often done in conjunction with runtime analysis tools, since the specific conditions will likely reveal any bug which would not appear in simple tests.

And finally, even if it may seem trivial: use your work. Using a program on a daily basis is a different thing than running a few tests on it.

--pollux 00:05, 21 January 2006 (CET)

Personal tools
documentation