Monday, February 15, 2016

Is Your E-Commerce Application Secure? Part 1 - Injection

A question came through the pipeline recently about Broadleaf Commerce and how we handle the OWASP top 10 security exploits. This is a pretty important question given the security climate these days and the number of vulnerabilities that have been exposed in the online properties of several major retailers. In the race to build out new features, companies often forget to, or don't make time to, properly harden their e-commerce application for security. They inadvertently use ill advised techniques and practices that leave the door open to savvy attackers, allowing sensitive customer information to be mined or unauthorized operations to be performed. Even security conscious developers can be bitten by third party libraries that introduce security risk they weren't even aware of. Consideration for security should be a first-class citizen in your application design and included in your third party library selection as well. At Broadleaf Commerce, we take security very seriously and strive to provide a framework on which our customers can construct a security hardened e-commerce presence. In this series, I would like to discuss, and dive a bit deeper into, the OWASP top 10 and how we handle these threats here a Broadleaf Commerce. Even if you're not using Broadleaf, this discussion can benefit almost any online application.

To start, here are the OWASP top 10 exploits as of 2013:

  • Injection
  • Broken Authentication and Session Management
  • Cross-Site Scripting
  • Insecure Direct Object References
  • Security Misconfiguration
  • Sensitive Data Exposure
  • Missing Function Level Access Control
  • Cross-Site Request Forgery
  • Using Components with Known Vulnerabilities
  • Unvalidated Redirects And Forwards

This list addresses a mixture of concerns, from development practices to configuration. All, however, are important to consider, since skimping at any point can make unwanted, and possibly disastrous, information available to a hacker.

Today, I'd like to touch on "Injection". The OWASP site describes this flaw as:

"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 goes on further to describe an example attack scenario. Their example is apt, so I'll include it here as well.

