Professional Documents
Culture Documents
Secure DotNet Programming
Secure DotNet Programming
Introductions
Not experts, just offering experience gained from .NET
programs weve done Goal is practical advice, based on principles and code smells1, rather than exact code one is supposed to apply to every programs (though reusable code is good) This (mostly) works for us it may not work for you. Use what works for your team, but remember:
OWASP Top 10
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
2 2007
Cross Site Scripting (XSS) SQL Injection Malicious File Execution (via Remote File Inclusion) Insecure Direct Object Reference Cross Site Request Forgery (CSRF) Information Leakage and Improper Error Handling Broken Authentication and Session Management Insecure Cryptographic Storage Insecure Communications Failure to Restrict URL Access
XSS
Cross site scripting is the most prevalent/pernicious web
application security issue. XSS flaws occur whenever an application takes data that originated from a user and sends it to a web browser without first validating or encoding that content. XSS types:
1. 2. 3.
Reflected displaying user supplied (hostile) data directly Stored storing user supplied (hostile) data and displaying (e.g. CMS, blogs, forums) DOM Injection Manipulating JavaScript directly on the page, including using XmlHttpRequest (basis of AJAX) to get around same source origination policies to forward users to hostile sites, etc.
is sent to an interpreter as part of a command or query. Attackers trick the interpreter into executing unintended commands via supplying specially crafted data.
String query = "SELECT user_id FROM user_data WHERE user_name = '" + txtUserName.Text + "'";
etc. Use Stored Procedures or at least strongly typed parameterized queries. Dont show detailed error messages.
Input Validation
.NET makes it easy to validate input controls using the
<asp:xxxValidator> controls.
ASP.NET Validators (except for the customValidator)
validate controls once using client side JavaScript and again on the server side (protecting you from clients who turn off JavaScript).
the RequiredFieldValidator Ex: If you want to make sure a string is not empty and matches a regular expression (like an Email address), you must use both a RequiredFieldValidator and a RegularExpressionValidator. The CompareValidator can do much more than comparing two controls. Leave the ControlToValidate propery blank, use the Type, Operator and ValueToCompare properties. Operators: dataTypeCheck, Equal, NotEqual, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual Types: Currency, Date, Double, Integer, String
than one
Parsing Objects
int age = 0; if (int.TryParse(textBoxAge.Text, out age)) { // Success in parsing string to int } else // Was not able to parse string { // Handle error }
[NotNullValidator()] [StringLengthValidator(1, 100)] public virtual string PositionTitle { get { return _PositionTitle; } set { _PositionTitle = value;} }
files.
Potential Issues: Remote Code Execution Unauthorized File Access
Check user permissions on retrieval Return the file as a binary stream (application/octet-stream)
<select name="language"><option value="fr">Franais</option></select> require_once ($_REQUEST['language]."lang.php"); And, assuming no SQL injection is possible, what is wrong with the following? int cartID = Integer.parseInt( request.getParameter( "cartID" ) ); String query = "SELECT * FROM table WHERE cartID=" + cartID;
as primary keys or filenames Validate any private object references extensively (e.g. RegExs) Verify authorization to all referenced objects
Its the web Assume a user will access any published
URL, dont assume theyll follow links to get there But see more on CSRF!
Permission Calculator (Permcalc.exe) Choose an appropriate trust level with required permissions, or better yet, create a custom trust level with only the permissions needed by the application Configure the ASP.NET application to use
Custom Permissions
Copy the Medium trust policy file, web_MediumTrust.conf,
located in %windir%\Microsoft.NET\Framework\{version}\CONFIG\ to a file located in your application directory Add RegistryPermission to <SecurityClass> in Web_CustomTrust.config: <SecurityClass Name="RegistryPermission" Description="System.Security.Permissions.Regis tryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
Custom Permissions
Add new <trustLevel> element to the <securityPolicy> section of the Web.config file to define new level called Custom associated with custom policy file
<location allowOverride="true"> <system.web> <securityPolicy> <trustLevel name="Full" policyFile="internal" /> <trustLevel name="High" policyFile="web_hightrust.config" /> <trustLevel name="Medium" policyFile="web_mediumtrust.config" /> <trustLevel name="Low" policyFile="web_lowtrust.config" /> <trustLevel name="Minimal" policyFile="web_minimaltrust.config" /> <trustLevel name="Custom" policyFile="web_CustomTrust.config" /> </securityPolicy> <trust level="Full" originUrl="" /> </system.web> </location>
Custom Permissions
Add RegistryPermission to <SecurityClass> in
Web_CustomTrust.config:
<SecurityClass Name="RegistryPermission"
Description="System.Security.Permissions.R egistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
Custom Permissions
Refer to web_CustomTrust.config in your applications web.config:
... <location allowOverride="true"> <system.web> <securityPolicy> <trustLevel name="Custom" policyFile="web_CustomTrust.config" /> </securityPolicy> <trust level="Custom" originUrl="" /> </system.web> </location> ...
Code Signing
Sign common necessary files with private key to
download)
Generates Key Pair files Places keys into each project (each application block has
CSRF
Cross site request forger forces a logged-on browser to send a request to a vulnerable web app, which performs chosen actions on behalf of the victim. Example:
<img src="http://www.example.com/logout.php">
Changed to:
<img src="http://www.example.com/transfer.do?frmAcct=document.fo rm.frmAcct& toAcct=4345754&toSWIFTid=434343&amt=3434.43">
Note the use of Direct Object access, but done in the context of
the user! (Hence my own preference to not use URL-based object references)
uncaught error is raised, and specific error pages when certain status codes appear (403/404/etc).
globally
public class ApplicationPage : System.Web.UI.Page { public ApplicationPage() { } protected override void OnError(EventArgs e) { Exception baseException = Server.GetLastError().GetBaseException(); //Handle Error: Log and Redirect to Error Page base.OnError(e); } }
try {
// Execute Database call } catch (SqlException sqlEx) { eReport.ReportError(sqlEx, System.Reflection.MethodBase.GetCurrentMethod()); }
GridView DataKeys
Use DataKeys to store primary key fields without
GridView DataKeys
<asp:GridView ID="CustomersGridView" DataSourceID="CustomersSqlDataSource" DataKeyNames="CustomerID" runat="server"> <Columns> <asp:BoundField DataField="CustomerName" HeaderText="Name" /> </Columns> </asp:GridView> //Access the datakey in your codefile gViewData.DataKeys[rowIndex].Value;
properly protected. Attackers compromise passwords, keys, or authentication tokens to assume other users identities.
Role Provider
The fundamental job of a role provider is to interface
with data sources containing role data mapping users to roles, and to provide methods for creating roles, deleting roles, adding users to roles, and so on. Given a user name, the role manager relies on the role provider to determine whether what role or roles the user belongs to.
Role Provider
public abstract class RoleProvider : ProviderBase { // Abstract properties public abstract string ApplicationName { get; set; } // Abstract methods public abstract bool IsUserInRole(string username, string roleName); public abstract string[] GetRolesForUser(string username); public abstract void CreateRole(string roleName); public abstract bool DeleteRole(string roleName, bool throwOnPopulatedRole); public abstract bool RoleExists(string roleName); public abstract void AddUsersToRoles(string[] usernames, string[] roleNames); public abstract void RemoveUsersFromRoles(string[] usernames, string[] roleNames); public abstract string[] GetUsersInRole(string roleName); public abstract string[] GetAllRoles(); public abstract string[] FindUsersInRole(string roleName, string usernameToMatch);
Role Provider
<authentication mode="Forms"> <forms name="FormsAuthDB.AspxAuth" loginUrl="~/login.aspx" defaultUrl="~/Default.aspx" protection="All" timeout="120" path="/"> </forms> </authentication> <roleManager enabled="true" defaultProvider="CAESDORoleProvider" cacheRolesInCookie="true"> <providers> <add name="CAESDORoleProvider" type="CAESDO.Recruitment.Providers.CAESDORoleProvider" applicationName="Recruitment" description="CAESDO Authorization Test Program" connectionString="CATBERT"/> </providers> </roleManager>
Role Provider
<location path="members"> <system.web> <authorization> <allow roles="member, manager" /> <deny users="*" /> </authorization> </system.web> </location> <system.web> <authorization> <deny users="?" /> </authorization> </system.web>
Password
Requires manual encryption and decryption in code Changes to legacy programs required Performs on the fly decryption No changes to code necessary
Add necessary lines to the web.config 2. Import / create machine key 3. Encrypt desired section (appSettings or connectionStrings)
1.
Insecure Communications
Use SSL Purchase Certs at IT Secuity site: http://security.ucdavis.edu/ Or you can use selfcert.exe or OpenSSH to create your
own certificates
No excuse!
Domain account
Associate with Application Pool
Keep separate accounts for separate App Pools
Check for backdoors Audit startup procedures (sp_MSRepl_startup) Audit commonly run procedures (sp_help, sp_password) Administrator Xstatus (2218 allows Admin login with no password) Use SQL Server 2005 if possible Reduced attack surface Table and column encryption [6]
But
All that can change next year. So what principles stay in common? Software Engineering - A systematic approach to the analysis, design, implementation and maintenance of software3
Software Development Life Cycle Security is a process Maintainable, auditable, provably correct code Architecture Separation of concerns into functional, independent, minimally coupled layers Service Oriented Architecture Infrastructure Separation of concerns into functional, independent, minimally coupled tiers Deployment, maintenance, upgrade, and retirement handled separately from programming/development
Software Engineering
Team Foundation Server with Visual Studio Team System Source control and code check-in policies
Bug and project tracking Automated (nightly) builds with MSBuild Test-driven development Unit testing Database testing Setup & deployment projects
Use Design Patterns Singletons Factories Inversion of Control/Dependency Injection Consider using frameworks Microsoft Enterprise Library NHibernate (Object-relational mapping) [7] Castle (Object interceptors) [8]
References
1. 2. 3.
4. 5. 6.
7. 8. 9.
A Taxonomy for Bad Code Smells. http://www.soberit.hut.fi/mmantyla/BadCodeSmellsTaxonomy.htm The Open Web Application Security Project.<http://www.owasp.org/index.php/Top_10_2007>. "software engineering." The Free On-line Dictionary of Computing. Denis Howe. 13 Jun. 2007. <Dictionary.com http://dictionary.reference.com/browse/software engineering>. Threat Profiling Microsoft SQL Server (A Guide to Security Auditing), David Litchfield, 20 July 2002. http://www.nextgenss.com/papers/tp-SQL2000.pdf Security in SQL Server 2005 as seen by a programmer, Software Developers Journal, 21 March 2006. http://www.codeproject.com/database/sqlserver_secure.asp How To: Use Code Access Security in ASP.NET 2.0, Microsoft Patterns & Practices Developer Center, August 2005. http://msdn2.microsoft.com/enus/library/ms998326.aspx NHibernate for .NET, Sergey Koshcheyev, Ayende Rahien, and others. http://www.hibernate.org/343.html Castle Project, Castle Project. http://www.castleproject.org/ Enterprise Library, Microsoft Patterns & Practices Developer Center, May 2007. http://msdn2.microsoft.com/en-us/library/aa480453.aspx
Adam Getchell (acgetchell@ucdavis.edu) Scott Kirkland (srkirkland@ucdavis.edu) Alan Lai (anlai@ucdavis.edu) College of Agricultural & Environmental Sciences Deans Office
IT Security Symposium June 20-22, 2007