--------- [ Programming and Programming Securely. ] ----------
    (Written for flippersmack #14 (www.flippersmack.com))
                        7/31/2001.

Every  programmer  has  to  have something to program, whether
it's work related, hobby related, for a friend, or even just a
quick  script  for  an automation.  We will discuss hobby pro-
gramming.

When  sitting  at home and pondering upon ideas to program you
sometimes  get stumped and feel halted.  This is a term in the
programming  world  called "coders block", yes... exactly like
a "writers block".  I can speak from experience and from other
documentation  on steps to overcome this block, I will try and
combine the both.
 
The  first  thing  to  do is get focused, you don't want to be
distracted  while  trying  to  program.  Keep your environment
quiet  or  even  put on some music to your liking that doesn't
get  you singing along... the slightest things can get us side
tracked  and  off  course.   A  lot  of coders create a coding
play-list, like myself.  Furthermore the time of day you chose
to  program  is  a big part as well.  From experience I do not
like to program when I get off work or get in from a long day,
instead  I  like to program when I wake up after eating break-
fast  and  have started a fresh day.  So if you're starting or
working  on  a big project, try and schedule in worthy time to
code.  After you have got all this situated it is now time for
step 2, finding something to program.

Remember  that  programming  is  an art and is only limited to
your  imagination  and programming skills.  If you have coders
block try and create a list of situations you have encountered
in  which  a tool did not exist for what was needed.  Once you
have thought of something don't stop adding ideas, you can add
several  and  the  next  time  you are in need of something to
program  you  can  go back and find previous self suggestions.
If you still can't think of anything, like a lot of us do time
to  time then just go search freshmeat.net and read the latest
released  projects and even search the previous released.  Try
and  spawn  a  totally new idea.  If a paper could help expand
your  imagination  then  no  one  would  ever  be in search of
projects.

Once  you  have  created  an idea, the next step is to chose a
programming  language.  I  can not tell you what to chose, but
when I chose a language I think of:
 1. How fast does the program need to be.
 2. How much data is actually user/client supplied.
 3. How much regular expression and parsing will it need.
 4. How secure does it need to be, (s*id/daemon?).
 
After  I compile a list I go from there.  I like to program in
C  when  the  software needs to be fast and secure, especially
for  daemon/client  type  software.  I also like to program in
Perl  if  the  input is mainly user supplied and heavily based
on  parsing  and  regular expression or I'm racing a clock.  I
obviously do not know every programming and scripting language
existent  so  it's  totally up to you and your preferences, my
suggestions are not near any type of standard.

Once  you  have  chose  a programming language a lot of people
like  to  gather all references needed, as in books and online
technical documentation like RFC's and such.

Once  all  if  this has been gathered it is time to setup your
programs  operation  outline  and build a mental list of func-
tions,  modules?,  objects, and techniques in which you intend
to  use.   You  now  want to sketch down a design in which you
intend  to  guide  and  follow while programming your project.
Without  a  guide  you  might  end up forgetting something and
having  to  redesign your entire  project.   Always plan ahead
and have an overall understanding of what is ahead of you.

It  is  now  time to code... securely.  I will now try and in-
clude  guidelines  which are needed to be followed in order to
produce  secure  programs.   I  will focus on s*id and network
applications.   If  you don't know what a s*id application is,
in  short  it  is a program that requires different privileges
(sometimes  root)  to  do  operations.   An  example  would be
/usr/bin/passwd  which  requires access to read and modify the
passwd  and  or  shadow  file.   When  programming a s*id app-
lication  you  want to be positive that you handle these given
privileges with extra care and contain them only when actively
using  them.   You  want  to try and put these operations that
need  extra  privileges  in the beginning of your code so when
they  are  finished you can drop these privileges right after-
wards.   This  prevents  any holes found in the source extend-
ing  the  privilege  drop  that  an  attacker may exploit from
spilling  those  privileges.   If these operations can be done
sgid new group just as they can suid root, do not make it suid
root.   Remember  the whole reason we are programming securely
is  to  prevent  bugs  and  mostly preventing an attacker from
gaining  privileges  that  he currently does not have, whether
it's  a  remote  attack  on  a  daemon like telnetd or a local
attack  on  a  program  like  su.   If you're coding a network
daemon  you  want  to  make  sure  every  single  instruction,
operation,  and routine you use is fool-proof.  Holes exploit-
able remotely are the worst to exist and the most dangerous.

Trust  nothing  and no one, ever.  Trust should never be apart
of your program.  Picture everything as an enemy to break your
program.  You have to build a defeatless set of operations and
routines, create a flawless and unbreakable structural design,
and  still  contain full functionality.  In C this is not even
near  an  unreachable  goal when utilizing the right functions
and  routines which are clearly at hand.  I will now list some
guidelines while programming:

  1. Argument checking. (Vital)
    A. Preform bounds checking on everything.
    B. Become a semiotician and cross verify all syntactics.
    C. Watch carefully over the handling of command line arg-
       uments and bound everything.
    D. Verify all typecast variables.
    E. Verify system function arguments going outbound.
    G. Try  and  prevent  from pulling arguments from the env-
       ironment.   If  you  have to, make triple sure that you
       preform bounds checking and monitor everywhere the var-
       iable  can go.  This is a major commonly known mistake.

 2. Arbituary lengths.
   A. Don't  use  functions  that omit buffer bounds checking.
      Example: - sprintf(), vprintf(), vsprintf(), etc.
               - strcpy(), strcat().
               - gets(), scanf(), sscanf(), etc.
   B. Make double sure all your variable sizes are calculated
      correctly.
   C. Don't trust strings to be all null('\0') terminated and
      remember strlen() does not include this null.  In real-
      ity the string is always one byte larger.
   D. Don't  allow  overwriting  of  the null terminated byte
      when using read() and fgets().

 3. Program equipment.
  A. If  you  must  run  operations  via higher privileges, be
     carefull  what your program is equipped with, like stated
     earlier...  trust  nothing.   GTK+  for  one  has been an
     example recently shown to allow a library hijacking which
     was  attackable  via  any s*id application which had GTK+
     equipped while running in 'higher privilege mode'.
  B. If  outside  "equipment"  has  to be used, I myself would
     audit it.

 4. Execution via shell escapes - functions with suction.
  A. Do  not  use system(), popen(), or exec().  These methods
     are  way  too  sketchy.  Arbituary  commands are commonly
     known  to  find their way to the arguments of these calls
     which escape the real intended usage and give an attacker
     easy  access to gain shell access as a superuser.  DO NOT
     USE THESE FUNCTIONS.
  B. Be sure you include full pathnames when using execl() and
     execvp(), these use $PATH if no '/' is found.
  C. If  they  must  be  used for some twisted situation, make
     triple  sure that you parse out any type of escaped shell
     escape characters (meta characters, etc).
  D. Make  sure you include full pathnames to all outside pro-
     grams  being  called.   $PATH  can  be enabled to use '.'
     (Trust  no one).  I would suggest creating your own $PATH
     and   make  sure  you  do not trail it with ":", that in-
     cludes '.' in the paths.

 5. Preventing race conditions.
  A. Do not use mktemp() when creating temp files, instead use
     mkstemp()/tmpfile().
  B. Use  file  locking  for modified files.  Leave yourself a
     recovery  method  in  case  of  an emergency(crash, etc).
     Catch signals.
  C. When  using open() to create a 'new' file, always use the
     O_EXCL  and  O_CREAT  flags  to cause failure if the file
     already exists.
  D. Also  when manipulating a file always remember to utilize
     fchown(),  fchmod(),  and  fstat() to prevent any type of
     race condition or an unexpected file replacement.
  E. Make sure a link does not exist with lstat().
  F. Make  sure  your sequence of operations are correct.  ie.
     Don't  expect  a file you just stat'd to be the same file
     5 seconds later. (Trust no one).

 6. Other sly tricks and misc things.
  A. Always  check  anything  going to be created that is user
     supplied  for  meta  characters...  a  filename, anything
     shell related, etc. (vital).
  B. Dynamically  link  all  libraries,  this will prevent any
     pseudo  system libraries from being created and switched.
  C. Setup  limit values so your program does not leave a core
     file. Catch SIGABRT.
  D. In Perl try not to use `...` this too is a shell escape.

 7. Implement logging / syslog'ing and debugging messages.
  A. Log the PID, time, user(*uid/*gid), and terminal.
  B. Log  the  command  line  arguments and cought attempts to
     breach your programs security.
  C. Do this while not flooding syslog.
  D. In  the most vital positions of your programs you want to
     implement  verbose messages.  Also debugging messages are
     a  big help when working on a huge project that starts to
     get  confusing  of  what's  doing  what and what is going
     where.  Lots of debugging messages are very good.  Create
     a 'Debug mode' in which you can turn on internally with a
     switch, debug=1, etc.

 8. Release everything evil you have inside you.
  A. Try  and  BREAK,  hurt, SMASH, trick, BEAT, and kill your
     program in any and every possible situation.
  B. Fix and secure what you've broken.

You  can  also  go download several 'lint' programs which scan
your  source  and  often highlight subtle unforeseen problems.
O`reilly  has  a  book  called 'Checking C programs with lint'
which  can be bought via http://www.oreilly.com/catalog/lint/.

After  you have finished your project you want to make sure it
is disposed of all bugs  and errors.  While you're in the beta
stages  you  want to allows friends or a selected few to 'beta
test'  this  software and have a few more brains try and wreck
it.  When all seems well then it is up to you to release it.

--------------------------------------------------------------
Author: Cody Tubbs (loophole of hhp).       I would rather
  Site: http://www.hhp-programming.net/            be dead
 Email: pigspigs@yahoo.com                       than cool...
  Date: 7/31/2001 3:08:55PM CST.
--------------------------------------------------------------