On Security

Security is a multifaceted concern. We believe the most reliable and resilient systems are ones with multiple layers of safe-guards and redundancy, and adopt the principles of defensive programming: where we build a barrier, we assume it may one day be broken so we build another barrier behind it; where we expose a programming interface, we assume it may be misused so we validate its behaviour.

Of course, the trade-off for redundancy is reduced efficiency - but we believe that, whilst faster hardware may be expensive, reliable and secure code is priceless. Some specific examples of how we secure our systems include:

  • Injection proof: we guard against HTML and SQL injection attacks by using validated input, parameterized queries and escaped output.
  • Cross Site Scripting (XSS) proof: we tag every interaction with a unique token and validate its value on every POST-back. We further use randomly generated, constantly changing names for all our HTML fields.
  • Overflow proof: all our technologies are Java-based to guard against buffer overflows.
  • Obscured IDs: we use UUIDs for all our identifiers. For practical purposes these are unguessable - avoiding the situation where, say, a user who loads a customer record with an ID of 123 might try to load one with an ID of 124. We further encrypt every UUID relative to the logged-in user, preventing a scenario where one user can snoop an ID and try it under their own login. To maximize performance we store each UUID as a 128-bit integer, not as a String.
  • Encrypted passwords: we encrypt all our passwords using a 10-byte salt.
  • Encrypted cookies: we encrypt all our long-lived cookies, such as 'remember my password' cookies. In addition, we don't them them live too long (i.e. only a month, not a year).
  • Encrypted against embarrassment: we encrypt non-critical, but still sensitive, data using 128-bit AES encryption. This guards against a recent trend towards security breaches that embarrass (e.g. post a list of names and addresses on the Web) rather than alter anything (e.g. obtain login credentials and update data).
  • Sanitized error messages: we sanitize all our error messages to prevent information leakage such as database table names.
  • Sanitized HTTP headers: we suppress all HTTP headers (such as Server and X-Powered-By) that can reveal architectural details of a system and give hackers a head start.
  • Sanitized HTTP responses: we return a login page and a 200 HTTP response whether a page is not found, found but not authorised, or whether there is something suspicious about the request. This 'neutral' response stops hackers narrowing their options of what areas of the system to target.
  • Role based authentication: we use industry standard JAAS and JSA to restrict access to resources.
  • URL parameter filters: we filter all URL query string parameters against JSA roles.
  • Minimized attack surface: all data going to and from the database passes through a single point: a JSR-compliant business rules engine. This enforces validation and security constraints, such as whether the logged-in user is allowed to load or save a given record.
  • Minimal code: we write as little code as possible and reuse it as much as possible, meaning fewer places for security holes to hide.
  • Bot proof: we monitor and block any IPs trying brute-force techniques, such as port scanning or guessing multiple URLs. This protects against botnets and other forms of automated attack.
  • Automated test scripts: we build automated test scripts for all our applications that aggressively try to hack in and either break the code or gain unauthorised access (and we're good at it too - often finding security holes in other people's code)

In addition, we regularly review and update our code to comply with the findings of industry journals and articles such as the Open Web Application Security Project's Top Ten and Improving Web Application Security: Threats and Countermeasures.