secure code

Post on 26-Jun-2015

223 Views

Category:

Software

7 Downloads

Preview:

Click to see full reader

DESCRIPTION

Talk about how to design code that helps one to avoid some of the issues identified on OWASP top 10. Domain Driven Security is one of the main tools to achieve this.

TRANSCRIPT

Secure Code?- Daniel Deogun, Omegapoint

Twitter: @DanielDeogun Javaforum, Göteborg, 2014-09-18

About…

• Daniel Deogun!

• 10+ years in the industry!

• Developed everything from patient critical software to high performant applications with Akka to various web-based systems !

• TDD, BDD, DDD Specialist!

• Passionate about high quality code and security

Manhattan, NY, USA

Umeå

Falun

Stockholm

GöteborgKalmar

Malmö

What’s Secure Code?

• What does secure code look like?!!

• Do we need to think about security all the time?

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

https://www.owasp.org/index.php/Top_10_2013-Top_10

owasp top 10 (2013)A1 - Injection

A3 - Cross-Site Scripting (XSS)

A4 - Insecure Direct Object References

A6 - Sensitive Data Exposure

https://www.owasp.org/index.php/Top_10_2013-Top_10

owasp top 10 (2013)A1 - Injection

A3 - Cross-Site Scripting (XSS)

A4 - Insecure Direct Object References

A6 - Sensitive Data Exposure

https://www.owasp.org/index.php/Top_10_2013-Top_10

A1 - Injection

“Injection flaws, such as SQL, OS, and LDAP injection occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing data without proper authorization.”

- OWASP top 10

Injection Flaws

http://areino.com/blog/hackeando/

Example

