How to handle the users deletion of their account from a website? - database

As a developer, how should a users deletion of their account from a website be handled?
In the case of someone guessing the users password and deleting their account, you would want to be able to reinstate the account, so deleting it instantly and fully can't be the answer.
On the other hand if you are sure you want to delete an account it would still be in a backup for some time.
Is there a best practice for handling account deletions?

This is usually handled via so-called "soft deletes", which mark a record as deleted but don't actually delete it.
This is a common scenario in many frameworks. For example Laravel uses a deleted_at timestamp property, so you can delete an account, and then run a scheduled task to really delete records that a were deleted more than a certain amount of time ago, say a week. "Undeleting" an account simply requires setting that field to null.
Soft deletes are useful for the inevitable "but I didn't mean to delete it" scenarios, but also when you perhaps have other tasks that need to be done when you delete a user account, for example removing data from 3rd party services that you have shared the data with, such as mailing list services.
While you may have a legal requirement to delete data under GDPR when requested, it's not absolute and depends on your basis for processing. For example you may be legally obliged to retain records for a certain amount of time, or you may have a contractual requirement to retain records until the account has paid all its bills.
You shouldn't be relying on soft deletes as a defence against password guessing – a strong password policy and 2FA should have a much higher priority against that.

I would add one more boolean field to the user account record called for example "IsDeleted". It will be an indicator that the user account has been deleted. Also, adding deleted DateTime could be useful to determine later if you should completely purged that user account record.
The best practice is to keep it simple.

Related

Is it a security risk if someone knows a salesforce account id?

I'm 90% sure that the answer is no but I would appreciate your thoughts.
Scenario: We build a system that uses Salesforce record IDs to locate information. This system is now shared with people outside our company thereby sharing record IDs. (It goes without saying that we do not expose our instance ID nor any credentials of authentic users within our organization. The only type of information that is visible is the record id.)
Is there anyway a malicious person could use the record ID and cause damage: either reading the data or worse?
I don't think so. Even if someone gets your instance ID, the only thing he could do is to spam your system (and may be make you out of API calls), but nothing more. Revealing of record ids is just okay.

How do I design my application such that audit trails cannot be edited or deleted?

I have this problem where I need audit trails (typically stored in DB) to be non-editable and deletable even for DBAs and System Admins.
1 way is to apply encryption and checksums, but this only allows detection of changes or prevention of snooping. It does not prevent a DBA to just delete a row.
Any discussion on this matter is appreciated.
If you want the audit trails to be non editable even by the DBAs and system admins, you would need to store them outside of equipment that is in their control.
However that would lead to the same problem - the DBAs and system admins of this system would be able to edit them.
The best bet is to have a system where you store these in two disparate locations that do not share an admin and have periodic comparision checks.
Alternatively you can have triggers on update/delete when they are made by a specific user or from a particular client. These triggers could be programmed to send email or text messages if such a non-application update or delete is made.
It should be known - very well known in the admin/dba community that such triggers exist. You wil not be able to prevent the updates or deletes but will definitely get them to stay away from that table.
There is still a catch however, which is the ability to remove or modify the trigger code.
There exists "write-once" archival storage systems, such as Venti from Plan 9. That doesn't stop anyone with physical access taking a magnet to the hard disk or similar of course ;)
A sufficiently savvy sysadmin could create a slightly modified version of the data and replace the reference to the venti score though... and an equally savvy sysadmin could still recover the original data.
Anyway, I think you could learn a lot from studying append-only storage systems. They make a lot of sense for storing audit trails, compared to a DB.
There exists appliances that act as sniffers and are able to record every single command executed on the database. IBM Guardium is an example.

Should I add a field like MarkedAsDeleted to my table?

I'm building an ASP.NET MVC application with SQL Server. I would like to know what will be a good practice for record deletion operations. I mean, when an item is deleted via web application, I would like to mark it as deleted, and then from an admin console, I will purge them if needed.
Is this a good practice? Should I use or avoid?
Thank you.
There is nothing wrong with this approach if you have no issues with storage space. Typically, we will use this pattern if the object being deleted is tied to other object (for instance, if you were tracking changes by user id, then you would not want to delete the user because you would not be able to pull info for that user later on). Simply mark a bit field showing the record has been deleted and filter those out when you query.
Again, it really depends on what makes sense for you and your application. Will you ever need this object again? Is it tied to other items in the database? Do you want to offer the user the option to 'undelete'? If the answer to any of those questions is yes, then you should probably keep the record. If the answer to all of those is no, then I would ask, why would you not just delete the record at the time it was requested?

How to ensure that a user in Rails can update/insert/delete only his/her record in a database

