JSON, Homoiconicity, and Database Access

During a recent review of an internal web application based on the Node.js platform, we discovered that combining JavaScript Object Notation (JSON) and database access (database query generators or object-relational mappers, ORMs) creates interesting security challenges, particularly for JavaScript programming environments.

To see why, we first have to examine traditional SQL injection.

Traditional SQL injection

Most programming languages do not track where strings and numbers come from. Looking at a string object, it is not possible to tell if the object corresponds to a string literal in the source code, or input data which was read from a network socket. Combined with certain programming practices, this lack of discrimination leads to security vulnerabilities. Early web applications relied on string concatenation to construct SQL queries before sending them to the database, using Perl constructs like this to load a row from the users table:

# WRONG: SQL injection vulnerability
$dbh->selectrow_hashref(qq{
  SELECT * FROM users WHERE users.user = '$user'
})

But if the externally supplied value for $user is "'; DROP TABLE users; --", instead of loading the user, the database may end up deleting the users table, due to SQL injection. Here’s the effective SQL statement after expansion of such a value:

  SELECT * FROM users WHERE users.user = ''; DROP TABLE users; --'

Because the provenance of strings is not tracked by the programming environment (as explained above), the SQL database driver only sees the entire query string and cannot easily reject such crafted queries.

Experience showed again and again that simply trying to avoid pasting untrusted data into query strings did not work. Too much data which looks trustworthy at first glance turns out to be under external control. This is why current guidelines recommend employing parametrized queries (sometimes also called prepared statements), where the SQL query string is (usually) a string literal, and the variable parameters are kept separate, combined only in the database driver itself (which has the necessary database-specific knowledge to perform any required quoting of the variables).

Homoiconicity and Query-By-Example

Query-By-Example is a way of constructing database queries based on example values. Consider a web application as an example. It might have a users table, containing columns such as user_id (a serial primary key), name, password (we assume the password is stored in the clear, also this practice is debatable), a flag that indicates if the user is an administrator, a last_login column, and several more.

We could describe a concrete row in the users table like this, using JavaScript Object Notation (JSON):

{
  "user_id": 1,
  "name": "admin",
  "password": "secret",
  "is_admin": true,
  "last_login": 1431519292
}

The query-by-example style of writing database queries takes such a row descriptor, omits some unknown parts, and treats the rest as the column values to match. We could check user name an password during a login operation like this:

{
  "name": "admin",
  "password": "secret",
}

If the database returns a row, we know that the user exists, and that the login attempt has been successful.

But we can do better. With some additional syntax, we can even express query operators. We could select the regular users who have logged in today (“1431475200” refers to midnight UTC, and "$gte" stands for “greater or equal”) with this query:

{
  "last_login": {"$gte": 1431475200},
  "is_admin": false
}

This is in fact the query syntax used by Sequelize, a object-relational mapping tool (ORM) for Node.js.

This achieves homoiconicity refers to a property of programming environment where code (here: database queries) and data look very much alike, roughly speaking, and can be manipulated with similar programming language constructors. It is often hailed as a primary design achievement of the programming language Lisp. Homoiconicity makes query construction with the Sequelize toolkit particularly convenient. But it also means that there are no clear boundaries between code and data, similar to the old way of constructing SQL query strings using string concatenation, as explained above.

Getting JSON To The Database

Some server-side programming frameworks, notably Node.js, automatically decode bodies of POST requests of content type application/json into JavaScript JSON objects. In the case of Node.js, these JSON objects are indistinguishable from other such objects created by the application code.  In other words, there is no marker class or other attribute which allows to tell apart objects which come from inputs and objects which were created by (for example) object literals in the source.

Here is a simple example of a hypothetical login request. When Node.js processes the POST request on he left, it assigns a JavaScript object to the the req.body field in exactly the same way the JavaScript code on the right does.

POST request Application code
POST /user/auth HTTP/1.0
Content-Type: application/json

{"name":"admin","password":"secret"}
req.body = {
  name: "admin",
  password: "secret"
}

In a Node.js application using Sequelize, the application would first define a model User, and then use it as part of the authentication procedure, in code similar to this (for the sake of this example, we still assume the password is stored in plain text, the reason for that will be come clear immediately):

User.findOne({
  where: {
    name: req.body.name,
    password: req.body.password
  }
}).then(function (user) {
  if (user) {
    // We got a user object, which means that login was successful.
    …
  } else {
    // No user object, login failure.
    …
  }
})

The query-by-example part is highlighted.

However, this construction has a security issue which is very difficult to fix. Suppose that the POST request looks like this instead:

POST /user/auth HTTP/1.0
Content-Type: application/json

{
  "name": {"$gte": ""},
  "password": {"$gte": ""}
}

This means that Sequelize will be invoked with this query (and the markers included here are invisible to the Sequelize code, they just illustrate the data that came from the post request):

User.findOne({
  where: {
    name: {"$gte": ""},
    password: {"$gte": ""}
  }
})

Sequelize will translate this into a query similar to this one:

SELECT * FROM users where name >= ''  AND password >= '';