Scenario #1: The application uses untrusted data in the construction of the following vulnerable SQL call: 
String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'"; 
Scenario #2: Similarly, an application’s blind trust in frameworks may result in queries that are still vulnerable, (e.g., Hibernate Query Language (HQL)): 
Query HQLQuery = session.createQuery(“FROM accounts WHERE custID='“ + request.getParameter("id") + "'"); 
In both cases, the attacker modifies the ‘id’ parameter value in her browser to send: ' or '1'='1. For example: 
http://example.com/app/accountView?id=' or '1'='1

It's a common application requirement to filter information from the database based on some set of parameters either implicitly or explicitly provided by the user. A straightforward, but naive, approach is to construct the application query logic in such a way that a user submission (in the example case - a http request parameter) is included directly into a SQL query through string concatenation and is executed against the database backing the application. Since not all user's intentions are good, it's possible that mischievous data can be included in the user submission. With a little bit of SQL knowledge, an attacker can submit data that, when combined into the application's dynamic query, can produce a new, valid query that yields unexpected results.

I'm always surprised when I see this is still a common exploit, since there's so much tooling available to help with this kind of problem. The most common technique to protect against SQL injection is to use an API that provides a parameterized interface. In Java applications, JDBC provides such an interface in the form of JDBC prepared statements. Again, from the OWASP site:

String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();

By using a proper prepared statement, the JDBC driver will escape the "userId" parameter, forcing it to remain a filter parameter, rather than allowing it to possibly change the behavior of the query in unanticipated ways.

Of course, many applications abstract away from JDBC and use ORM frameworks on top of JDBC to handle the mapping of the database records to a object model that is more easy for the application to consume. In these cases, the SQL construction is generally handled by the ORM framework (in the case of Broadleaf Commerce, it's Hibernate under JPA). This can end up involving special query languages on top of SQL (Hibernate uses HQL). These special query languages, just like SQL, are not immune to injection problems and should be constructed and dealt with using the same care. JPA and Hibernate both provide APIs that benefit from parameterized HQL query construction to help avoid the pitfalls of string concatenation when constructing queries.

JPA and Hibernate also provide a criteria API for retrieving data that does not involve a SQL or HQL query string, per se. Usage of this API is also protected, as the parameters that are entered using the API are eventually escaped correctly in the same way as the parameterized query example from above.

At Broadleaf Commerce, we are careful to use parameterized queries without string concatenation and we consistently monitor how user supplied data is incorporated into queries made against the datastore. This is just one of the ways in which we strive to provide a great framework for constructing secure e-commerce applications.

In the next installment, I look forward to exploring more of the OWASP top 10.

Monday, May 21, 2012

Broadleaf Commerce Versioning

The idea of semantic versioning came up the other day here in the office and I wanted to blog about this topic and provide some clarity on what our versioning methodology is here at Broadleaf Commerce. Semantic versioning is an attempt to codify the rules around a standard process for determining the version number for any given software release of a particular product. Rather than address every one of the rules here, I'll direct you to the link above for more specific information. I will, however, address some of the key aspects.

Version Formatting


First of all, Broadleaf releases use a major, minor and patch release configuration. This is no different than what is described in rule #2:
A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically by increments of one. For instance: 1.9.0 -> 1.10.0 -> 1.11.0.

Support Releases 


The most interesting part is how we deal with each segment of the version number, and when we choose to increment those numbers. Let's take a closer look at rule #7:
Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.
So far, so good. Rule #7 is in line with our methodology in that we agree to not introduce backwards incompatible API changes or new database schema in our support (or patch) releases. We haven't been the best about this in the past, but we are committed to sticking with this approach going forward. The takeaway here is that one should be able to drop-in a support release of Broadleaf Commerce without experiencing compilation errors or the need to make database schema changes. An example of this would be changing an application's Broadleaf dependency from 1.6.0-GA to 1.6.1-GA.

This raises another point - we will always put a "-GA" at the end of our public releases to the maven central repository. This is different than our other pre-release versions deployed to our Broadleaf Commerce nexus repository. I'll discuss this a bit later.

Minor Releases


Here's where we depart a little from the semantic versioning specification. Let's take a look at rule #8:
Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.
For the most part, our approach coincides with that described above. However, because of the heavy data nature of Broadleaf Commerce, it is often necessary for us to add API and schema changes to support even small functionality. Often these changes may be in support of minor improvements that do not warrant a major release. Because any entity API changes inherently required database changes, then even these small changes make the new version not automatically backwards compatible. As a result, minor release of Broadleaf Commerce are not guaranteed to be backwards compatible. You can expect possible code updates to your application code and schema changes to your database when upgrading a minor release change (e.g. 1.6.0-GA to 1.7.0-GA). In fact, the changes are generally big enough here that a migration document is required to help you migrate from the previous minor release - which we provide as part of the documentation for the new release

Major Releases


Here's rule #9:
Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented.
We definitely adhere to the major version rule, as one can fully expect API changes and schema changes between major releases of Broadleaf Commerce. The main driver for major revisions of Broadleaf Commerce is introduction of major new functionality. While minor revisions may include small new features and improvements to existing features, major revisions include major new features. By limiting major releases to major new pieces of functionality, but not limiting minor revisions to backwards compatible changes, we can keep our major version numbers under control. Otherwise, we could go from version 1 to version 10 in the matter of a year!

Pre-Releases


The last area of interest for us in the semantic versioning specification is the portion that details pre-release versions:
A pre-release version MAY be denoted by appending a dash and a series of dot separated identifiers immediately following the patch version. Identifiers MUST be comprised of only ASCII alphanumerics and dash [0-9A-Za-z-]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
Since we use a maven build methodology here at Broadleaf Commerce, we always have nightly snapshot releases delivered to our snapshot nexus repository for both the current development stream, as well as support streams. This means that users can get the most bleeding edge code from us daily. These versions always end with the word "SNAPSHOT". Therefore, the full snapshot version might look like 1.7.0-SNAPSHOT, for example.

We also periodically release milestone builds that encapsulate various key pieces of functionality prior to a subsequent GA release. These are also considered pre-release builds and take on the letter "M" in the version number to denote the milestone. As a result, the first milestone for a 1.7.0 development branch would look like 1.7.0-M1.

Acquiring Versions


All of our GA releases are available on the maven central repository.

All snapshot builds are available on our snapshot nexus repository at: http://nexus.broadleafcommerce.org/nexus/content/repositories/snapshots/

All of our milestone releases are available on our releases nexus repository at: