The document summarizes application security best practices. It discusses who is responsible for application security and design considerations like authentication, authorization, privacy and data integrity. It then covers security principles like designing for security by default and in deployment. Top application vulnerabilities like SQL injection, cross-site scripting and access control issues are explained along with remedies. Finally, it provides checklists for designers, developers and testers to follow for application security.
Responsibility of designers, coders, administrators; Testers also have a role; Most of the security failures caused by bad code; Also bad design (disregard for security or lack of awareness), or mis-administration; Many of the flaws could be discovered in the testing phase, if aware and planned for;
NT built in storage and checking of security for Kernel objects
In today’s distributed systems (network computing), multiple users are simultaneously trying to use common resources. In order to get or restrict access to these resources, users need to get authenticated (Alan, is that you ?) and authorized (Kevin, you are not allowed to read that restricted file !). These are some aspects of system security, together with: Privacy encryption can anybody see what you do? Data integrity can anybody change your action? A malicious user would try to attack on any of these fronts, for various reasons: to steal secret data, to vandalize/deface web applications/sites etc.
A application system should be designed, started, configured and tested with security in mind. Security, together with robustness and reliability, should be of importance at every tier. The more complicated the system, the bigger the number of failures (any code that looks overly complicated likely has bugs).
Security principles: SD3 (Secure by Design, by Default and in Deployment) Writing solid code (coding principles to minimize number of bugs: const == var etc.) Minimize attack surface: number of sockets, pipes, services, files, registry keys etc. Training for everyone involved, makes everyone aware of security threats and vulnerabilities; Security checklists for designer, developer and tester;
Also mandatory application logging (discover possible intrusion early) Audit often
There is no statistics on app vulnerability yet; Order is arbitrary Even the definition of application vulnerability is widely disputed: some argue that even administration flaws (last) should not be on the list; network and infrastructure security issues (firewalls, server configuration, Denial of Service etc) are not considered; Microsoft considers “Buffer overrun” as public enemy #1 We will show brief descriptions on how they manifest and their countermeasures/remedies;
Any data submitted by a user is initially untrusted data. could lead to buffer overruns, SQL injection attack, server crash etc. Data supplied as input to a function should be also checked. Data checking a must even though it could affect system performance (better than system crash, especially when it is a critical component);
Reusable components (DLL, COM) should be designed and written carefully: they should not trust the caller, since the caller can be any code; Also, configuration data (config file, environment variables, even registry settings) should not be always trusted: they can be unintentionally wrongly set by an administrator, and they could cause application crash.
Rule is derived from the principle of “failing securely”; Check data type, data length (min/max), numeric range, param required or not, whether duplicates are allowed etc; Regular expressions serve 2 purposes: to find data and to validate data; Regex++ (STL) CAtlRegExp in VC++ 7 Issues when used with Unicode In C++, get around regular expressions by implementing private method Validate();
Canonicalization: multiple ways to specify file name: /, , /../../, absolute vs. relative, case insensitive etc Example: MyFile.txt. == myfile.txt Files could be really devices; system blocks when try to open “devices”; Usage of non-alpha characters: escape sequences, CR etc. Example: file name entered by user is logged; one can fudge the log by entering a “file name” that contains multiple lines: they are going to be logged as they are ! Rules for canonicalization: Reject non alpha-numerical chars (~ etc.), trailing dot, OR/AND Evaluate the long file name in case short file name was used, by calling GetLongPathName() -> defense in depth measure (double check) Prepends app-configured directory to the file name (make sure len < MAX_PATH); Adds \? to the start of the filename, instructing OS to handle filename literally (turn off path parsing, do not perform extra canonicalization steps) Evaluate the long file name in case short file name was used, by calling GetLongPathName() Determines if filename represents a file or a device by using GetFileType(); if returns FYLE_TYPE_DISK, it’s real file Check server names by calling GetComputerNameEx() Check user names by calling GetUserNameEx()
When a web application displays as output some unfiltered input accepted from a user. End user trusts the web app; attacker exploits this trust; Attackers employ a variety of methods to encode malicious code, such as using Unicode. in the case of stored attacks, the injected code is permanently stored on the target servers (db, forums, logs, bultin boards); in the case of reflected attacks, the injected code takes another route to the victim, such as in an email message, or on some other server (redirection to a malicious server that send back attack code);
Although the URL looks like pointing to microsoft.com domain, it is bogus ! It is a user name (www.microsoft.com), followed by the real web site name, hex-encoded to make it harder for the victim to read it.
vulnerable web server does not filter the input, and just sends it back to client. pass a wisely crafted script as input, it will be passed back to the browser; mask this input (escaped HTML, as in the previous microsoft site exemple); Need: web browser supporting scripting with DHTML model;
pass somehow (email, other trusted site) this trusted-site link (param is a sequence of code) to the victim’s browser (the script part of the link is masked); Sometimes, it is not necessary for the victim to click the link: attacker uses onmouseover=“malicious script”; also onload, on activate
Local content is vulnerable to attack if file location is known or predictable and it outputs input from user; Link to a vulnerable local file (specifying the full path) could allow execution of a script (passed from “Internet” zone) in the “My computer” zone; This code echoes back the input after the # sign (in URL);
ASP Server.HTMLEncode converts dangerous symbols , including HTML tags, to their harmless HTML representation, for example < becomes &lt; Why double and not single quotes: HTML encoding does not escape single quote characters, but only double quotes; Protection for reading the cookie from script. For example, the following cookie cannot be accessed by DHTML: Set-Cookie: name=John; domain=microsoft.com; HttpOnly (the cookie could be poisoned though, this does not provide protection against that) An internet page saved locally is still displayed in the “Internet” zone. This is possible because a comment is placed in the file: <!– saved from url=(0026)http://msdn.microsoft.com--> The only valid setting is “restricted”: no script is executed. Forces the web site into “Restricted sites” zone.
Stack overflow: many of the GPFs (ones that display an application address) will lead to possibility of buffer overrun; Other GPFs, caused by heap overrun (where system memory is displayed), are also exploitable; VC++7 has /GS compiler option that keeps track of stack allocation: offers some protection (displays a GPF type of message, trappable in the app though);
build and run in release; play with this example by passing various string parameters (various lengths, less than 10 and more than 10), like “abcdefghijklm”; Trick to view stack: printf(“stack is:
%p
%p
”) Once you can overwrite values within the application, it is possible to cause security bugs: the overwritten value will be the address of your malicious function; Ban the use of strcpy and the incidence of buffer overrun will drop dramatically;
Format string bugs: not really buffer overflow Warning: %S format specifier with printf family of functions silently skips characters that don’t translate; Strsafe.h file defined by microsoft during windows security push Code reviews, thorough testing, ban unsafe function calls;
there is no dangerous function, only dangerous developers – Dave Cutler (paraphrase of Heinz Guderian) Name-squatting: create a name that could be guessed by attacker; Trojaning: need a guarantee that the launched app is the one it pretends to be (authenticate the app); DoS: app can halt if, in low memory conditions, thrown exception are not caught;
Select statement returns all customers, far from initial intention Comment operator (“--”) makes the statement valid regardless of the rest of the statement; supported to many db; Can also insert additional sql statements: A125612’ drop table statement –--
Pseudo-remedies: Double-Quote the input: if the input contains quotes, double it, as you would have done for names like O’Bryan Renders sql statement invalid; This “remedy” does not work if variables are not quotes (as for ints)
Remedies: never connect as sysadmin, thus eliminate the possibility for attacker to drop tables, delete system data, call admin stored procs, add database users to the system, delete logs etc. In SQL server, xp_cmdshell allows the call of shell commands; Oracle has utl_file that allows read/write to file system; Cmd = CreateObject(“ADODB.Command”) Cmd.CommandText = “select * from … where name=(?) and age=(?)” Set parm1 = cmd.CreateParameter(…)
If an attacker can access a resource, her job is done; Resources secured through ACL are: files and directories, registry keys, printers, named pipes, active directory objects, synchronization objects (mutex, semaphores). sounds simple problem but difficult to implement correctly, since it is tight to the content the app provides; Other access control issues include: Insecure ID’s: attacker should not be able to use a guessed ID in order to get access; Credential checks must be not bypassable (security check pages could not be skipped); Client side caching: through coding, make sure that the pages containing sensitive info are not cached on the browser; Testing with Windows 2000 (and later) security templates that define recommended lockdown computer configurations, configurations more secure than the default one. Some apps fail to operate correctly when security settings are anything but defaults. 7 named security templates
Key management is considered the weakest link of cryptographic applications; Easy to generate keys, hard to store, exchange, and use; Hard-coding a key in an executable is trivial to break; XingDVD player from RealNetworks did not have the DVD encryption keys satisfactorily protected; DeCSS program cracked DVDs based on key info from the executable;
CryptGenRandom gets its randomness from many sources in Win 2000, including: current procID (GetCurrentProcessID) current threadID (GetCurrentThreadID) Ticks since boot (GetTickCount) Current time (GetLocalTime) Various high precision performance counters (QueryPerformanceCounter) High precision CPU counters (RDTSC, RDMSR, RDPMC for Pentium) Etc. There are long term and short term (ephemeral) keys. The latter are used by networking protocols (DCOM, SSL, RPC). Long term keys are used for authentication and integrity and they are used to establish the ephemeral keys. For example, when using SSL, the server uses its private key (identified by its public key certificate) to generate ephemeral keys for each encrypted SSL session. Symmetric keys are protected by asymmetric ones: see equivalence tables (for example, 80 bit symmetric key requires 1228 bit RSA asymmetric key). When use crypto keys, keep them close to the point where they encrypt/decrypt data. (The value of a secret is inversely proportional to its availability). When passing the key to functions, use key handle rather than the key itself, minimizing the key’s exposure. Crypto API: CryptGenKey (generates a strong key, yet you never see the value directly; you access it using a handle), CryptExportKey (export the key from CryptoAPI to a persistent storage), CryptoImportKey. The key is protected by either a public key in a certificate (and later decrypted with the private key) or (Win2K and later) by a symmetric key. The key is never in plaintext, except deep inside CryptoAPI.
The message being encrypted, T , must be, evidently, less than the modulus, PQ . ^ is exponentiation