Any string is greater than or equal to the empty string, so this query will find any user in the system, regardless of the user name or password. Unless there are other constraints imposed by the application, this allows an attacker to bypass authentication.

What can be done about this? Unfortunately, not much. Validating POST request contents and checking that all the values passed to database queries are of the expected type (string, number or Boolean) works to mitigate individual injection issues, but the experience with SQL injection issues mentioned at the beginning of this post suggests that this is not likely to work out in practice, particularly in Node.js, where so much data is exposed as JSON objects. Another option would be to break homoiconicity, and mark in the query syntax where the query begins and data ends. Getting this right is a bit tricky. Other Node.js database frameworks do not describe query structure in terms of JSON objects at all; Knex.js and Bookshelf.js are in this category.

Due to the prevalence of JSON, such issues are most likely to occur within Node.js applications and frameworks. However, already in July 2014, Kazuho Oku described a JSON injection issue in the SQL::Maker Perl package, discovered by his colleague Toshiharu Sugiyama.

Other fixable issues in Sequelize

Sequelize overloads the findOne method with a convenience feature for primary-key based lookup. This encourages programmers to write code like this:

User.findOne(req.body.user_id).then(function (user) {
  … // Process results.
}

This allows attackers to ship a complete query object (with the “{where: …}” wrapper) in a POST request. Even with strict query-by-example queries, this can be abused to probe the values of normally inaccessible table columns. This can be done efficiently using comparison operators (with one bit leaking per query) and binary search.

But there is another issue. This construct

User.findOne({
  where: "user_id IN (SELECT user_id " +
    "FROM blocked_users WHERE unblock_time IS NULL)"
}).then(function (user) {
  … // Process results.
}

pastes the marked string directly into the generated SQL query (here it is used to express something that would be difficult to do directly in Sequelize (say, because the blocked_users table is not modeled). With the “findOne(req.body.user_id)” example above, a POST request such as

POST /user/auth HTTP/1.0
Content-Type: application/json

{"user_id":{"where":"0=1; DROP TABLE users;--"}}

would result in a generated query, with the highlighted parts coming from the request:

SELECT * FROM users WHERE 0=1; DROP TABLE users;--;

(This will not work with some databases and database drivers which reject multi-statement queries. In such cases, fairly efficient information leaks can be created with sub-queries and a binary search approach.)

This is not a defect in Sequelize, it is a deliberate feature. Perhaps it would be better if this functionality were not reachable with plain JSON objects. Sequelize already supports marker objects for including literals, and a similar marker object could be used for verbatim SQL.

The Sequelize upstream developers have mitigated the first issue in version 3.0.0. A new method, findById (with an alias, findByPrimary), has been added which queries exclusively by primary keys (“{where: …}” queries are not supported). At the same time, the search-by-primary-key automation has been removed from findOne, forcing applications to choose explicitly between primary key lookup and full JSON-based query expression. This explicit choice means that the second issue (although not completely removed from version 3.0.0) is no longer directly exposed. But as expected, altering the structure of a query by introducing JSON constructs (as with the "$gte example is still possible, and to prevent that, applications have to check the JSON values that they put into Sequelize queries.

Conclusion

JSON-based query-by-example expressions can be an intuitive way to write database queries. However, this approach, when taken further and enhanced with operators, can lead to a reemergence of injection issues which are reminiscent of SQL injection, something these tools try to avoid by operating at a higher abstraction level. If you, as an application developer, decide to use such a tool, then you will have to make sure that data passed into queries has been properly sanitized.

How to find your phone – 3 alternatives to the rescue

how to find phone

Have you ever wonder if there is a way of locating your phone in case you lose it or it gets stolen? Well, relax, because the answer is yes! There is a way you can find your phone, how? Here we explain to you three ways of doing it! Keep reading. You have 3 ways of doing it.

How to find your phone

With Panda Mobile Security

Thanks to the mobile and tablet location system in our antivirus for Android, you can recover your device if you lose it!

Panda Mobile Security tracks and displays on a map your lost or stolen tablet or phone so you can find it quickly. You will also be able to block the device and erase all your personal information remotely to prevent others from accessing your most valuable information.

find phone

In addition, our service has an antitheft application that protects the user and ensures the phone’s safety. Panda Mobile Security makes a picture of the user and sends it via email together with the device’s location every time the user fails to enter the password.

If the device runs out of battery, Panda Mobile Security will geo-locate it and save this information, so it can be used later if necessary.

You can also use Google…

To find your Android phone or tablet with Google, you must do it through the site in English, since this feature it is only available in this language.

Once you are in the web site you will only need these three magic words: ‘Find my phone’. This Google search will result in a map, which will display your phone’s location with a precision that may vary a few meters, as the service informs.

In addition, if it is nearby but you still can’t find it, Google can make it ring, even if the device is in silence.

And if you have an Apple device: Find my iPhone

If you are an Apple user and you have lost any of your devices, don’t worry! You can find them with iCloud. Don’t know how, just follow this few steps:

  • Access your iCloud account or use the Find my iPhone app in another device to locate your iPhone, iPad, iPod touch or Mac on a map.
    find my iphone
  • Using Lost Mode you can track your phone, see where it is and where it has been.
  • Once you locate it, you can lock it and send a message with your contact number. So, whoever finds it can call you but can’t access the rest of your information.
  • If you think your device has fallen into the wrong hands, you can remotely erase it and restore your iPhone, iPad, iPod touch or Mac to its original settings.

And last but not least…

Phone locators

When we wrote this article we found lots of webs that offer a series of services which they call ‘phone locators’. But what they actually do is take advantage of those users who have lost their phone or tablet.

So, if we use these web pages, in addition to not finding our cell phone, we will waste our time and money. That is why, we recommend you not to trust any web if it asks you for any kind of financial compensation or personal information!

The best thing you can do to find your cell phone is to use official services like iCloud, Google or the feature included in our antivirus for Android.

The post How to find your phone – 3 alternatives to the rescue appeared first on MediaCenter Panda Security.

URL-Spoofing: Apple Safari Can Be Manipulated Easily

What it’s about

All you need to do so is a bit of Javascript. With just a few lines of it Safari users can be deceived by what’s commonly known as URL-spoofing: During such an attack, a computer user innocently visits a web site and sees a familiar URL in the address bar such as http://www.avira.com but is, in reality, sending information to an entirely different location that would typically be monitored by a cybercriminal.

The security issue was discovered by David Leo, who put together a proof-of-concept for it. When clicking on OK a new website is being loaded. While the address bar tells you that you are visiting dailymail.co.uk the actual page is definitely a different one.

The URL-spoofing itself is done with just a few lines of code:

function f()
{
location=”http://www.dailymail.co.uk/home/index.html?random=”+Math.random();
}
setInterval(“f()”,10);

The last part, setInterval(“f()”,10); , makes sure that the address bar is reloaded ever 10 milliseconds (so you might as well say, that it’s kind of a DDoS attack, too), just before the browser can get the real page and so the user sees the “real” web address instead of the fake one. This causes the spoofed URL to flicker; sometimes it’s even possible to briefly see the actual URL.

What you can do

Your first step should always be to make sure that your browser is up to date so that security updates can be installed once available. In addition to that open up the Safari settings, go to the advanced tab, and choose “Show full website address”. The browser will then show the results of MathRandom in the address bar.

Alternatively you could also just use another browser for the time being: The code will not work in Google Chrome and Mozilla Firefox.

The post URL-Spoofing: Apple Safari Can Be Manipulated Easily appeared first on Avira Blog.

Ubuntu Security Notice USN-2615-1

Ubuntu Security Notice 2615-1 – Alexandre Oliva reported a race condition flaw in the btrfs file system’s handling of extended attributes (xattrs). A local attacker could exploit this flaw to bypass ACLs and potentially escalate privileges. A memory corruption issue was discovered in AES decryption when using the Intel AES-NI accelerated code path. A remote attacker could exploit this flaw to cause a denial of service (system crash) or potentially escalate privileges on Intel base machines with AEC-GCM mode IPSec security association. Various other issues were also addressed.

Ubuntu Security Notice USN-2612-1

Ubuntu Security Notice 2612-1 – A race condition between chown() and execve() was discovered in the Linux kernel. A local attacker could exploit this race by using chown on a setuid-user-binary to gain administrative privileges. Vincent Tondellier discovered an integer overflow in the Linux kernel’s netfilter connection tracking accounting of loaded extensions. An attacker on the local area network (LAN) could potential exploit this flaw to cause a denial of service (system crash of targeted system). Various other issues were also addressed.

Ubuntu Security Notice USN-2611-1

Ubuntu Security Notice 2611-1 – Vincent Tondellier discovered an integer overflow in the Linux kernel’s netfilter connection tracking accounting of loaded extensions. An attacker on the local area network (LAN) could potential exploit this flaw to cause a denial of service (system crash of targeted system).

Ubuntu Security Notice USN-2616-1

Ubuntu Security Notice 2616-1 – Alexandre Oliva reported a race condition flaw in the btrfs file system’s handling of extended attributes (xattrs). A local attacker could exploit this flaw to bypass ACLs and potentially escalate privileges. A memory corruption issue was discovered in AES decryption when using the Intel AES-NI accelerated code path. A remote attacker could exploit this flaw to cause a denial of service (system crash) or potentially escalate privileges on Intel base machines with AEC-GCM mode IPSec security association. Various other issues were also addressed.

Ubuntu Security Notice USN-2614-1

Ubuntu Security Notice 2614-1 – Vincent Tondellier discovered an integer overflow in the Linux kernel’s netfilter connection tracking accounting of loaded extensions. An attacker on the local area network (LAN) could potential exploit this flaw to cause a denial of service (system crash of targeted system). Jan Beulich discovered the Xen virtual machine subsystem of the Linux kernel did not properly restrict access to PCI command registers. A local guest user could exploit this flaw to cause a denial of service (host crash). Various other issues were also addressed.