Learning about Software Security

Before I started my journey to become a Software Engineer, I did not think about software security much beyond installing a good anti-malware product on individual computers and configuring the wireless network with the most advanced security options. As an ordinary user, I just had to use strong and unique passwords for each of my online accounts.

Of course, now I realize that there is a lot more to it all than just following the above guidelines. I like to classify the topic of software security into three areas.

  • Network security: Set of measures to protect the underlying network, computing and data resources from unauthorized access and service disruption.
  • Application security: The entire gamut of technical concerns such as SQL injection, buffer overflow to permissions of files deployed in production.
  • Logical security: The business rules controlling user role based access to application functions and data.

I was recently able to dive deeper into the application security aspect of software security through a few different means.

At work, I freed up a little bit of time to go back and complete a couple of online training courses that I had scheduled a while ago. The first course was a comprehensive introduction to application security for a Java developer. It covered a range of topics from the OWASP Top 10 and PCI DSS to cryptography and vulnerabilities within the Java language. The second course was specifically about web application security concepts. This is the stuff developers usually think of when hearing the term “software security”.

Both the courses helped me get a better grasp of the fundamentals of software security. I began to see how I could incorporate the lessons from them into my own development practices.

Then, I had the opportunity to attend two Meetups on associated topics within a couple of weeks of each other. I gained a further understanding of the practical aspects of software security from these sessions. I decided to document my takeaways from them in this post.

Introduction to Ethical Hacking by Mike Erman

  • The biggest security threats originate from inside the organization’s network, not from outside. Most of the damage occurs when people fall victim to phishing or social engineering attacks.
  • Default configurations of many Operating Systems and Networking Software used in companies are insecure.
  • Even if the configurations are secured, patches or upgrades to the components above may revert them back to insecure settings.
  • Once inside a network, malicious hackers can use powerful command line tools – that are openly available – to scan other connected resources and compromise them.

Secure Coding – Lessons Learned by Bill Smith

  • Security cannot be bolted on at the end of the development cycle. It needs to be incorporated into every step of the process.
  • Perform threat modeling and risk assessment during the initial stages of a project.
  • Build security related deliverables into the product backlog.
  • Some of the risk mitigation measures may have to be deferred to the clients using the product.
  • Code signing and certificate management get really complicated in CI environments.
  • Keep IOT/embedded devices off the internet.
  • Both the JDK and popular third party libraries have vulnerabilities. Those might not always get fixed immediately after they are discovered.

Overall, I walked away with a great appreciation for the importance of software security and the amount of responsibility developers have to ensure that the software they develop is secure.

 

A Nuance of Lambda Functions in Java 8

As I was trying to solve part 2 of the Day 6 problem in the Advent of Code 2015 challenge using Java 8, I ran into a curious problem. I had defined functions as follows for the various operations.

 public static Function<Integer, Integer> turnUp = i -> i++;

However, the solution from my program did not match the official answer. At first glance, I could not figure out the cause for the discrepancy. But after thinking about it for a while, I had a “a-ha moment” and wondered if the postfix version of the increment operation was the source of my issue. So I modified the functions to a prefix version as follows.

 public static Function<Integer, Integer> turnUp = i -> ++i;

Sure enough, the solution from my program matched the answer after this change.

The lesson here is that if you are relying on an implicit return from your lambda function, then you should use the prefix version of unary operations. That will ensure that the operation is performed before rather than after the return action.