Sorry if this is an elementary question but I've just started to consider whether I've been doing this correctly all along. Usually when a user tries to update the database, I simply use his/her username as the key in a user table and then base all operations on that. However I just realized that a crafty user MIGHT be able to submit a query using another username name thus circumventing this weak form of enforcing entitlements. So my question really is how do I prevent a user from potentially submitting a destructive action against a database under a different userid?
You should store the current user's ID in the session, which isn't easily manipulated.
I usually refer to the objects through a relation on a User object:
current_user.fragile_records.find(params[:id]).destroy
It's a readable and simple way of doing an ownership test.
http://guides.rubyonrails.org/security.html is a surprisingly good read on the subject.
There are plenty of readymade solutions for maintaining user identity (authentication) and ensuring user has clearance for an action (authorization) in Rails.

Audit trails and implementing SOX/HIPAA/etc, best practices for sensitive data

I consider myself to be relatively proficient in terms of application design, but I've never had to work with sensitive data. I've been wondering about what the best practices were for audit trails and how exactly one should implement them. I don't have to do it right now, but it'd be nice to be able to confidently talk with a medical company if they ask me to do some work for them.
Let's say we have a "school" database, with 'teachers', 'classes', 'students' all normalized in a many-to-many 'grades' table. What would you log? Every insert/update on the 'grades table'? Only updates (say, a kid breaks in and wants to change grades, this should send up redflags)? Does this vary entirely based on how paranoid one wants to be? Is there a best practice?
Is this something that should be done in the database? (A trigger on each sensitive SELECT which inserts a row to an 'audit' table logging each query?) What should be logged? Is there functionality automatically built into Oracle/DB2 that do it for you? Should this be application side logic?
If anyone has any formal documentation/books on how to deal with sensitive data (not quite DoD "Trusted Computing" spec, but something along the lines of that :P), I'd appreciate it. I'm sorry if this question is terribly vague. I realize that this varies from application to application. I just want to hear your detailed experiences with dealing with sensitive data.
The first thing to understand is the native auditing capabilities of your chosen DBMS. These vary in detail, but generally provide a way to configure which operations are audited, and provide secure storage for the audit records that they generate.
The next thing to understand is what you want to audit. In the case of HIPAA and SOX, for example, you are probably looking at PII - Personal Identifying Information. Remember the fuss made about people accessing Obama's phone records, or various celebrities medical records, or ... Those were caught because the system audited who read those records, and the audit analysis officer (AAO) spotted that the celebrity records were accessed by people who were not specifically authorized to do so. So, those systems must be logging who accesses each record, and spotting when the user who does so does not have an authentic business reason to do so. In these cases, it appears that the users had read authority for the records, so if their ordinary duties required them to look at the records, they could do so. But, when they were not required to do so, then they were abusing their power and appropriately sanctioned (up to and including losing jobs over it).
What this means is that you probably don't want to track who accesses the table of States which records the state code and full name (and assorted other bits of information about the state). There is nothing confidential about that list - it doesn't matter who reads it. Of course, almost no-one should write to it; the list of states does not change very often - but that can probably be handled by revoking update and delete permission on the table from everyone.
OTOH, you probably do want to record who accesses the records in medical histories (HIPAA), or who modifies the data in the accounting systems (SOX). You might or might not need to worry about who reads the accounting data; a lot of that can be dealt with by basic permissions (accounting staff have permission; IT staff do not). However, auditing is always an extra line of defense.
Bear in mind that audit records are no help whatsoever if they are never looked at. In general, auditing slows a system down (simply because it is doing more work when it writes audit records); it is important to understand how much it slows down before deciding to implement your auditing strategy. However, there are some things that are more important than application speeed, and one of those is keeping yourself and other staff members out of jail. Auditing can be necessary to ensure that happens.
Oracle has a product called Oracle Audit Vault- DB2 probably has an equivalent.
You should start by prevention. The system should not allow invalid actions. Period. If the system allows 'dubious' actions that need to be monitored, that's "business logic", you are probably better of implementing like the rest of your business logic.
If you want to do something in your database, you can look into log shipping (terminology might differ from RDBMS to RDBMS). Basically, any DML operation is logged to a file. You can use this information for backups and point-in-time recovery, even for replication/HA/failover/etc. If you ship your logs to a separate, "trusted" system in an "append-only" (i.e. the log shipping process has privileges to create new log files, but not to modify existing information) fashion, you already have a primitive auditing functionality. If you do it in a secure way (i.e. authentication, non-repudiation), you probably even are quite close to "compliance" :-p
Of course, sifting through lots and lots of INSERT/UPDATE/DELETE statements is not the most sophisticated way to work.

Resources