Content Query security

From Sense/Net Wiki
Jump to: navigation, search
  •  
  •  
  •  
  •  
  • 100%
  • 6.3
  • Enterprise
  • Community
  • Planned

Overview

In Sense/Net ECMS there are many Content that we consider security critical like users, confidential documents, system content. As this platform is based on Content Query that lets users find content in the Content Repository easily, we need to make sure that noone can access information that he or she does not have permissions for. This article is about how we made querying safe in Sense/Net ECMS.

Text-based querying

When a query can be composed by concatenating strings, there is always some suspicion about security. Take the SQL language for example: one of the most well-known security risks of a badly built website is SQL injection, when you let everybody execute queries directly against the database.

In case of Sense/Net ECMS we can query the repository with Sense/Net Content Query language. It lets you execute complex queries against the Content Repository (actually, the Lucene index). In this article we describe the thinking behind our way of protecting the repository against security leaks, like 'content query injection'.

For more info about composing queries please visit the Content Query syntax article. For details about programmatic ways to execute a query, visit the Content Query API article.

Content Query injection

If the developer or portal builder composes a query of multiple strings (e.g. by concatenation or using a StringBuilder), or substitutes field values into a query using a formatted string, than we must be very cautious about the inserted value. If it comes directly from the UI (e.g. from a textbox), there is a possibility that it tries to modify the query in a bad way. For example:

  • tries to insert a comment (// or /*) to erase the subsequent parts of the query
  • tries to add unwanted filter expressions (e.g. an additional date or path filter)
  • tries to add unwanted modifiers (e.g. autofilters:off)

In the following section you can read about the ways we protect the Content Repository against these kinds of attacks.

UI layer protection

The responsibility of the UI layer (e.g. content views, portlets) is that after executing a query it must not provide more information to users than they need. For example if the count of the results may tell something about the underlying content, than it must not be displayed to the user, not even in an error message.

Permissions

When a user executes a query (or to be precise, the system executes it in the name of the user), the result list will contain only those content that the user has permissions for. There is no way for the user to access other content using a query, only the permitted ones. This is baked into the system, because we filter the result for the appropriate permissions. This means even if somebody hijacked the query somehow, he will not be able to access sensitive information.

Elevated mode

There is a feature in Sense/Net ECMS however that must be taken into account: the elevated mode. A developer can decide to execute a block of code in the name of the administrator instead of the current user. This means even content queries may run in this context and may return results that the user would not be able to access otherwise.

using (new SystemAccount())
{
    //load system content...
}

From version 6.5.2 the following style can also be used:

var parent = SystemAccount.Execute(() => 
{ 
   // ...many lines of code...
   return Parent as GenericContent; 
});

Of course there are system functions that must be executed this way: loading system content (e.g. a user, settings, UI templates) must not depend on the permissions of the current user. It is the responsibility of the developer to make sure that no harmful code can be executed in this mode.

Safe queries

In Sense/Net ECMS there is a Content Query API that lets developers execute text-based queries against the Content Repository. To make sure that no 'modified' or 'hacked' queries can be executed in elevated mode, we introduced a feature called safe queries. This is basically a white list of predefined queries that we allow to be executed when the system runs a code block in elevated mode.

If the code tries to execute a query that is not on this white list and the system is in elevated mode, an InvalidOperationException will be thrown (with the event id 16001). Please follow the link below to the API article to learn how to define and use safe queries.

The white list contains only the pedefined query texts. This means it does not really matter how you construct the query you execute, if the result equals with any of the safe queries, it can be executed in elevated mode - otherwise not.

If a business logic needs to build a query from different sources containing multiple filters (e.g. by using the AddClause method), than it cannot be executed in elevated mode (unless the final constructed query itself is safe of course).

Safe queries does not mean static queries. They can contain parameters for field values (e.g. the path, or content type) to make the query dynamic. Learn more about query parameters in the following article:

OData query

Sense/Net ECMS has a popular OData REST API that is able to execute full queries constructed on the client side. These queries are never executed in elevated mode by the built-in query execution mechanism. Of course 3rd party developers may create custom OData actions that execute the provided query in elevated mode but those queries must be safe queries too.

Indexing passwords

The most sensitive personal data in an ECMS is the password of a user. To make sure that it is safe, Sens/Net ECMS does not index the Password and PasswordHash fields - and this cannot be changed by a configuration, this behavior is hardcoded.

Additionally if a content query text contains "Password" or "PasswordHash" fields (meaning sombody tried to query for them), an InvalidOperationException will be thrown to protect older indexes that may contain these fields.


Related links

References