NYCPHP Meetup

[nycphp-talk] Not-so-subtle attack on PHP

bz-gmort at beezifies.com bz-gmort at beezifies.com
Fri Sep 28 13:57:11 EDT 2007


John Campbell wrote:
> On 9/28/07, Kenneth Downs <ken at secdat.com> wrote:
> 
>>   I will claim that putting security
>> directly into the database is better than any other way because it does what
>> is needed in the end with the least possible work.
> 
> I must be missing something.  Take a simple social networking
> scenario: A user can only see another user's complete profile if and
> only if they are mutual friends.  Implementing that in the tables
> would be a huge pain in the ass and incur a big performance penalty.
> Is there some super easy way to implement this that I am missing?


It would?

Think of the profile information as follows:
ProfileTable
Username, userid, fullname, address, emailaddress, bio, Recordid
FriendTable:
Recordid, friendid


So, in the classic sense, if someone loads a profile, you might do a 
join between friendtable and profiletable and add a where clause where 
the friendid equals your userid- if you get data from it you display it. 
  Otherwise, you would pull just the public information.


In a DB driven sense, you would have:
ProfileTable
Username, fullname, address, emailaddress, bio, Recordid
FriendTable:
Recordid, friendusername

PublicProfiles:
A select only view of ProfileTable having only:
username, fullname, bio

And then for each and every userid, you have created automatically a set 
of views:
Myusername.friendprofiles
select Username, fullname, address, emailaddress, bio from profiletable 
where recordid in (select recordid from friendtable where friendusername 
= 'myusername')

(and to extend it a bit, you would also have a view for update:
Myusername.myprofile
select Username, fullname, address, emailaddress, bio from profiletable 
where username = 'myusername')


Now from the application perspective, you have 2 queries:
First you do a select to the myusername.firendprofiles table and if you 
locate the user your looking for, display the full data.
Second, if no record is found, than check the publicprofiles table for data


The important point here is that the only view you have UPDATE authority 
to is myusername.myprofile, wheras you have select authority on 
myusername.friendprofiles and publicprofiles.  You have no direct access 
to the profiletable.


Now, assume for a moment that the user get's some SQL injected past the 
program.

In the first case, since all the queries are run against the 
profiletable, the user can then view the private informaiton of other 
users(and worse, can change it since they have edit authority to edit 
their own record!)

With the view level security, the only view they can update is 
myusername.myprofile - so they can only change their personal record. 
As for selecting data, they can only select from the 
myusername.friendsprofile and myusername.publicprofiles.

Since the only data in those views is the data they are allowed to see 
anyway, even if they manage an SQL injection they still can't view data 
they were not authorized to access.





More information about the talk mailing list