Breeze is a numerical processing library for Scala. ScalaNLP

Knockout - Using foreach and sort together

I am having trouble combining the foreach binding with a sort. I have a list bound like so:

<article data-bind="foreach: widgets">  

Widgets is a simple obvservable array:

var widgets= ko.observableArray();

This works nicely giving me a list of my "widgets". If I add a new "widget" to this list then it appears dynamically in the list via data binding.

However as soon as I add sorting to the array:

<article data-bind="foreach: widgets.sort(function (left, right) { return left.order() == right.order() ? 0 : (left.order() < right.order() ? -1 : 1); })">

Then newly added widgets no longer appear in my list - unless I reload the page. (The sorting works nicely at this point - if I update the "order" field that I am sorting on then the items in my list are dynamically re-sorted).

How can I go about getting the sorting to play nicely with the dynamic updating of new items in my observable array?

I am using Breezejs in order to retrieve my data, however I do not think that is impacting on this scenario.

Source: (StackOverflow)

Securing Breeze on the server to prevent malicious updates to foreign keys

The Problem

I'm just trying to figure out exactly how much of my own security I need to implement on the server side when saving changes in Breeze. In particular, I'm thinking about how a malicious user could manually hack the SaveChanges request, or hack the javascript in the client, to bypass my normal business rules - for example, to maliciously alter foreign key IDs on my entities.

I want to understand exactly where I need to focus my security efforts; I don't want to waste time implementing layers of security that are not required.

I'm using Breeze with .net and Entity Framework on the server side.


Here's a trivial example. ObjectA has a reference to an ObjectB, and ObjectA is owned by a particular User. So, my database looks like this:


Id    ObjectB_Id    SomeField          User_Id
1     1             Alice's ObjectA    1
2     2             Bob's ObjectA      2


Id    SomeOtherField
1     Foo
2     Bar


Id    Name
1     Alice
2     Bob

From this model, the security concerns I have are:

  1. I don't want unauthenticated users to be changing any data
  2. I don't want Bob to be able to make any changes to Alice's ObjectA
  3. I don't want Alice to try to point her ObjectA at Bob's ObjectB.
  4. I don't want Bob to try to change the User_Id on his ObjectA to be Alice.

The solution for (1) is trivial; I'll ensure that my SaveChanges method has an [Authorize] attribute.

I can easily use Fiddler to build a SaveChanges request to reproduce issues 2 to 4 - for example, I can build a request which changes Alice's ObjectA to point to Bob's ObjectB. This is what the message content might look like:

        "SomeField":"Alice's ObjectA",

As I'd expect, when no security is implemented on the server side, this persists the updated value for ObjectB_Id into the database.

However, I've also confirmed that if there is no entry for ObjectB_Id in the originalValuesMap, then even if I change the value for ObjectB_Id in the main body of the message it is NOT updated in the database.

General Rules?

So, I think this means that the general security rules I need to follow on the server are:

[Edited 4 July 2013 - rewritten for clarity]

In general:

  • Nothing in the message can be trusted: neither values in the originalValuesMap nor supposedly "unchanged" values
    • The only exception is the identity of the entity, which we can assume is correct.
    • Supposedly "unchanged" properties may have been tampered with even if they are not in the originalValuesMap

For "Unchanged" properties (properties which are not also on the originalValuesMap):

  • When "using" any "unchanged" property, we must NOT use the value from the message; we must retrieve the object from the database and use the value from that.
    • for example, when checking owenership of an object to ensure that the user is allowed to change it, we cannot trust a UserId on the message; we must retrieve the entity from the database and use the UserId value from that
  • For any other "unchanged" property, which we are not using in any way, we don't need to worry if it has been tampered with because, even if it has, the tampered value will not be persisted to the database

For changed properties (properties which are also on the originalValuesMap):

  • Business rules may prevent particular properties being changed. If this is the case, we should implement a check for each such rule.

  • If a value is allowed to be changed, and it is a foreign key, we should probably perform a security check to ensure that the new value is allowed to be used by the session identity

  • We must not use any of the original values in the originalValuesMap, as these may have been tampered with

[End of edit]

Implementing the Rules

Assuming that these rules are correct, I guess there are a couple of options to implement security around the changed foreign keys:

  • If the business rules do not allow changes to a particular field, I will reject the SaveChanges request
  • If the business rules DO allow changes to a particular field, I will check that the new value is allowed. In doing this, CANNOT use the originalValuesMap; I'll need to go to the database (or other trusted source, eg session Cookie)

Applying these rules to the security concerns that I gave above,

  • security concern (2). I'll need to check the user identity on the session against the User_ID on the ObjectA that is currently in the database. This is because I cannot trust the User_ID on the request, even if it is not in the originalValuesMap.

  • security concern (3). If the business rules allow a change of ObjectB, I will need to check who owns the new value of ObjectB_Id; I'll do this by retrieving the specified ObjectB from the database. If this ObjectB is not owned by ObjectA's owner, I probably want to reject the changes.

  • security concern (4). If the business rules allow a change of User, this is already covered by (2).


So, really, I'm looking for confirmation that I'm thinking along the right lines.

  1. Are my general rules correct?
  2. Does my implementation of the rules sound reasonable?
  3. Am I missing anything?
  4. Am I over complicating things?

Source: (StackOverflow)