We had a bad day yesterday. One of our Domain Admins deleted an OU containing 700+ users and the same amount of computers as well as assorted other useful things like groups etc.
We restored from a backup, but it wasn't pretty.
I know that ADUC asks you if you're sure etc... but I'd like it if it was not possible to delete this particular OU without going into something like ADSIEdit to set it "allowable" for deletion - thereby not allowing people to delete without actually opening a new app and specifically indicating that "YES - I know what I'm doing". This would have the added benefit of stopping accidental miscoding from deleting critical AD objects.
Any such attribute or method that you folks could think of?
There is a feature in AD for Win2k3 and higher to mark an object to prevent accidental deletion. This check box on the object actually changes the underlying permissions for you to remove delete permissions. Therefore it is not tool specific and must be respected by other tools (like powershell and vbscript).
Simply remove the permission to delete things from those unable to get it right. You can give very fine-grained permissions in AD.
There is no "readonly" attribute. That's what the ACLs are for.
You could deny the Delete privalge from Administrators through Delegation at the root level and then you would need to be an enterprise admin to perform deletions. Ensure that no admins are in the Enterprise Admins group for day-to-day usage.
Related
I'm trying to write a secure application that performs a privileged operation on Windows (in particular it changes system time). Because of that I ask the user to run this application with Admin privileges. As one of the first things I want to do in the program is to drop all unnecessary privileges from my access token to limit the impact of any bugs I introduce later. From the Microsoft documentation on the topic I understand that I can either "disable" those privileges via AdjustTokenPrivileges, or create a new access token with "removed" privileges via CreateRestrictedToken and relaunch my application with it. If I understand this correctly the disabled privileges can be re-enabled at any time, so any sufficiently compromised application will just do that and ignore any restrictions I tried to impose. On the other hand, If I remove the privileges completely with CreateRestrictedToken they can't be added back, which sounds safer and what I'd generally imagine under the term "dropping privileges" (also this way sounds like an enormous amount of hassle with the relaunching and such).
I suspect that this understanding might be wrong. What would be the most appropriate way of dropping all but needed privileges in Windows?
My understanding was indeed wrong. Despite what the documentation claims, you can "easily" remove privileges using AdjustTokenPrivileges() by setting the attribute SE_PRIVILEGE_REMOVED to the appropriate privilege in the NewState field.
I'm writing a Windows app that has a time limited demo. There's not going to be a server that the app can phone home to, so I need to store data on the system in order to figure out if the demo has been started and how much time is remaining. The location of this data needs to be obfuscated so that a typical user (and possibly even some power users) are unlikely to be able to find it.
I already know the logistics of how to implement a time limited demo as long as I can store data secretly somewhere on the system, but I'm not sure how to do that last part. The requirements here are:
The data needs to be globally readable and writable so that any user account can access it and modify it without requiring elevated privileges (as the demo applies system-wide and not on a per-user basis)
Preferably it doesn't require elevated permissions to create the data, but if it's necessary to do that once (for example to create the data and adjust its permissions so that everyone has write access) that's acceptable though not ideal.
Whatever method or combination of methods I use to do this needs to work in Windows 7 and later
Does anyone have any idea on how I can accomplish this?
Are there any approaches or architecture design patterns to implement secure, clean role/permission based access control and UI conveniences without coupling them together?
The long story.
I have seen ambiguous use of roles and permissions in many web applications and I have often experienced how these ambiguities have caused misunderstandings and implementation difficulties.
Here is a simplified example.
Business requirements say that permission set for some specific role should deny access to some part of the system that displays a full list of addresses. But at the same time, users of this role will need to read the addresses for an autocomplete list on some other web page.
I have seen how reckless developers create a permission entry to disable access to addresses, and later they discover that users actually need to read the addresses from other parts of the system. Then they invent another specific permission for special cases where addresses can be read.
But for me it seems ambiguous and potentially risky situation. If user has no access to some specific data, then he/she shouldn't be able to access it at all. Period. Adding a special permission just for dropdown lists seems like a deliberate security hole. If user loads the list through an async request and the server is using the same controller action to return the list (and it should - to avoid code duplication), then how the server will know when it should not return the addresses, if they are sometimes forbidden?
This situation raises the question: "why shouldn't users of some specific role see the full list of addresses in the first place, if they have access to the list through some other means?" And the answer I often get from business analysts is something like "Well, the address list is not forbidden for data security reasons, but just because users of this particular role are not expected to do anything with the address list and it would be redundant item in their workspace".
So, now the problem seems clear to me: some permissions exist just for controlling the UI and not strictly for controlling access to some data. Such (ab)use of permissions feels wrong to me. Therefore the question which was given at the very beginning.
Good writing! It pretty much feels that you already have your answer.
IMO user profiling and user access are not the same thing. Access rights should be handled as low level as possible (eg. if or not a user has read-access to a specific SQL table) and profiling in this case should only apply at the UI level ("what the user actually wants or needs to see").
When we talk about an application that has some kind of access right control, there's almost always some kind of an "engine" behind the UI that actually holds all the data. The WORST thing ever you can do is implementing the security anywhere else than the engine itself. The data must never be accessible in any other way than through that engine's own access control or otherwise it's not access control - it's UI restriction.
But that's the perfect world :/ In reality, like in all areas of work, software development also has been driven torwards being more and more cost-effective, agile and responsive to the client. Not surprisingly, this guides people to do fast and cheap decisions... like "hell, let's just make another SQL procedure that pulls the data out as an admin" instead of "we need to re-evaluate user access rights, and/or possible redesign our tables to keep consistency with the access privileges". It's always a short-term (bad) solution WHEN it's done, but some solutions are definitely more NO-NOs than others.
As a guideline I'd say that if you're not 110% sure what you're doing, it's a biggest NO-NO there is.
TL;DR: If some data should be accessible even in one place, it's not restricted by access control. If it's unneccessary to show accessible data somewhere, use user/application profiling for filtering it.
I can tell you where non-admin's aren't allowed to write to:
Environment::GetFolderPath(Environment::SpecialFolder::ApplicationData) + "\\Config.ini";
Environment::GetFolderPath(Environment::SpecialFolder::CommonApplicationData) + "\\monitorService\\Config.ini";
Environment::GetFolderPath(Environment::SpecialFolder::ProgramFiles) + "\\monitorService\\Config.ini";
I had high hopes for Environment::SpecialFolder::CommonApplicationData but sadly that one's off limits for ordinary limited users also. I need a common, easy to, err, know & find, directory where I can load configuration data from and save it to. I suppose I could countenance per-user config files, but I'd rather keep things as simple as possible.
Could I perhaps have my installer set aside some area of the registry or filesystem for universal access? I use Innosetup and .NET code to install. I've noticed (IRC) firefox fills up "Application Data" folders for named and default users so I guess that's another possibility. As the config data is needed by the service it might be too much trouble to store a couple of short strings and ints in anything other than the registry.
Since no one has answered I may as well posit my solution while I go about the implementation.
Limited users only have write access to HKCU. This is the same as using the file system- some user specific branches will be writable. It is hassle to have to check for write access to the global config file at the right time the user logs on and then delegate to user-local config if it throws, but that is what must be done. Being easier to defrag and less of a performance hit I will attempt using the FS before HKCU.
We're building an application designed to run on Windows-based servers. One of the considerations we're looking into at the moment is how to control access to the application's GUI, which allows configuration and controls the "back end" services.
In order to secure the application properly, there are several objects which will need ACLs to be applied - files, directories, Registry keys, named pipes, services etc. We need to provide administrators with some way to configure those ACLs in order to limit access to authorized users only.
One approach we have considered is to create a tool which can modify the ACLs on all those objects simultaneously, but that would be a fair chunk of work and could be fragile.
The other possible approach we're looking at is to create a custom group (e.g. "My App Users") so we can give that group the appropriate rights to each object. This means that administrators will be able to add/remove authorized users by using familiar Windows group membership tools.
So: is creating groups at install time an acceptable thing to do, or is it likely to upset administrators? I'm more familiar with the UNIX world, to be honest, where server-based apps are more or less expected to create groups, but I'm uncertain of the etiquette in the Windows ecosystem.
Also: is there a better solution to this that I've missed?
Thanks in advance!
The question is twofold - one technical, and one political. Technically a local group is fine, you can add AD or domain users into a local group and everyone's happy. In terms of whether an app should be messing with a server's security 'stance', the only reasonable answer is to pop up some kind of request telling the user what you are going to do and asking permission (make sure you also document the decision in some kind of log or entry). This also addresses everybody's legal a$$ eg if they click "no, leave my app unsecured" and get hacked).
Taking a UNIX approach, you could tell the user what you need, suggest a local group (and give the user the chance to pick another local or domain/AD group). Take a look at how (eg) Oracle installs on UNIX do it.
Since this is a server app and you might have to support silent/unattended install, make sure that the behavior can be specified in the install script and very, very sure that the behavior of the script is documented so that no one installs the program without realizing the change in security policy that the installer implements.
I think it's perfectly fine to create a local group for this purpose.
Furthermore I have not been able to come up with a better solution after giving it some thought.
Depending on the size of the implementation, groups could be the way to go.
But please keep in mind that the relevant ACLs on directories and the registry ought to be set. I do agree that setting them once to the group and then let access control be maintained by group memberships.
In regards to klausbyskov's answer, I think a local group could be fine, but consider using LDAP instead. From a security perspective you would detach the authentification process and let the Directory handle it; using kerberos.