1 / 75

“Secure” Programming

“Secure” Programming. Matt Bishop Department of Computer Science University of California, Davis Davis, CA 95616- 8562 USA email : mabishop@ucdavis.edu. क्यूंकि मैं हिंदी मे बात नहीं कर सकता, इसलिय यह टॉक इंग्लिश मे है . As I don't speak Hindi, this talk will be in English.

micheal
Download Presentation

“Secure” Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. “Secure” Programming Matt Bishop Department of Computer Science University of California, Davis Davis, CA 95616-8562 USA email: mabishop@ucdavis.edu

  2. क्यूंकि मैं हिंदी मे बात नहीं कर सकता, इसलिय यह टॉक इंग्लिश मे है As I don't speak Hindi, this talk will be in English

  3. Weinberg’s Second Law If builders built buildings the way programmers wrote programs . . . then the first woodpecker to come along would destroy civilization

  4. Outline • Background • Where the problems are • Doing it right • Teaching it

  5. What Is Robust Programming • Robust programming, code • A style of programming that prevents abnormal termination or unexpected actions • Handles bad input gracefully • Detects internal errors and handles them gracefully • On failure, provides information to aid in recovery or analysis • Fragile programming, code • Non-robust programming, code

  6. Robust vs. Secure Programming • “Secure” program conforms to a security policy • And implicitly requires robustness • Robust programming does not require such conformance

  7. Example: Buffer Overflow • The program has additional privileges, so I use a buffer overflow to escalate my privileges in violation of a security policy (non-secure program) • The program has no privileges other than mine, so I cannot use it to escalate privileges in a way that violates the security policy (secure program, but not robust one)

  8. Who Should Care? • Users of Facebook • Mishandled error condition made it inaccessible for over 2 hours • Users of medical equipment—and patients • Errors have caused problems ranging from inconvenience to death • Voters • Electronic voting system software shown to have severe problems • And many more . . .

  9. Problem • We don’t build systems that meet security requirements • We don’t write software that is robust • Some exceptions in special cases • Many different models for developing software • Agile, waterfall, rapid prototyping, . . .

  10. Quality of Code • Underlying all this is programming • When coding, you make assumptions about services, systems, input, output • Other components you rely on have bugs or may act unexpectedly • Hard to have robust, secure software when the infrastructure isn’t

  11. Security is Cumulative • Composing non-secure modules produces non-secure software • Can ameliorate this with shims to handle non-secure results • Shims provide the security • What if they themselves are written, installed, etc. non-securely? • What if they can be bypassed?

  12. More Problems • Refactor code, use external libraries, modules, services • You inherit their bugs and assumptions! • Example: RSAREF2 library buffer overflow (1999) • Affected ssh, anything using that library • Move code into different environment, assumptions may not hold

  13. Policies and Procedures • These affect security and robustness • Approach 1: ignore these • Program will be used in a wide variety of environments • Need to know in which ones it is safe to do so • Approach 2: take these into consideration • Focus here is on use of program in particular environment with a certain set of procedures

  14. Basic Principles • Paranoia • Assume maximum stupidity • Don’t hand out dangerous implements • “Can’t happen” means it can

  15. Looking for Problems • Or . . . How to Attack via a Program

  16. What Is Intended? • Figure out what the problem is • Control access: find out for whom, where, when, what, why, how • Understand the policy and the practical limitations • Example: you can’t secure anything from root on UNIX-style system • This is an iterative process

  17. Find Assumptions • Implicit in all security are assumptions • Often about what is trusted • Attacks based on these • Ask what happens if the assumption is wrong • If program does something undesirable, continue • Ask how to make assumption wrong • Try it!

  18. One Good Way to Find These • Look at manual for programs • “can”, “must”, “should”, “will”, “ought”: don’t do it • “can’t”, “don’t”, “shouldn’t”, “won’t”, “limit”, “maximum”: do it • Look for ambiguity or contradictions in the manual, and see what the program does • Good, accurate manuals tell you many assumptions the program or system makes!

  19. General Thoughts • Look at interactions with (internal and external) components • Anything involving user I/O • Anything involving network interactions • Anything involving dependencies • Cryptography • Access control checking, especially credentials • Cleaning up (or not cleaning up) • Error handling

  20. Good Places for This • Network servers • Unknown users can access them • Local servers • They perform acts normal users cannot • Anything where privileges or rights are changed • For example, setuid/setgid; changing protection domains • Shared resources • Privileged and unprivileged users both use these • This includes (local, remote) clients of servers

  21. Network Servers • Accessible from throughout the network • Gives access to system • Attacker may not have access to account on target • Usually has privileges of some kind • root or daemon; may be only that of ordinary user • But you can usually get whatever you need from any of these • May make bogus assumptions • Weak authentication (identity from IP address) • May be poorly written

  22. Local Servers • Accessible through system entry point • Usually socket, shared directory, shared files • Usually has privileges of some kind • root, daemon, or some other system user • May make bogus assumptions • Determine requester’s identity from ancillary information (file ownership, etc.) • Initial environment may be poorly configured • May be poorly written

  23. Privileged Programs • Execute with privileges other than that of user • Executes in user’s environment • User’s environment may be incorrectly configured • Usually has privileges of some kind • root, daemon, or some other system user • May make bogus assumptions • Determine requester’s identity from ancillary information (file ownership, etc.) • May be poorly written

  24. Clients • Connect to (local or remote) servers • May not check input thoroughly • Browsers may pass environment information via command strings • If client is remote, can attack remote system with no other information beyond the server’s existence • Need not be privileged • Client connects to privileged programs • May be poorly written

  25. Cryptography • Avoid “homebrew” implementations • And (especially) algorithms • When using a (pseudo-)random number generator, look for the seeding • Process, time of day, etc. easy to guess • Key management problem • Hard-coded (default) keys a good example

  26. Access Control Checking • Race conditions (TOCTTOU, especially) • Mismatch between credentials sent and expected • Trusting IP address as identity for credential • Assume ports under 1024 are trusted • Differences in interpretation of rights based on object type (polymorphism in language)

  27. Cleaning Up • Core or intermediate files with sensitive data not deleted • Passwords, crypto keys not erased as soon as possible • File descriptors not closed when child is spawned • Signals caught by parent not reset when child is spawned • Environment cleaned up, and not reset

  28. Error Handling • Program tries to recover but doesn’t handle some cases properly • Look for improper assumptions when recovery attempted • Overly helpful error messages • Classic: “invalid password” (now I know I guessed a user name right)

  29. Key Ideas • To know how to write a good program, you need to know how to find problems • Assumptions are the basis for all security—so look for them!

  30. Example of Fragile Code • It’s always fun to pick apart someone else’s code! (Well, it’s mine ) • Library: implement standard queues (LIFO structures) • Written in C, in typical way • Files • queue.h • Header file containing QUEUE structure and prototypes • queue.c • Library functions; compiled and linked into programs

  31. Queue Structure • In queue.h: /* the queue structure */ typedefstruct queue { int *que; /* array of queue elts */ int head; /* head index in que */ int count; /* number of elts */ int size; /* max number of elts */ } QUEUE;

  32. Interfaces • In queue.h: • Create, delete queues void qmanage(QUEUE **, int, int); • Add element to tail of queue void put_on_queue(QUEUE *, int); • Take element from head of queue void take_off_queue(QUEUE *, int *);

  33. How To Mess This Up • Create queue • Change counter value QUEUE *xxx; … qmanage(&xxx, 1, 100); xxx->count = 99; • Now the queue structure says there are 99 elements in queue

  34. qmanage /* create or delete a queue * PARAMETERS: QUEUE **qptr pointer to, queue * int flag 1 for create, 0 for delete * intsizemax elements in queue */ void qmanage(QUEUE **qptr, int flag, int size) { if (flag){ /* allocate a new queue */ *qptr = malloc(sizeof(QUEUE)); (*qptr)->head = (*qptr)->count = 0; (*qptr)->que = malloc(size * sizeof(int)); (*qptr)->size = size; } else{ /* delete the current queue */ (void) free((*qptr)->que); (void) free(*qptr); } }

  35. What Can Go Wrong • . . . within this routine? • . . . calling this routine? The first argument’s validity cannot be checked Parameters are not sanity checked Return values are not checked There is no checking for integer overflow The order of parameters is easy to confuse The parameter values have arbitrary meanings There is no check that this is an attempt to delete a deleted (or non-existent) queue

  36. Adding to a Queue /* add an element to an existing queue * PARAMETERS: QUEUE *qptr pointer for queue involved * int n element to be appended */ void put_on_queue(QUEUE *qptr, intn) { /* add new element to tail of queue */ qptr->que[(qptr->head + qptr->count) % qptr->size] = n; qptr->count++; }

  37. What Can Go Wrong • . . . within this routine? The first argument’s validity cannot be checked qptr may not point to a valid queue There is no checking for incorrect values in structures or variables There is no check whether the array will overflow

  38. Taking from a Queue /* take an element off the front of an existing queue * PARAMETERS: QUEUE *qptr pointer for queue involved * int *n storage for the return element */ void take_off_queue(QUEUE *qptr, int *n) { /* return the element at the head of the queue */ *n = qptr->que[qptr->head++]; qptr->count--; qptr->head %= qptr->size; }

  39. What Can Go Wrong • . . . within this routine? There is no checking for incorrect values in structures or variables The values of qptr and n are not checked There is no check whether the array will underflow

  40. Protecting Your Code • Doing it . . . • Robustly • “Securely” • Right!

  41. General Rules • Design functions so that the order of elements in the parameter list can be checked • Choose meaningful values for the parameters • Check the sanity of the parameters • Using pointers (addresses, references) in parameter lists leads to errors

  42. Lessons • Check that the function’s operations are semantically meaningful • Check all return values unless the value returned does not matter • Check for overflow and underflow when performing arithmetic operations • Provide meaningful and useful error indicators and messages

  43. Example Program • login program from UNIX(-like) systems • Clear goals • Authenticate user as required • change UID of process to that of authenticating user • update log files • initiate shell • Security-critical functionality

  44. Restating the Goals . . . • Goal 1: only allow authorized user onto the system • Goal 2: restrict user’s privileges to those allowed to that user • Goal 3: log information to reconstruct any unauthorized login (break in)

  45. Environment and Assumptions • login program accesses correct authentication data • Is it /etc/passwd, Kerberos, or something else? • How do you know it’s up to date? • Does it use environment variables? • login program sets up correct environment • If not, it should not use environment, or allow any subprocess to use that environment

  46. Bad Code if ((p = getenv(“HOST”)) < 0) . . . do something else . . . if (strcmp(p, “host1”) == 0) authenticate(SKEY); else if (strcmp(p, “host2”) == 0) authenticate(KERBEROS); else authenticate(PASSWORD_FILE); Problem is HOST is under user’s control. Using gethostname, which is under system control, eliminates this trust in user.

  47. More Bad Code authenticate = YES; while ((o = getopt(argv, argc, “fph:n”)) != EOF){ switch(o){ case ‘n’: authenticate = NO; break; … } Problem: assumption is that -n flag (to turn off authentication) cannot be invoked by user

  48. Really Bad Code if ((fp = popen(“mail staff”, “w”)) != NULL){ fprintf(fp, “Send help soon!\n”); fclose(fp); } Problems: 1) Implicit assumption that PATH variable gets right mail program 2) Invocation of shell implies command works as expected (hint: think “rc file”) 3) Implicit assumption that no other variables affect shell’s interpretation of command (hint: IFS)

  49. Cutely Bad Code for(k = 0; environ[k] != NULL; k++) if (strncmp(environ[k], “PATH=“, 5) == 0) break; if (environ[k] != NULL) environ[k] = “PATH=/bin:/usr/bin:/usr/etc”; . . . system(“echo hithere | mail bishop”); Problem: multiple definitions of PATH variable. If shell takes last definition of variable, this won’t force the right mail program to be selected. (To put multiple definitions, write a short C wrapper …)

  50. Doing It Right environ = allocate_env_array(NUM_ENV); environ[0] = “PATH=/bin:/usr/bin:/usr/etc”; environ[1] = / * something else */; . . . environ[NUM_ENV-1] = NULL; if (execve(arg_ct, arg_array, environ) < 0) perror(/* error message prefix here */); Just create a new environment that you know to be safe!

More Related