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öteborg 
Kalmar 
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 Defense 
public 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 Defense 
public 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> 
Browser 
Write Context Read Context
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 
public boolean isPositive(final int value) { 
return value > -1; 
} 
cyclomatic complexity =
Cyclomatic Complexity 
public boolean isPositive(final int value) { 
return value > -1; 
} 
cyclomatic complexity = 
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 tests 
public 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.753) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.
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 
Extract module 
Remove defensive code constructs
Legacy Code 
Dependency injection 
Remove code only used by tests 
Design by contract 
Map input to domain objects 
Extract module 
Remove defensive code constructs
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

Secure code

  • 1.
    Secure Code? -Daniel Deogun, Omegapoint Twitter: @DanielDeogun Javaforum, Göteborg, 2014-09-18
  • 2.
    About… • DanielDeogun! • 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öteborg Kalmar Malmö
  • 3.
    What’s Secure Code? • What does secure code look like?! ! • Do we need to think about security all the time?
  • 4.
    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
  • 5.
    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
  • 6.
    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
  • 7.
    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
  • 8.
  • 9.
    Example public voidregister(String name, String phoneNumber) {! ! ! ! //Do registration stuff! ! }
  • 10.
    Example public voidregister(String name, String phoneNumber) {! ! ! ! //Do registration stuff! ! } A. register(“Daniel”, “Deogun”);! ! ! B. register(“+46707010101”, “Daniel”);! ! ! C. register(“Daniel”, “+46707010101”);
  • 11.
    Add Some Defense public 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”);
  • 12.
    Add Some Defense public 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”);
  • 13.
    Map Input to Domain Objects public void register(Name name, PhoneNumber number) {! ! ! ! //Do registration stuff! ! } register(new Name(“Daniel”), new PhoneNumber(“+46707010101”));
  • 14.
    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();! }! ! …
  • 15.
    Prepared Statements •What about prepared statements?! ! • Do we still need them?
  • 16.
  • 17.
    @Test! public voidshould_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
  • 18.
    @RunWith(Theories.class)! public classNameTest {! 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());! }
  • 19.
    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
  • 20.
    Example - Coder’sBlogg… • Let’s say we’re running a website where anyone can ask questions about code! ! • Is it possible to avoid XSS?
  • 21.
  • 22.
    Stored XSS & Broken Context Mapping <script>alert(’42’)</script> Browser Write Context Read Context
  • 23.
    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.
  • 24.
    Cyclomatic Complexity publicboolean isPositive(final int value) { if (value > -1) { return true; } return false; } cyclomatic complexity =
  • 25.
    Cyclomatic Complexity publicboolean isPositive(final int value) { if (value > -1) { return true; } return false; } cyclomatic complexity = 2
  • 26.
    Cyclomatic Complexity publicboolean isPositive(final int value) { return value > -1; } cyclomatic complexity =
  • 27.
    Cyclomatic Complexity publicboolean isPositive(final int value) { return value > -1; } cyclomatic complexity = 1
  • 28.
    public void reserveRoomFor(Stringmeeting, 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
  • 29.
    Cyclomatic Complexity publicvoid 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);! }
  • 30.
    A4 - InsecureDirect 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
  • 31.
    A6 - SensitiveData 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
  • 32.
    Logging • Thelogs 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
  • 33.
    Code only usedby tests public 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;! }
  • 34.
    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.753) at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.
  • 35.
    Hide it ! Well, that’s embarrassing! We seem to have made an error …
  • 36.
  • 37.
  • 38.
    Legacy Code Designby contract Extract module
  • 39.
    Legacy Code Designby contract Map input to domain objects Extract module
  • 40.
    Legacy Code Dependencyinjection Design by contract Map input to domain objects Extract module
  • 41.
    Legacy Code Dependencyinjection Design by contract Map input to domain objects Extract module Remove defensive code constructs
  • 42.
    Legacy Code Dependencyinjection Remove code only used by tests Design by contract Map input to domain objects Extract module Remove defensive code constructs
  • 43.
    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
  • 44.