Principal Security Issue

Principal Security Issue

Old forum URL: forums.lhotka.net/forums/t/5921.aspx


Alan Shaw posted on Tuesday, December 02, 2008

I think I found a security issue from a developer stand-point.  I can create fake Principal and Identity objects and set them from the application consuming my business objects like shown below...

Csla.ApplicationContext.User = New TestPrinc

Fake Objects...

<Serializable()> _
Public Class TestPrinc
  Inherits BusinessPrincipalBase

  Public Sub New()
    MyBase.New(New TestIdent())
  End Sub

  Public Overrides Function IsInRole(ByVal lstRole As String) As Boolean
    Return DirectCast(Me.Identity, TestIdent).IsInRole(lstRole)
  End Function

End Class

<Serializable()> _
Public Class TestIdent
  Implements IIdentity

  Public ReadOnly Property AuthenticationType() As String _
      Implements
 System.Security.Principal.IIdentity.AuthenticationType

  Get
    Return "Csla"
  End Get

End Property

Public ReadOnly Property IsAuthenticated() As Boolean _
 
 Implements
System.Security.Principal.IIdentity.IsAuthenticated

  Get
    Return True
  End Get

End Property

Public ReadOnly Property Name() As String _
 
Implements
System.Security.Principal.IIdentity.Name

  Get
    Return "My Name"
  End Get

End Property

Public Sub New()
  MyBase.New()
End Sub

'May remove this at some point - kept for possible compatibility to built-in functions - not sure if needed yet.

Friend Function IsInRole(ByVal lstRole As String) As Boolean
  Return True
End Function

End Class

 

Whenever there is a security check for a role, the fake Identity returns True and IsAuthenticated=True no matter what is passed.  This would affects object-level security by a programmer trying to bypass your security while also having knowledge of CSLA--not very likely, but still a potential problem.

A workaround is to place additional code in the Shared (vb) contstructor-replacement and in Get/Set Property calls to a function that perfomed a TypeOf check on the Principal to ensure that it is my custom object or Windows depending on what you are doing.  I have CSLA applications that use both approaches. 

Public Shared Function GetMe(ByVal lboOpenOrders As Boolean) As OrderListRO
  CheckPrincipalIsValid() 
   Return DataPortal.FetchChild(Of OrderListRO)(New SingleCriteria(Of OrderListRO, Boolean)(lboOpenOrders))
End Function

Public Sub CheckPrincipalIsValid() 
    If Not TypeOf Csla.ApplicationContext.User Is System.Security.Principal.WindowsPrincipal Then
       Throw New Exception("Not a valid security descriptor"
)
    End If
End Sub

Does anyone know of a more effective way of handling this?  Can I set the specific type limitation of the Principal object somewhere in CSLA?

 

 

ajj3085 replied on Tuesday, December 02, 2008

Well, if you can't trust developers working on the application, I'm not sure what you can do.  This is one area where having an application server (that is, the dataportal is running in remote mode) might be able to help.. assuming you can lock down the server.  The server code wouldn't have the assembly with the Trojan principal, and so you'd hit an exception when the BO is deserialized on the server.

RockfordLhotka replied on Tuesday, December 02, 2008

So true... If you can't trust your developers you are in deep trouble.

If your data portal is remote, CSLA .NET 3.6 now includes a feature where you can provide a bit of code that is invoked at the very start of each data portal request - before any meaningful user code has run.

However, I must say that a clever developer, who's inserted her own nasty identity class into your app, could pretty easily write an identity object that passed your test, but then would re-instate itself as the current identity later in the process.

If you can't trust your developers you are in deep trouble.

Copyright (c) Marimer LLC