> -----Original Message----- > From: Mike Soultanian [mailto:[EMAIL PROTECTED] > Sent: Thursday, September 08, 2005 12:05 AM > To: CF-Talk > Subject: Re: Question about my security system > > > I see the point.... but I'm not sure if I agree with the implementation. > > > > What you talking about here is metadata: information about the file. By > > putting all of this in the data base you're adding a level of complexity > > that I just wouldn't be comfortable with. > > Well, it adds flexibility at the price of complexity. It's not *that* > hard to implement it. My first implementation was actually quite easy > to code. And yes, while it is a database lookup, it's a very small > lookup at that so I don't think it should take that much time. I'll > have to research how bad the performance degredation will really be...
I'm not worried at all about performance - performance can be addressed. I don't think anything you've talked about will pose a real challenge in that area - it's all doable. > > The cf_Security tag has to be used (it doesn't have to be used in every > > file, by the way, just a common include that's run for every request). > > you already have a requirement to put something in every file (or in > > common place) but let's say it's included on every page. > > Well, yes, it does need to be included on any template that needs to be > secured (every template in my case). At the time of coding a template, > I will identify what actions are to be performed in that template. I > will then update the cf_security tag to read like this: > > <cf_security permissions=read,write,delete> For some reason I had assumed that all addition of permissions would be done through the GUI... this is clearer. For what it's worth my site works in a very similar fashion and for very similar reasons. The main problem is that Application.cfm can't accept parameters from the page - it's prepended to the page and so nothing on the page can affect it. To get around this in the past (I'm talking CF 4.5) we used "baseinclude.cfm" files which, as a standard, included at the top of every page but preceded by any number of settings, values or whatever (one of which is the security profile). > What happens is when the cf_security tag runs, it will update the > database with those permissions (if it hasn't already been done) and > then I can go into the GUI and find that file and assign groups to each > of those permissions. This makes a lot of sense - the page informs the system. I like that model. > Then, when a user requests the template, cf_security runs and spits out > a structure or some variables set to TRUE for whatever permissions that > the user's group has access to. This is how I am abstracting any > group/user references from the template. The cf_security tag does the > lookup and spits out variables that the calling template can use for its > processing. But would the database actually be storing the page information or just the abstracted permissions? It seems like all of your negatives hinge on storing the page information (page name and location) in the database ALONG with the permissions. But since those permissions are already in the page why does the system need the page? > > But you're also inheriting a need to make every file uniquely named (or > else > > moving files would be a nightmare) and this doesn't mesh with most web > sites > > (which use the same root for every directory). > > Ahh, yes, I've thought this out. Obviously it's a problem if every file > on my site is called index.cfm ;) So, instead, the cf_security tag will > include a unique file security identifier that is automatically placed > in every file that the cf_security tag is place: > > <cf_security permissinos="read,write,delete" FileSID="jasjdj32j42kj3"> This makes more sense... but I'm not sure if the complexity is worth it. It seems like just making sure your permissions are uniquely named would solve the problem. Doing: <cf_security permissinos="MessageRead, MessageWrite, MessageDelete"> would let you ignore the page - you'd be abstracting the permissions. Once ANY page added them you could reuse them for other pages just by adding the name. > As of now, I know of no other way to uniquely identify other than giving > it a unique identifier. I'd just think long and hard on whether you need to uniquely identify the page. Instead just consider uniquely identifying the entitlement and reusing it over and over. This also goes further to eliminating situations were somebody is prevented from performing an action on one page, but can on another because each page has a separate entitlement for the same action. > You know, no, it's not that bad. Where it gets annoying is if you > rename a group. Now you've got a big uh oh. Suppose Admin is now > called Support Staff and I've added a new group called System > Administrators. Now I'd have to edit every file that makes a reference > to each of those groups and could possibly compromise my security by a > stupid editing mistake. I'm not sure I want to get into that discussion again... I think Isaac's still pissed at me. ;^) But I still say this is just convention. The labels don't matter - I could have said "isEntitled(User, 'edit,delete')" instead - it's the same concept: you're labeling things and checking whether those labels are linked to the current user. But even changing the convention from group-based to task-based doesn't eliminate page edits. If you change "delete" to "expunge" (let's say you're having a middle-english kind of day) you have to edit all the files which delete. Or, perhaps more likely, you might decide that "edit" needs to be split to "editContent" and "editAuthor"... or maybe decide that only an admin can delete a thread whereas a moderator can delete a messages... but your initial design just had "delete". Now you have to change all the files that reference those permissions. I'm not saying that what you're doing is bad by any means (in practice it's a lot like what I'm doing and I'm happy with that)... I'm just saying that it doesn't magically eliminate page edits. A thoughtful security model enforced through development is what really reduces that kind of maintenance in my opinion - whichever conceptual model you adopt. You make a convention (in your case task-based entitlements) you define the boundaries and you stick to it. > One thing someone told me is be very careful about building limitations > into your system. On our campus, they are having big problems with a > vendor's application. Apparently the vendor didn't use very good coding > practices and now they're having trouble updating their systems. Yes, > I'm doing a lot of work up-front, but I think it will pay off when I > decide I want to change things around down the road. I can't agree more. > > The think I think you're really troubled about it maintenance, right? > The > > issue of adding a group and needing to change the files and such? > > > > Off the top of my head I could see two possibilities that would make me > more > > comfortable with the idea (and we all want that, right?) ;^) > > > > One idea is to keep the information in the files, but centralize the > > management of it. This is most like the Windows File System model. > > You know, I'd love to do this, but there are two problems. 1) There is > no inherently built in system to uniquely identify a file and 2) storing > the group information in the file has to be done manually through a text > editor. If as part of my app, I built a file editor that would actually > open up the file and assign the permissions and save those permissions > into the file, that would be sweet. However, it's just easier to store > it in the database instead. Well... I think you're already doing what I was suggesting. The entitlements ARE in the files and that's all I was getting at. How those entitlements relate to the larger system doesn't have to be in the files. They could be, but they definitely don't have to be and still allow for a robust system. > You know, I'm curious where NTFS stores all its permissions information. > Does it really keep the permissions for a file in the file itself, or > does it actually store the information in a database and then just keep > track of the file in a central database. You know, I'd guess the latter. In NTFS it's a hybrid model - the basic entitlements are in the files, but much of the security information is in a modified FAT. This works just because the way a FAT works (you can't "unlink" a file from it's FAT entry). Active Directory is a whole 'nother kettle of fish: it stores permissions in an LDAP directory. But Active Directory is really a different beastie - you can assign permissions to machines, printers, shares, etc - not just files. > > <cf_Security roles="" /> > > > > Or even this: > > > > <!--- Inserted by the Security Manager ---> > > <cfset SecurityRoles = ""> > > <!--- Inserted by the Security Manager ---> > > <cf_Security /> > > > This is not a bad idea, but then I would need to build an app that would > handle all the updating. Also, if I decided to rename a group, it would > have to be smart enough to know which files have that group reference > and update them. I could also use find/replace, but that just gets > kludgy again. But this IS what you're doing, isn't it? Your "permissions" attribute is exactly what I'm talking about. Keeping information about who can do what to a file in the file. "Who" in this case isn't a user or a group - it's as simple as "anybody that can do this" (delete, edit, etc). Again - I don't see a systemic difference between saying "anybody that can delete" or "anybody that's an admin". The difference is up to your development conventions to enforce. Don't get me wrong tho' - defining and enforcing that convention is difference between a difficult to maintain and an easy to maintain system... but the underlying system doesn't necessarily need to be limited either way. > Yeah, there would be a ton of files that all have edit in them. The > User template will have that, the message template, and a whole bunch of > others, but so does every file in NTFS. > > > This permission (duh) is needed to delete a user. Now, in good > programming > > practice you create an encapsulated, portable CFC/Custom > > Tag/Function/Whatever to delete the user. That function, of course, > checks > > for that permission. > > aha, no it wouldn't. A properly encapsulated tag doesn't care about > permissions. It just does what it's told. It's the parent template > that's calling the tag that is the deciding factor whether that tag is > run or not. Sorta... there's two ways to look at that. A properly encapsulated tag could (as you say) not care about permissions and just do its job. Or it COULD care about permissions and do its job according to the conventions of the system. (The last interpretation is pretty much the reason that CFCs support per-method security.) For me it depends on whether the component is considered a widely applicable "utility" or a system-specific member of the application. For example something like a spell-checker would not (in my opinion) have system permissions embedded in it - it could be applicable to many, many systems. But something like "DeleteUser" might - it's application to that one application but, potentially many places in it. Personally I go back and forth on it. But for task-based entitlements I'd rather check them at the task. In your case you're saying at the top of the page: I might read, post or delete. I'd rather just ask if I can delete when they try to do it (or before I display the control). Instead of your hard-coded Boolean key list you have a Boolean function that does the exact same job. > haha.. that's funny that you mention fusebox because that throws a whole > wrench into this conversation. I've been doing alot of research on > frameworks this weekend and I have decided that I am going to be using > fusebox for my application. Obviously, the only file that is ever > called is index.cfm. > > So, insead of assigning permissions to files, I'm going to assign them > to fuseactions instead. I am planning on making a plugin (similar to > cf_security) that will intercept the fuseaction that is being called and > then do a similar process like I was planning on doing with my files. > The nice thing about fuseactions is they are all unique! This makes sense - and in the context of FuseBox is actually rather elegant to boot. ;^) My last comment - which actually doesn't affect FuseBox so much since its internally segmented into fuseactions, is a concern for the management interface when you don't have uniquely labeled permissions. For example if you have "edit" in three place (let's say "message", "user", and "forum") then the person managing those permissions really has to know what those pages (or fuseactions) DO to be able to meaningfully assign users to them. This is another argument for unique, descriptive entitlements rather than linking generic entitlements to files (or fuseactions). In fact it will make things more complex (but not so much moreso) but you may want to extend your permission definition model to include more information - perhaps at least a description. You could do this with nested tags pretty easily. For example you currently might have: <cf_security permissions="read,write,delete" FileSID="jasjdj32j42kj3"> You might extend that to something like: <cf_security FileSID="jasjdj32j42kj3"> <permission name="read" description="The ability to read posts."> <permission name="write" description="The ability to write new posts."> <permission name="delete" description="The ability to delete posts."> </cf_security> This (or something like it) might go a long way in preventing people from granting the right person the wrong "edit" entitlement. My last concern would be continuing maintenance. Consider removing a permission. To do it "right" you have to do it at both the database and the file. But you might also see (and I think this is likely) developer's just stop checking the Boolean key... the page would not be doing the task any longer but it would still be requiring permission for it. If the file is the cardinal source of the information then when you remove the entitlement from the cf_security tag you should, on the next page hit, remove it from the database. You'd have to, on every page, make sure not only if the permissions listed are IN the database but make sure that they're the ONLY ones in there. And even then you have an issue where the database won't get updated until the page is parsed again meaning that somebody may fiddle with it while it technically doesn't exist. I'm still just hung up on the per-page system... I think it adds conceptual complexity for very little gain over just making the entitlement labels unique. But in the end, of course, it's whatever works best for you. I'm not gonna be building or using this thing. ;^) Jim Davis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Discover CFTicket - The leading ColdFusion Help Desk and Trouble Ticket application http://www.houseoffusion.com/banners/view.cfm?bannerid=48 Message: http://www.houseoffusion.com/lists.cfm/link=i:4:217605 Archives: http://www.houseoffusion.com/cf_lists/threads.cfm/4 Subscription: http://www.houseoffusion.com/lists.cfm/link=s:4 Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4 Donations & Support: http://www.houseoffusion.com/tiny.cfm/54