On this second day at Code One I have again visited interesting sessions. One on security by Jim Manicode and one on cash (or the lack thereof) in Sweden.
OWASP Top Ten Proactive Controls
The first session worth mentioning today is OWASP Top Ten Proactive Controls with Jim Manicode. This document isn’t really developer-ready, but more for security standards. Instead of pointing out risks, the Proactive Controls read more like suggestions or commands to follow.
- Define Security Requirements - The Application Security Verification Standard (or its mobile counterpart, the MASVS) provides a good basis for this. It comes in various levels that correspond to the type of system that you are building. By making concrete requirements it is easier to have a good level of security. It avoids a situation where security is something for the security department and its specialists, and brings it to the team that’s actually building the software.
- Leverage Security Frameworks and Libraries - Typically the time-to-fix between a security vulnerability being announced and being attacked is just a few days. This means you have to keep your libraries up to date. Not doing that on a regular basis means you are at risk for a major upgrade as soon as a vulnerability is announced.
- Secure Database Access - Input validation is not enough - valid email addresses (like
firstname.lastname@example.org) can still inject commands into an SQL query. The only valid defense against this is using prepared statements.
- Encode and Escape Data - Unfortunately, there is no real standard on how to do proper defense against XSS for example. It depends on the frameworks, libraries and view technologies that you use.
- Validate All Inputs - All data entered into the system needs to be validated. This applies to character set, structure and length.
- Implement Digital Identity - Using a third party login system (like Google, Facebook, Twitter) is usually more secure than building something yourself.
Those companies invest many hours and large budgets to defend against all kinds of attacks.
Storing passwords is only a good idea when it is secure enough:
- use a user unique salt;
- hash the password using SHA-512 or another strong hash;
- use ARGON2i, BCRYPT or SCRYPT on the hashed password and store that.
- Enforce Access Controls - Access control implies always verifying whether a user retrieves or modifies an item. Also, don’t hardcode roles, but instead rely on attribute based access control (see NIST SP 800-162 for details).
- Protect Data Everywhere - This does not only imply transport-level encryption (using for example HTTPS) but make sure to have approriate encryption for data at rest, too. Don’t rely on low-level encryption primitves when you need to build encryption yourself. Google Tink is the first library that directly integrates with key management solutions, and has implementations for C++, Go, Java and Objective-C.
- Implement Security Logging and Monitoring - Log intrusion attempts, early and often. This especially applies to authentication attempts, access control attempts and input validation failures. Both request and response should be logged (as far as possible within privacy laws like the GDPR).
- Handle All Errors and Exceptions - (not handled because time ran out)
How Java Has Killed (Almost) All Cash in Sweden
Victor Duran delivered an interesting story about a project that has ran in Sweden over the last few years. Swish, as it was named, should enable fast and smooth payments with challenging requirements. The most challenging one was installment of a security door at the data center - this requirement was actually handed over to the sofware team. Even though the project was ran by eight banks together, there was no lead architect appointed to make sure those requirements would land in another discipline ;-).
The project had five external and very diverse integrations, varying from mobile clients that speak JSON over HTTP to old SOAP-based systems running on WebSphere. Of course, since the system handles payments, security was a very relevant topic. It has been pen-tested by three different companies. All communication between the app and the server was encrypted with TLS 1.2.
An interesting observation during performance testing was that they couldn’t get the performance levels they initially expected. Those tests where run at user story level, as requested by the client. But in practice, users turned out to use multiple user stories at the same time. On the other hand, they learned that writing small methods has more advantages than resulting in clean code (usually). It also allows the just-in-time compiler to do very aggressive inlining of those methods, yielding higher performance.
After a slow start, the volumes transferred using this app have grown to multi-million numbers last year. One of the drivers for that is that Swedish people don’t really like to owe money to someone else. This app provides them with a way to immediately transfer money after sharing a taxi of having dinner. Also, business have started to accept payments with Swish, further increasing transaction volumes.
As a result, less and less stores in Sweden accept cash payments. Even some banks don’t accept cash deposits anymore, which sounds contradictory. In the feeling of people, cash has become inefficient and smells like fraud. On the other hand, it also reduced robberies in streets, since less and less people have cash with them.