I have a large subset of WordPress users in a MySQL database who I want to migrate to Identity Server 4/5.
While I could easily select the data and insert into the ASPNetUsers table, my concern is:
I'm bypassing the controlling application (Identity Server)
Also there appears to be, two cryptographic fields in ASPNetUsers table (SecurityStamp
and ConcurrencyStamp) which I don't know how to generate data for. Not populating them feels like it could lead to interesting side-effects.
What is the best practice in importing a large subset of users programmatically into Identity Server?
Those 2 values just need to be random and in the correct format and don't in themselves hold any meaning. They're just used to check if the DB record has changed since it was loaded.
The main thing to worry about is migration of password hashes. We solved this by having a back channel call to the source system to validate the password the first time the user signs in and then updated the local PasswordHash once we'd verified the provided password was valid.
Related
I am a beginner
A week ago I'm developing a web application in ASP.NET (C #) and using Entity Framework, the application consists of a simple Login system and a series of windows to insert, update delete and select information from the database which brings I get a series of roles (Administrator and Common User). Once the project is completed the idea is that it is housed on a server and can be used by many people
Hata now I have two somewhat silly questions but I want to clear once and for all:
How to know which user has entered? That is, if I enter the correct user and password, in what way will I make a SELECT, an INSERT, an UPDATE or a DELETE? What I do is to make a simple SELECT to the ID (Primary key) taking into account that the user and password match and save this value (INT) in the Session variable:
HttpContext context = HttpContext.Current;
context.Session["identifier"] = primaryKey;
But I recently read this article. It's here when we talk about cookies... even encryption.
What is the safest and most effective way to save the user's
reference?
If there are users administrators, writers, consultants, etc. How do
I design the forms? for example, administrators can publish but common users
can only query information. Will I have to design multiple forms for
each role?
I have thought that the primary key (which is an integer) should not be necessary but rather the user's email or nickname
I have a .NET client app and a PHP server web app.
At some point, the .NET app will have to be identified by a unique id and pass that data to the webserver by http post. The web server will respond with some data and store the unique id in a database.
Assume that I have a malicious user and I would like to ban him by the unique id. So in my opinion there are two important things about this unique id:
The unique id has to be really unique and always the same per computer
A user should not be able to trick the system (a banned user could generate a new id and post it manually to the web server to receive new data)
How can I make sure that the unique id cannot be (easily) generated by a user?
How can I make sure that the unique id can be verified on the server for validity?
What is the usual approach (algorithms, encryptions?) here?
Create UUIDs for all apps and store them into databases after verification and delete/ban/flag UUIDS so they cannot be used again
UUIDs in MYSQL :
http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_uuid
also available in postgres and other RDBMS storage
I have created 10 million lists with uuids multiple times and never once had a collision.
Okay so here I summarize:
Of course there is no perfect security system. Jeremy Miller
Dan's answer is not correct because a MySql UUID is not device dependant and so not fulfilling the condition "the id should be the same per computer"
I should generate an id (like UUID), store it somewhere on the computer in an encrypted form, include a seed in your code then transmit a hash of the id with the seed to your server, requiring every call to include that hash along with some other component which you also include in the hash to verify. Jeremy Miller
This approach is not fool proof because everything stored locally can be removed but at least it is hard to guess a valid generated hash
Okay so my problem is this:
Firstly, user access to the SQL database is controlled by windows authentication, but the app is doing a second check to set user privilege levels within the app.
When I create a new user in my WinForm client App it asks for a password which I then hash with a random salt, these data are then stored in the users table of my SQL database thusly:
users
username, firstName, lastName, pHash, pSalt, accessLevel etc.
When that user, in a later session, tries to log in he gives his password. I pull the salt out of the database and hash the given password.
Now this is my problem: I'm obviously insecure if I pull the hash from the database and compare it with the computed hash locally.
My App maintains a 'user' object that sets a flag for 'authenticated' and has a property that is set based on the 'accessLevel' column in the users table in the database.
There must be a usual way of doing this - or is my answer, you need to be using the SQL Server access facilities to do this not trying to re-invent it in managed code?
You're right in that you can't trust the client to do authentication or authorization. That must be done on the server side.
In your case when you are accessing the SQL server directly from the client you would have to use SQL servers built in functionality for protecting different database objects.
That's usually quite hard to do in a good way though, so a more normal architecture is to create a separate server application such as a WCF service. The clients access the WCF service, which does the authentication and then is in charge of all database operations.
Simple and contrived example:
C# desktop application talks to SQL Server database. All orders exist in Orders table.
Application views, creates and amends orders. In this example a user can only amend their own orders.
Concerns:
Storage of connection string if using dedicated sql credentials.
Even if user credentials are used, application security could be bypassed by connecting directly through Excel or Access.
Solutions:
Provide access to SQL through web service/middleware only. Good, but not necessarily viable in this case.
Encrypt connection string in application somewhere. Not hugely secure, security through obscurity.
Secure database by granting access to specific stored procedures, views, etc and no access to actual tables. SP's and views take into account the user's rights/credentials. Pretty awful. Ok for simple examples (Select where user , becomes complicated once you introduce users in different groups, manager relationships, etc.
Alternatives:
How would you approach this?
Thanks
Even if user credentials are used, application security could be
bypassed by connecting directly through Excel or Access
what do you mean? you should not allow users to connect to SQL Server directly or with Excel or Access. They should NOT know the sa or other password.
After this, surely you could encrypt some sections of your app,config so that nobody can see its content.
I would really have the logic that a user can only modify his/her own Orders at the application level. Could be done also in the stored procedures I guess but it depends and more details should be known about this to suggest the best or most appropriate approach.
Use windows authentication instead of sql authentication.
To allow users to see only their data you can create view and filter data based on the currently logged in user by using SYSTEM_USER to get the data for the current user only and deny select permission on the table itself.
You can't do row level security in SQL Server (well you can, but it's not straightforward). So your only choice to be totally secure is to go through a data-layer which controls access. You can store your credentials encrypted, but that's not totally secure, as you say. It depends what you need.
Well in our application we handle we store the connection string encrypted in a file.
So the user has no direct access to this file.
We also use sql connection only to our database and grant the user for this only.
If you use Windows Credentials to access it and want to prevent any manipulation you can disallow write access to table.
For reading the data you can build queries or access the tables.
For writing/adding/manipulating data you can create stored procedures. One of the parameter is the username. Inside the procedure you build your bussiness logic, impersonate to a user that has write access to finally write/update the data.
There you have your "layer" inside the SQL server.
But I wouldnt suggest to go this way :) It is possible but to many business logic inside the database imho. So the safest way is to find a good encryption class in your language, use sql auth only and store those data inside your code.
We have audit table in our database.
Records to this table are done using triggers.
Currently, there is nothing that prevents user to log on to database server, open table from management studio and change data in audit table.
What are possible mechanisms that can prevent (or at least detect) cases of audit data tampering?
I'm thinking of adding one column in audit table which should contain some hash calculated based on values that are entered in that row. However, since audit is done using trigger, malicious user could open any trigger and see the logic by which this hash is calculated.
EDIT:
I was not clear enough. Application user does not have access to database. I was referring to some user like DB admin, with appropriate rights on database. Still, if this DB admin logins and has rights to temper with audit table, I would like to have some mechanism to detect this tampering at least.
Nothing can prevent someone accessing your database via SQL manager from changing the contents. You can make it tamper evident though.
Basically you need to use HMACs which are keyed hashes. Unfortunately this leads you to requiring key management to ensure the key stays secret which may not be possible in triggers. We use a cryptographic service to provide the key management but this is accessed from code.
You also need to think about a users ability to delete a record rather than change its contents. We ended up with two HMACs, one calculated using the contents of the record (to make changes to a record evident), the second using the current records HMAC and the HMAC from the previous line to make any line deletion tamper evident.
Then you need to worry about deleting the first or last x records. For this we use a trailer and header record which always have the same contents, if those aren't present then the top or the bottom of the table has been deleted. The combined HMAC of the header uses the record after it rather than the record before (as there is no record before).
And, of course, if you are going to be deleting old records to manage the amount of data you store you'll need a mechanism to add a new header record after the deletion.
Here are some possibilities:
You can't prevent or detect tampering by somebody with sysadmin (sa) permissions. If you don't trust your system administrator, you probably have worse problems than this specific one.
It's difficult to prevent or detect tampering by a domain or local administrator. Such a person can restart SQL Server in single-user mode and gain access as a sysadmin using SQL.
To detect tampering by the database owner (dbo), you could use Server Audit in SQL Server 2008 or a server-side SQL Trace in earlier versions of SQL Server.
You can prevent tampering by other users by restricting their permissions to the relevant triggers and audit tables.
you could enable Change Tracking so you have kind of "Audit on the audit table".
if your infrastructure is properly managed I guess users do not have sa rights and they use Management Studio to see the database logging in with their windows account, in this case you can set security on that audit table, only sa and other administrative accounts will be able to change content but not normal users/developer accounts.
Hope this helps.
The problem you're describing may indicate a more serious problem in the architecture of your system.
Usually, users shouldn't even have direct access to the machines running the database.
You may want to consider an architecture where the database machine is separated from your business logic machines, and are accessible only to them.
If your users decide to try to access your servers not through your clients, then all they should be able to do is reach well defined web services that you decided to expose.
There's no reason that a user should be able to access a DB machine, or to have the credentials of an account that is allowed to write to the database. You seem to be worried about tampering with audit information. What's to stop a malicious user from deleting tables or tampering with functional data?
Separate the audit data into its own schema and then set permissions such that the users you're concerned about don't have access to that schema.
Use an entirely separate database which could even be on a different machine.
I often see some type of publish/subscribe model used to publish audit data from a relational database and then asynchronously write that audit data to the audit store.
Perhaps you could have your triggers write audit data to a queue. Then you could have a scheduled job that runs every few minutes to take audit data from the queue and write it to your audit store.