public void register(String name, String phoneNumber) {! !! ! //Do registration stuff!!}

Example

public void register(String name, String phoneNumber) {! !! ! //Do registration stuff!!}

A. register(“Daniel”, “Deogun”);!!!B. register(“+46707010101”, “Daniel”);!!!C. register(“Daniel”, “+46707010101”);

Add Some Defensepublic void register(String name, String phoneNumber) {! if(name == null || !name.trim().matches("[a-zA-Z]{3,20}")) {! throw new IllegalArgumentException("Bad name");! }!! if(phoneNumber == null || !phoneNumber.trim().matches("^[+][0-9]{11}")) {! throw new IllegalArgumentException("Bad phone number");! }!! //Do registration stuff ! }

A. register(“Daniel”, “Deogun”);!!B. register(“+46707010101”, “Daniel”);!!C. register(“Daniel”, “+46707010101”);

Add Some Defensepublic void register(String name, String phoneNumber) {! if(name == null || !name.trim().matches("[a-zA-Z]{3,20}")) {! throw new IllegalArgumentException("Bad name");! }!! if(phoneNumber == null || !phoneNumber.trim().matches("^[+][0-9]{11}")) {! throw new IllegalArgumentException("Bad phone number");! }!! //Do registration stuff ! }

A. register(“Daniel”, “Deogun”);!!B. register(“+46707010101”, “Daniel”);!!C. register(“Daniel”, “+46707010101”);

Map Input to Domain Objects

public void register(Name name, PhoneNumber number) {! !! ! //Do registration stuff!!}

register(new Name(“Daniel”), new PhoneNumber(“+46707010101”));

Value Object with Restrictions

public class Name {! private final String value;!! public Name(final String value) {! notNull(value);! satisfies(value.trim().matches("[a-zA-Z]{3,20}"));!! this.value = value.trim();! }!! …

Prepared Statements

• What about prepared statements?!!

• Do we still need them?

Evil Tests

http://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Emblem-evil-computer.svg/500px-Emblem-evil-computer.svg.png

@Test! public void should_have_X_frame_options_header_set_to_DENY() {! assertTrue(headerIsSetTo("X-Frame-Options", "DENY", !! ! ! ! ! ! ! ! restTemplate.getForEntity(url, String.class)));! }!! @Test! public void should_have_xss_protection_header_defined() {! assertTrue(headerIsSetTo("X-XSS-Protection", "1; mode=block", !! ! ! ! ! ! ! ! restTemplate.getForEntity(url, String.class)));! }!! ...

Testing HTTP Headers

@RunWith(Theories.class)!public class NameTest {! private interface IllegalName {String value();}! !! @DataPoints! public static IllegalName[] illegalInput() {! return new IllegalName[]{! () -> null,! () -> "",! () -> " ",! () -> "A",! () -> "AA",! () -> " AA ",! () -> "1234567890",! () -> "TwentyOneCharactersXX",! () -> "<script>alert('42')</script>",! () -> "' or '1'='1"! };! }!! @Rule! public ExpectedException exception = ExpectedException.none();!! @Theory! public void should_be_illegal(final IllegalName illegal) {! exception.expect(IllegalArgumentException.class);!! new Name(illegal.value());! }

A3 - Cross-Site Scripting (XSS)

“XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation or escaping. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites.” !

- OWASP top 10

Example - Coder’s Blogg…

• Let’s say we’re running a website where anyone can ask questions about code!!

• Is it possible to avoid XSS?

Stored XSS

<script>alert(’42’)</script> Browser

Stored XSS & Broken Context Mapping

<script>alert(’42’)</script>

Write Context Read Context

Browser

Cyclomatic Complexity

• 1976 publicerade Thomas J. McCabe “A Complexity Measure” i IEEE Transactions on Software Engineering, Vol. SE-2 No. 4!!

• A measurement of the number of linearly independent paths through a program's source code.

Cyclomatic Complexity

public boolean isPositive(final int value) { if (value > -1) { return true; } return false; }

cyclomatic complexity =

Cyclomatic Complexity

public boolean isPositive(final int value) { if (value > -1) { return true; } return false; }

cyclomatic complexity = 2

Cyclomatic Complexity

cyclomatic complexity =

public boolean isPositive(final int value) { return value > -1; }

Cyclomatic Complexity

cyclomatic complexity =

public boolean isPositive(final int value) { return value > -1; }

1

public void reserveRoomFor(String meeting, String owner, String roomName, !! ! ! ! ! ! ! Calendar start, Calendar end, String... invitees) {! ! final List<Booking> bookings = repository.getBookingsFor(roomName);!! if(bookings != null && !bookings.isEmpty()) { //To make it faster! for(Booking booking : bookings) {! if(booking.collidesWith(new Booking(start, end, meeting, roomName, owner))) {! throw new AlreadyReservedException(start, end, roomName, meeting, owner);! }! }! }!! repository.store(new Booking(start, end, meeting, roomName, owner));!! if(dispatcher == null) {! dispatcher = Platform.instance().eventDispatcher();! }!! dispatcher.notify(invitees, new Booking(start, end, meeting, roomName, owner));!}

Cyclomatic Complexity

Cyclomatic Complexity

public void reserveRoomFor(final Meeting meeting, final Room room) {! notNull(meeting);! notNull(room);!! repository.store(booking(meeting, room));!! dispatcher.notify(meeting.invitees, booking(meeting, room));! }!! private Booking booking(final Meeting meeting, final Room room) {! return new Booking(meeting, room);! }

A4 - Insecure Direct Object References

“A direct object reference occurs when a developer exposes a reference to an internal implementation object, such as a file, directory, or database key. Without an access control check or other protection, attackers can manipulate these references to access unauthorized data.”

- OWASP top 10

A6 - Sensitive Data Exposure

“Many web applications do not properly protect sensitive data, such as credit cards, tax IDs, and authentication credentials. Attackers may steal or modify such weakly protected data to conduct credit card fraud, identity theft, or other crimes. Sensitive data deserves extra protection such as encryption at rest or in transit, as well as special precautions when exchanged with the browser.”

- OWASP top 10

Logging

• The logs are just another view of the system!!

• One needs to design and pay careful attention to what data that’s placed in the logs!!

• Access control of logs is extremely important

Code only used by testspublic class AccountRepository {! private Map<AccountNumber, List<Account>> userAccounts = new HashMap<>();!! public void register(final Account account) {! notNull(account);!! if(!userAccounts.containsKey(account.number())) {! userAccounts.put(account.number(), new ArrayList<>());! }! userAccounts.get(account.number()).add(account);! }!! public Map<AccountNumber, List<Account>> userAccounts() {! return userAccounts;! }

Stack trace

java.sql.SQLException: Closed Connectionat oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:1170) at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.rollback(DelegatingConnection.java:368) at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.rollback(PoolingDataSource.java:323) at net.sf.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:86) at org.springframework.orm.hibernate.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:529) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:753) at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:730) at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.j

Hide it

Well, that’s embarrassing! We seem to have made an error …

!

Legacy Code

Legacy Code

Extract module

Legacy Code

Design by contract

Extract module

Legacy Code

Design by contract

Map input to domain objects Extract module

Legacy Code

Dependency injection

Design by contract

Map input to domain objects Extract module

Legacy Code

Dependency injection

Design by contract

Map input to domain objects

Remove defensive code constructs

Extract module

Legacy Code

Dependency injection

Design by contract

Map input to domain objects

Remove defensive code constructs

Remove code only used by tests

Extract module

Key take Aways

• Developers cannot think about security all the time!!

• Good design principles will help one to avoid many security issues!!

• There is no such thing as just a string (Dr. John Wilander)!!

• Validate input and map everything to domain objects

Thanks

Twitter: @DanielDeogun

top related