outline
play

Outline Saltzer & Schroeders principles CSci 5271 More secure - PDF document

Outline Saltzer & Schroeders principles CSci 5271 More secure design principles Introduction to Computer Security Day 7: Defensive programming and design, part 1 Software engineering for security Stephen McCamant Announcements


  1. Outline Saltzer & Schroeder’s principles CSci 5271 More secure design principles Introduction to Computer Security Day 7: Defensive programming and design, part 1 Software engineering for security Stephen McCamant Announcements intermission University of Minnesota, Computer Science & Engineering Secure use of the OS Economy of mechanism Fail-safe defaults When in doubt, don’t give permission Security mechanisms should be as simple as Whitelist, don’t blacklist possible Obvious reason: if you must fail, fail safe Good for all software, but security software needs More subtle reason: incentives special scrutiny Complete mediation Open design Security must not depend on the design being Every mode of access must be checked secret Not just regular accesses: startup, maintenance, etc. If anything is secret, a minimal key Checks cannot be bypassed Design is hard to keep secret anyway E.g., web app must validate on server, not just client Key must be easily changeable if revealed Design cannot be easily changed Open design: strong version Separation of privilege “The design should not be secret” Real world: two-person principle If the design is fixed, keeping it secret can’t help Direct implementation: separation of duty attackers Multiple mechanisms can help if they are both But an unscrutinized design is less likely to be required Password and ✇❤❡❡❧ group in Unix secure

  2. Least privilege Least privilege: privilege separation Programs must also be divisible to avoid excess Programs and users should have the most limited privilege set of powers needed to do their job Presupposes that privileges are suitably divisible Classic example: multi-process OpenSSH server Contrast: Unix r♦♦t N.B.: Separation of privilege ✻ ❂ privilege separation Least common mechanism Psychological acceptability Minimize the code that all users must depend on for A system must be easy to use, if users are to apply security it correctly Related term: minimize the Trusted Computing Base Make the system’s model similar to the user’s (TCB) mental model to minimize mistakes E.g.: prefer library to system call; microkernel OS Sometimes: work factor Sometimes: compromise recording Cost of circumvention should match attacker and Recording a security failure can be almost as good resource protected as preventing it E.g., length of password But, few things in software can’t be erased by r♦♦t But, many attacks are easy when you know the bug Outline Pop quiz Saltzer & Schroeder’s principles More secure design principles What’s the type of the return value of ❣❡t❝❤❛r ? Software engineering for security Why? Announcements intermission Secure use of the OS

  3. Separate the control plane Defense in depth Keep metadata and code separate from untrusted Multiple levels of protection can be better than one data Especially if none is perfect Bad: format string vulnerability But, many weak security mechanisms don’t add up Bad: old telephone systems Canonicalize names Fail-safe / fail-stop If something goes wrong, behave in a way that’s safe Use unique representations of objects Often better to stop execution than continue in E.g. in paths, remove ✳ , ✳✳ , extra slashes, symlinks corrupted state E.g., use IP address instead of DNS name E.g., better segfault than code injection Outline Modularity Saltzer & Schroeder’s principles Divide software into pieces with well-defined More secure design principles functionality Software engineering for security Isolate security-critical code Minimize TCB, facilitate privilege separation Announcements intermission Improve auditability Secure use of the OS Minimize interfaces Appropriate paranoia Many security problems come down to missing Hallmark of good modularity: clean interface checks Particularly difficult: But, it isn’t possible to check everything continuously Safely implementing an interface for malicious users Safely using an interface with a malicious implementation How do you know when to check what?

  4. Invariant Pre- and postconditions A fact about the state of a program that should Invariants before and after execution of a function always be maintained Precondition: should be true before call Assumed in one place to guarantee in another Postcondition: should be true after return Compare: proof by induction Dividing responsibility When to check At least once before any unsafe operation If the check is fast Program must ensure nothing unsafe happens If you know what to do when the check fails Pre- and postconditions help divide that If you don’t trust responsibility without gaps your caller to obey a precondition your callee to satisfy a postcondition yourself to maintain an invariant Sometimes you can’t check Error handling Every error must be handled Check that ♣ points to a null-terminated string I.e, program must take an appropriate response action Check that ❢♣ is a valid function pointer Errors can indicate bugs, precondition violations, or Check that ① was not chosen by an attacker situations in the environment Error codes Exceptions Separate from data, triggers jump to handler Commonly, return value indicates error if any Good: avoid need for manual copying, not dropped Bad: may overlap with regular result May support: automatic cleanup ( ❢✐♥❛❧❧② ) Bad: goes away if ignored Bad: non-local control flow can be surprising

  5. Testing and security Fuzz testing “Testing shows the presence, not the absence of bugs” – Dijkstra Random testing can also sometimes reveal bugs Easy versions of some bugs can be found by Original ‘fuzz’ (Miller): ♣r♦❣r❛♠ ❁✴❞❡✈✴✉r❛♥❞♦♠ targeted tests: Even this was surprisingly effective Buffer overflows: long strings Integer overflows: large numbers Format string vulnerabilities: ✪① Modern fuzz testing Outline Mutation fuzzing: small random changes to a benign Saltzer & Schroeder’s principles seed input More secure design principles Complex benign inputs help cover interesting functionality Grammar-based fuzzing: randomly select valid inputs Software engineering for security Coverage-driven fuzzing: build off of tests that cause Announcements intermission new parts of the program to execute Automatically learns what inputs are “interesting” Secure use of the OS Pioneered in the open-source AFL tool Note to early readers ROP defense question Which of these defense techniques would completely prevent a ROP attack from returning from an intended This is the section of the slides most likely to change return instruction to an unintended gadget? in the final version A. ASLR If class has already happened, make sure you have B. A non-executable stack the latest slides for announcements C. Adjacent stack canaries D. A shadow stack E. A and C, but only if used together Project meetings Alternative Saltzer & Schroeder Not a replacement for reading the real thing, but: Starting tomorrow, run through next Wednesday ❤tt♣✿✴✴❡♠❡r❣❡♥t❝❤❛♦s✳❝♦♠✴t❤❡✲s❡❝✉r✐t②✲♣r✐♥❝✐♣❧❡s✲♦❢✲s❛❧t③❡r✲❛♥❞✲s❝❤r♦❡❞❡r Security Principles of Saltzer and Schroeder, Invitations sent yesterday illustrated with scenes from Star Wars (Adam Shostack)

  6. Outline Avoid special privileges Saltzer & Schroeder’s principles Require users to have appropriate permissions More secure design principles Rather than putting trust in programs Anti-pattern 1: setuid/setgid program Software engineering for security Anti-pattern 2: privileged daemon Announcements intermission But, sometimes unavoidable (e.g., email) Secure use of the OS One slide on setuid/setgid Don’t use shells or Tcl Unix users and process have a user id number (UID) . . . in security-sensitive applications as well as one or more group IDs String interpretation and re-parsing are very hard to Normally, process has the IDs of the use who starts do safely it Eternal Unix code bug: path names with spaces A setuid program instead takes the UID of the program binary Prefer file descriptors Prefer absolute paths Maintain references to files by keeping them open Use full paths (starting with ✴ ) for programs and files and using file descriptors, rather than by name ✩P❆❚❍ under local user control References same contents despite file system changes Initial working directory under local user control But FD-like, so can be used in place of ♦♣❡♥❛t if missing Use ♦♣❡♥❛t , etc., variants to use FD instead of directory paths Prefer fully trusted paths Don’t separate check from use Avoid pattern of e.g., ❛❝❝❡ss then ♦♣❡♥ Each directory component in a path must be write Instead, just handle failure of open protected You have to do this anyway Read-only file in read-only directory can be changed Multiple references allow races if a parent directory is modified And ❛❝❝❡ss also has a history of bugs

Recommend


More recommend