I've got a Python application that connected to Microsoft SQL Server 2000. The application checks for updates on startup and automatically applies them. Soon, it will need to handle database schema changes as well. Based on my research, it seems that creating a baseline script of my current database and then creating a new script for each schema change is the way to go. That way, any version of database can be updated to the newest version.
My question is how do I manage the permissions for these updates? Right now there's about 50 people using my application, most of which have read-only access. Ideally, I'd like any user to be able to perform the necessary changes such as creating or altering tables so that the first person to receive the new update will apply the new schema changes. If that doesn't happen, then he/she might not be able to use the application at all until someone with appropriate permissions updates the database.
I can see a problem occurring if every user can update the schema. What would prevent them from logging into the SQL Server Management Studio and causing issues like dropping tables, etc.?
Right now, this application is only deployed in once place, so it's easy for me to manage schema changes manually. But we do have plans to deploy to more areas and I'd for all this to be handled automatically.
You want to restrict users admin privileges, but at the same time you want them to perform admin activities... Bit of a "chicken and egg" problem :-)
Option 1: Use webapp
Convert your program to run as a web application.
Bit drastic, however, much simpler maintanence. Your users no longer need to install Python, centralized upgrades and a shared connection pool to the database.
This solves your database authentication problem. Users authenticate themselves to the web application, not the database.
I use liquibase to manage my database schemas. It has a servlet listener which can automatically upgrade the database when a new version of my app is deployed. (Liquibase also has a command-line interface for use by alternative technologies like Python).
Option 2: encrypt admin password
You encrypt the admin password and make it available as a text file retrievable from a corporate web server, enabling any users application to download it at startup.
There is a security issue with this solution.... In order to decrypt the admin password, a shared secret needs to be built into your python application.... This is security by obscurity.
Related
I'm looking for a one click system that doesn't require one to delete the Azure database, publish from the local server, and re-create the user info onto the deployment.
What currently works:
Drop existing Azure database.
MSDeploy the database to azure.
Move the database to the app pool
Configure Azure database user/access
I briefly looked into the Azure sync, but that doesn't seem like something one can use "on request". Do correct me with example if I'm wrong on this assumption.
The ideal solution would be a one button click from Azure Data Studio to push any and all changes from the (localdb) database to the live one.
Azure Data Studio doesn't provide any readymade Single Click data transmission feature from local to cloud or vice-versa.
Azure Data Studio offers a modern editor experience with IntelliSense,
code snippets, source control integration, and an integrated terminal.
It's engineered with the data platform user in mind, with the built-in
charting of query result sets and customizable dashboards.
It doesn't provide in-built data push feature. Either you should use any programming language to build a dashboard as per your requirement, or you need to use Store Procedure for it.
In our shop we store credentials for Test and Prod resources in a secured vault and our CI/CD pipelines manage retrieval and provide access by the apps to those credentials at run time. This works great.
However, the vaulting mechanism is not accessible from a local development workstation which makes management of credentials to our Dev database a hassle.
Various mechanisms have been suggested:
1. give each dev access to the DB on their specific credentials
The concern here is that apps are not owned by specific teams so anyone new to the code base would need to request db accesses to be setup.
use a common account and share credentials among the team
One sharing approach suggested is to check the shared credentials into the code repo as an environment specific configuration. provided those credentials have limited access (dev db, read,write permissions) and the data bears no relation to real data, its low risk. (We also have on-premise code repository thats not publicly accessibly)
Another is to store the creds in plain text on a secured location. But that requires the dev to locate the creds each time they get a local copy of the code.it also opens the risk that a file setup for the app gets inadvertently checked into the code repository. (see above)
What are others doing to solve this problem?
A couple alternate options that I've done.
Get everyone use a local db - understand this might not be viable depending on your scenario. DEVs could restore their local databases from backup (taken from say a test environment), OR (for new/greenfield projects), you could use a local containerised database where all DDL and config data is created via database migration framework - the latter is what we do at my workplace (we're using SQL Server and DbUp as migration framework). Note: we're not seeding the database with test data, but this is something you can also look into...
Use git-crypt (or something similar) for transparent encryption and decryption of specific files in a git repository e.g. config file containing database password.
Microsoft recommends using Windows authentication when connecting a Windows application to an SQL server database.
http://msdn.microsoft.com/en-us/library/89211k9b.aspx
I understand this to mean that the database must have a user with enough permissions to manipulate data and that user links to the currently logged in Windows user. If this is true, how do I prevent the user from bypassing the application and simply modifying data directly in the database?
It seems like I am stuck between using Windows Authentication and potentially allowing users to modify data directly in the database, or attempting to hide the connection string password somewhere so only the app can modify this data.
If you're that concerned about it, you can implement a logon trigger on the server that for certain people (e.g. members of a certain Windows group), they can't log in unless the application name has a certain value. Note that this is weak security since it's pretty easy to set the application name (even in SSMS). It can/will slow down the logon process, though. So keep that in mind if that's a concern for you.
Alternatively, you can have your application authenticate to and interact with an application server, after which the application server connects to and interacts with the database. The application server can run as a service account, to which you'd grant the permissions you need. This way, the end users' accounts aren't in the database to do raw DML against the db.
But I agree with the other answer here: stored procedures are the classic answer to this question.
It is possible to create stored procedures / views etc and only allow the user permission on those. This prevents the user from accessing the database structure directly, and you maintain control over what the user can do (via creating the functionality in the stored procedures / views). If using windows credentials, I think that this would be the best solution.
This site explains how to grant there permission on stored procedures.
http://msdn.microsoft.com/en-us/library/ms345484.aspx
Here is the list of options, for posterity:
Windows authentication only
Pros: simple, No secret to hide.
Cons: user can easily modify data bypassing your app
Password in connection string
Pros: simple, prevents user meddling in your db's.
Cons: have to hide a password yourself, which is always the worst option.
Sprocs access
Create sprocs to access your data, grant access only to those sprocs. No one but the dbo can alter tables.
Pros: Tightest control over what both the user and the application can do to the data
Cons: Higher coupling of database and application; more expensive than the first 2 options.
Proxy
Create a second executable, whether a web or a windows service, with which your GUI application communicates. The 2nd executable can run with different, securely hidden credentials (IIS, Windows Services).
Pros: Decoupled database and executable, securely hidden secrets.
Cons: By far the most expensive solution.
Good day all,
I am studing the following case:
Scenario: An application connects to the production database(SQL server 2008) using a generic "SA" user instead of the domain user. This is making traces\logs\organization harder, because everything is flagged as done by SA user!
NOTE: In the application the domain user/password is used, the generic account is only regarding to the database.
Questions: What would be the best pratice in this case? every user should have an account to log in the database? (sql using windows authentication) there are +- 500 users is that an issue regarding to database performance? or a generic account is indicated?
Many thanks!
As others have mentioned, Active Directory and Windows Authentication might be more appropriate if that's an option. But if not...
If the application has a central place that creates the connection & transaction prior to update, you may be able to use SET CONTEXT_INFO to pass along the "real" application user while still using a shared SQL account for the login.
Then in your auditing triggers you can pull the information back out again using the CONTEXT_INFO() function
This is the approach used by at least one commercial auditing tool
See also similar SO questions here and here which reference context_info and a blog post Exploiting Context_Info for Fun and Audit which gives an NHibernate example.
Nitpick on something else in your question: you said it's using sa user. Maybe that was just an example, but probably the application should not have so many rights on the server. Create a user with only the rights needed for the particular database(s) that application uses. This limits the impact of any future security vulnerability (e.g. SQL Injection) in your application. And to take it one step further, you might have one connection string with a read-only user account, and then at the point where you create a transaction to update data, switch to a connection string with the read/write user account. You still get most of the benefits of connection pooling, but you limit even further the impact of any application-tier bugs.
I have a question that really feels like I should have an easy answer to, but for one reason or another I haven't been able to totally reason around it.
I'm embarking on development of an ASP.NET MVC3 intranet application, and I'm currently working on designing authentication & authorization. We're forced to use basic authentication in our environment, and we use Active Directory, so the authorization part is generally taken care of. Unfortunately our role/user hierarchy in active directory doesn't mirror what I need for the roles in the application, so I'm going to have to define my own.
I'm using SQL Server, so I was originally thinking of using stored procedures for all DML, and then creating roles and adding users in roles in SQL Server, and then controlling access to the stored procedures via those roles. I was also thinking I could query for those SQL Server database-level users & roles in order to use that as the source of authorization info in the application itself. That originally seemed like a great idea, but it doesn't seem like a popular one (for one, it seems the queries for that are a little long and messy for what they produce). Alternatively, would it be better to have the web app impersonate a user for all queries to the server, and then implement a user/role database with my own schema, and only authorize on the application side?
It originally seemed that authorizing on both the application and database side would be a good thing for security, and using the SQL Server user/role objects means that the user and role data wouldn't need to be stored in two places.
I did see some potentially relevant discussion at Best practice on users/roles on SQL Server for a web application, but I think this is a different question overall.
Thanks!
I recommend creating a sql login that the web application will use to connect to sql server. This way you are not impersonating any specific AD account which may get deleted, disabled in the future and can control the user strickly in SQL Server.
I would then recommend implementing roles based authentication in your application. This will enable you to create users and roles that are custom to your application and then assign users to them. This way if a user tries to access a resource that their role is not allowed it will not do any work. Here is a demo app based on this principle http://www.codeproject.com/KB/web-security/rolesbasedauthentication.aspx.