Asegurar Breeze en el servidor para evitar actualizaciones maliciosas a claves externas

El problema

Solo estoy tratando de averiguar exactamente cuánto de mi propia seguridad necesito implementar en el lado del servidor al guardar los cambios en Breeze. En particular, estoy pensando en cómo un usuario malintencionado podría piratear manualmente la solicitud de SaveChanges, o piratear el javascript en el cliente, para pasar por alto mis reglas comerciales normales, por ejemplo, para alterar de manera malintencionada las identificaciones de claves extranjeras en mis entidades.

Quiero entender exactamente dónde debo enfocar mis esfuerzos de seguridad; No quiero perder tiempo implementando capas de seguridad que no son necesarias.

Estoy usando Breeze con .net y Entity Framework en el lado del servidor.

Ejemplo

Aquí hay un ejemplo trivial.ObjectA tiene una referencia a unaObjectByObjectA es propiedad de un particularUser. Entonces, mi base de datos se ve así:

ObjectA:

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

ObjectB:

Id    SomeOtherField
1     Foo
2     Bar

User:

Id    Name
1     Alice
2     Bob

Desde este modelo, las preocupaciones de seguridad que tengo son:

No quiero que los usuarios no autenticados cambien ningún dato.No quiero que Bob pueda hacer cambios a Alice'sObjectANo quiero que Alice intente señalarlaObjectA en casa de BobObjectB.No quiero que Bob intente cambiar elUser_Id sobre suObjectA ser alicia

La solución para (1) es trivial; Me aseguraré de que mi método SaveChanges tenga un[Authorize] atributo.

Puedo usar Fiddler fácilmente para crear una solicitud SaveChanges para reproducir los problemas 2 a 4; por ejemplo, puedo crear una solicitud que cambieAliceEl objeto A para apuntar a BobObjectB. Este es el aspecto del contenido del mensaje:

"entities":
[
    {
        "Id":1,
        "ObjectB_Id":2,
        "SomeField":"Alice's ObjectA",
        "User_Id":1,
        "entityAspect":
        {
            "entityTypeName":"ObjectA:#MyNamespace",
            "defaultResourceName":"ObjectAs",
            "entityState":"Modified",
            "originalValuesMap":
            {
                "ObjectB_Id":"1"
            },
            "autoGeneratedKey":
            {
                "propertyName":"Id",
                "autoGeneratedKeyType":"Identity"
            }
        }
    }
],

Como es de esperar, cuando no se implementa seguridad en el lado del servidor, esto persiste el valor actualizado paraObjectB_Id en la base de datos.

Sin embargo, también he confirmado que si no hay entrada paraObjectB_Id en eloriginalValuesMap, entonces incluso si cambio el valor deObjectB_Id en el cuerpo principal del mensaje NO se actualiza en la base de datos.

¿Reglas generales?

Entonces, creo que esto significa que las reglas de seguridad generales que debo seguir en el servidor son:

[Editado el 4 de julio de 2013 - reescrito para mayor claridad]

En general:

No se puede confiar en nada en el mensaje: ni los valores en el originalValuesMap ni los valores supuestamente "sin cambios"La única excepción es la identidad de la entidad, que podemos asumir es correcta.Las propiedades supuestamente "sin cambios" pueden haberse alterado incluso si no están en el originalValuesMap

Para las propiedades "Sin modificar" (propiedades que no están también en el OriginalValuesMap):

Cuando "use" cualquier propiedad "sin cambios", NO debemos usar el valor del mensaje; debemos recuperar el objeto de la base de datos y usar el valor de eso.por ejemplo, al verificar la propiedad de un objeto para garantizar que el usuario tenga permiso para cambiarlo, no podemos confiar en un UserId en el mensaje; debemos recuperar la entidad de la base de datos y usar el valor UserId de esePara cualquier otra propiedad "sin cambios", que no estemos usando de ninguna manera, no debemos preocuparnos si se ha manipulado porque, incluso si lo ha hecho, el valor manipulado no se conservará en la base de datos.

Para propiedades modificadas (propiedades que también se encuentran en el originalValuesMap):

Las reglas comerciales pueden evitar que se modifiquen propiedades particulares. Si este es el caso, deberíamos implementar una verificación para cada regla.

Si se permite que se modifique un valor y es una clave externa, probablemente deberíamos realizar una verificación de seguridad para garantizar que la identidad de la sesión permita que el nuevo valor sea utilizado

No debemos usar ninguno de los valores originales en el originalValuesMap, ya que estos pueden haber sido manipulados.

[Fin de edición]

Implementando las Reglas

Suponiendo que estas reglas son correctas, supongo que hay un par de opciones para implementar la seguridad en torno a las claves externas cambiadas:

Si las reglas de negocios no permiten cambios en un campo en particular, rechazaré la solicitud de SaveChangesSi las reglas comerciales SÍ permiten cambios en un campo en particular, verificaré que se permita el nuevo valor. Al hacer esto, NO PUEDES usar eloriginalValuesMap; Tendré que ir a la base de datos (u otra fuente confiable, por ejemplo, cookie de sesión)

Aplicando estas reglas a las preocupaciones de seguridad que mencioné anteriormente,

preocupación de seguridad (2). Tendré que verificar la identidad del usuario en la sesión con elUser_ID sobre elObjectA que se encuentra actualmente en la base de datos. Esto se debe a que no puedo confiar en el ID_de_usuario en la solicitud, incluso si no está en eloriginalValuesMap.

preocupación de seguridad (3). Si las reglas de negocio permiten un cambio deObjectB, Tendré que comprobar quién posee el nuevo valor deObjectB_Id; Haré esto recuperando el ObjectB especificado de la base de datos. Si estoObjectB no es propiedad deObjectAEs probable que quiera rechazar los cambios.

preocupación de seguridad (4). Si las reglas de negocio permiten un cambio deUser, esto ya está cubierto por (2).

Preguntas

Entonces, realmente, estoy buscando confirmación de que estoy pensando en la dirección correcta.

¿Son correctas mis reglas generales?¿Mi implementación de las reglas parece razonable?¿Me estoy perdiendo algo?¿Estoy sobre complicando las cosas?

Respuestas a la pregunta(2)

Su respuesta a la pregunta