DNN Encrypted Profile Field - encryption

In DNN's site settings, I would like to store a user's credit card in their profile. Is there a way I can encrypt this data? Here is the code I use to pull user custom fields:
UserInfo theUser = new UserInfo
ProfilePropertyDefinition ppd = theUser.Profile.GetProperty(propName);
if (ppd != null)
{
string v = ppd.PropertyValue;
if (String.IsNullOrEmpty(v))
{
return string.Empty;
}
return v;
}

My advice would be don't even try.
There are a lot of other issues related to storing credit card information than just encrypting data. If you need help figuring out how to encrypt it, you're most likely much better off not storing it at all. PCI requirements are extremely strict and go much farther than data encryption to even specify the physical security measures that restrict access to the server the data is being stored on (encrypted or not).
Most payment gateways will take care of the heavy lifting for you as far as PCI requirements are concerned these days, and most people don't mind re-entering a credit card number each time they make a purchase. No reason to open yourself up to that liability, just make sure the data is transmitted securely then drop it for good.
You can read more about PCI requirements here: https://www.pcisecuritystandards.org/.

Related

How to ensure unmodifiable document checksum?

Scenario: I need to store document accepted by the customer in my database. Customer needs to be sure that I don't modify it through time, and I need to have possibility to prove that stored document was accepted by the customer.
Do you know proven ways how to achieve this without doubts from any side?
I think I can create checksum from stored data for the customer, but I need to ensure that this checksum is unmodifiable by the customer. Any ideas?
PS. If you have better idea how to title this question then tell me, please.
PS. Let me know if you see better forum to ask this question, please.
What we call this in Cryptography is data integrity.
To ensure that the data is not changed by you or someone else, your customer can calculate the hash of the file with a cryptographic hash functions, which are designed to have collision resistance. I.e.
Hash(Original) != Hash(Modified) // equality almost impossible
In short, when you modify it is expected that the new modified document has the same hash value is impossible (in Cryptology term, negligible).
Your customer can use SHA-3 hash function which is standardized by NIST.
Don't use SHA-1 which has shattered.
If you want to go further, your customer can use HMAC which are key-based hash functions which supply data integrity and the authentication of data.
For the second part, we can solve it by digital signatures. Your customer signs the message
Sign(hash(message))
and gives you
( Sign(hash(message)), message ) )
and his public key.
You can verify the signature with the public key of the customer to see that the customer changed the data or not. Digital signatures gives us Non-Repudation.
This part actually solves your two problems. Even third parties can check that the data is not modified and comes from the signer (your customer).
Note : don't use checksums which are not Cryptographically secure and mostly easy to modify the document in a way that they have the same checksums.

Where and How to "cache" ASP.NET Role Data

Design Choices
Presume two ASP.NET MVC authorization/role design stories. Both are intended to minimize hits against a middle-tier or data store:
After fetching “MyRoleProvider” info from a database, it is subsequently stored in the AuthTicket user-data which in turn means that the auth-cookie holds role-info. Furthermore, in this story, storing and retrieving this role-info is done by a distinct implementation, entirely outside "MyRoleProvider."
Or...
After fetching “MyRoleProvider” info from a database, it is subsequently stored in session and accessed from there. More precisely, the class “MyRoleProvider” itself will internally access (and update) session when possible.
Again, both the above stories aim to minimize the latency of hitting an external store by "caching" role info. Both work fine. The question is, are both design-story choices equally valid? If not, why?
The Issue
There appears to be no "best practice" stated anywhere, which says "your (custom) RoleProvider should always know where role-info is found, whether in session, cache, the database, etc."
Also, there appears to be no (solid) guidance anywhere that explains what kinds of things you should not store in "userData" in the authCookie. What little documentation and guidance there is suggests only two things:
'userData' can store additional user information (a vague, broad statement). I've seen only one code example online, which involved storing additional 3rd party identity/authentication info.
Do not put too much data in 'userData', because it might make the cookie become too big to be transferred (some browsers limit cookie size).
That's it. From the above guidance, nobody is being expressly told "it is a best practice to limit the userData only to authentication info." And I certainly have not seen a document which says "it is a bad idea to put authorization or role-info into 'userData' because..."
Deduce a Best Practice?
My own answer about the two design choices being equal is “no.” I want to present my argument, and learn from you if:
You agree.
You disagree, because I'm making needless fuss.
You disagree; although my argument is valid, there are even better arguments of why my thinking ultimately is not right.
Hopefully a best-practice concept will emerge as an answer. Now for my argument(s)...
My Argument(s)
I believe the second design-story should be taken, because it represents better modularity: role information is handled completely inside “MyRoleProvider.” The first option needlessly intermingles authentication (extracting identify from a cookie) and authorization concerns. Indeed, all the built-in ASP.NET security mechanisms keep these two topics separate; base ASP.NET functionality never stores role-info in the authcookie. If anyone wants to confirm this, try reflecting these classes: FormsAuthenticationModule, FormsAuthentication, IPrincipal with RolePrincipal implementaion, and IIdentity with FormsIdentity implementation.
The ASP.NET RolePrincipal deserves a particular highlight. It permits that role-info is indeed stored in a cookie, but it is a second cookie separate from the auth-cookie. Furthermore, this peculiar idiom still involves consultation with the RoleProvider. See the example section of this MSDN documentation.
Investigating RolePrincipal further, let's look at RolePrincipal.IsInRole(). Although any such IPrincipal derived class combines identity and role information programmatically, the internal implementation still maintains the RoleProvider as the only source of role information (note the reference to Roles.RoleProviders...):
public bool IsInRole(string role)
{
if (this._Identity != null)
{
if (!this._Identity.IsAuthenticated || role == null)
{
return false;
}
else
{
role = role.Trim();
if (!this.IsRoleListCached)
{
this._Roles.Clear();
string[] rolesForUser = Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name);
string[] strArrays = rolesForUser;
for (int i = 0; i < (int)strArrays.Length; i++)
{
string str = strArrays[i];
if (this._Roles[str] == null)
{
this._Roles.Add(str, string.Empty);
}
}
this._IsRoleListCached = true;
this._CachedListChanged = true;
}
return this._Roles[role] != null;
}
}
else
{
throw new ProviderException(SR.GetString("Role_Principal_not_fully_constructed"));
}
}
This kind of ASP.NET “one-stop” deep-assumption of where role information is found, is why role info should be consolidated into the RoleProvider. In short I claim:
If you do store role info in a cookie, the reason why ASP.NET does not have a built-in capability to combine that into the auth-cookie, is precisely because ASP.NET maintains strongly a separation of concerns between the different providers.
Any RoleProvider should be aware of where role-info might be found, whether in a cookie, session, or otherwise.
Conclusion:
Do not put role-info into the auth-cookie, and ensure your (custom) RoleProvider knows all the places where role info is found, whether the database, a web service, session, cache, or a cookie.
Agree? Disagree? Thoughts?
There are a LOT of different concerns and design choices that go into deciding where to actually cache information whether it be cookie, session or some other provider.
Of course, the first question is whether you should even cache it at all. Sure there are concerns with regards to constantly accessing the database for fairly static information. However, there are equal concerns of being able to lock someone out immediately.
Only if an immediate response isn't needed does caching become viable. Because of this there can be no best practice with regards to caching authorization.. and certainly no best practices on where to cache it if your application doesn't need that level of security.
Presuming the above isn't an issue then there are trade offs with location.
Cookie
If you put it in a cookie, then it can be captured and subsequently replayed. Also it slightly increases your internet traffic because the cookie is transferred on every request.
Session
If you put it in session, then you either limit yourself to a single web server OR you must have session state stored in a location accessible by the entire web farm. If you take the latter route, then it's entirely likely you are storing session in a database somewhere thereby completely trashing your reason for having it in session to begin with.
Memcache or other
This is similar to storing the roles in session; however it's typically stored in memory on a separate server and is generally fast. The drawback is that for a load balanced web farm this can add yet another point of failure... unless it is properly clustered. At which point you've increased project development, deployment and maintenance costs....
Ultimately, there isn't a best practice. Only a bunch of trade-offs that are very situation dependent. Quite frankly for this type of data, I wouldn't cache it at all. It's usually relatively small and queries for it are generally quite fast. I might consider it if we were talking tens of thousands of users, but at that level there are many other operational considerations that would ultimately make the choice here apparent.
It seems to me that you're asking an absurd question. Nobody in their right mind would store role data in the authentication cookie. ASP.NET doesn't do it that way precisely because they provide the RolePrincipal that will store it in an encrypted separate cookie.
The whole issue of cookie is kind of pointless anyhow, since this is an implementation detail of the RolePrincipal. The app should not be cognizant of where the role data is stored.
So my question to you is... Why are we even having this discussion? You're asking if it's best practice to do something contrary to how it's done by the system, and then arguing why you shouldn't do it in this way nobody would ever use.
Also, your comment about the RoleProvider having to deal with the cookie is not true. RoleProvider does not create the RolePrincipal, this is done inside the framework. The choice of whether to use cookies is not in the RoleProvider, but rather provided by the RoleManagerModule framework class, and the way IPrincipals are instantiated by the framework.
The example in the RolePrincipal has nothing to do with the RoleProvider. In fact, the RoleManagerModule controls this functionality. RoleManagerModule is an HttpModule that is installed into IIS and runs as part of the pipeline. It doesn't even know about the RoleProvider, and basically what this means is that the Roles are populated from the cookie at a very low level, and when `RoleProvider gets around to running, if it finds the roles already there, it just does nothing.

Value obfuscation information at value level in RavenDB

I am storing sensitive information within RavenDB relating to employee performance reviews.
As such, I need a simple first-line-of-defence against curious db admins, to prevent them from browsing the data.
I would class this as client-side encryption (although it need not be TNO) just really to obfuscate the data, however, in such a way that it obviously does not impact indexability.
Notes:
I am aware that indexed fields will remain unencrypted in Lucene.
I would really like to maintain document schema browsability if possible, so if someone were to use Raven Studio, they would see something like this (they can see the schema, not the data):
{
WhatIThinkOfMyManager: 'jfjsd83hfdljdf983nofs==',
AmIHappyWithMyPayLevel: false
}
Are there any facilitiesin Raven for this? And how do I go about it?
RavenDB 1.2 supports encryption of the data on disk (including in the indexes).
But an admin that has access to the data can see it in its decrypted form.
You might want to store the data inside RavenDB encrypted from your own code.

WordPress Plugin and One-Way Encryption

I was hoping someone could help me sort something out. I've been working on a shopping cart plugin for WordPress for quite a while now. I started coding it at the end of 2008 (and it's been one of those "work on it when I have time" projects, so the going is very slow, obviously!) and got pretty far with it. Even had a few testers take me up on it and give me feedback. (Please note that this plugin is also meant to be a fee download - I have no intention of making it a premium plugin.)
Anyway, in 2010, when all the PCI/DSS stuff became standard, I shelved it, because the plugin was meant to retain certain information in the database, and I was not 100% sure what qualified as "sensitive data," and I didn't want to put anything out there that might compromise anyone, and possibly come back on me.
Over the last few weeks, some colleagues and I have been having a discussion about PCI/DSS compliance, and it's sparked a re-interest in finally finishing this plugin. I'm going to remove the storage of credit card numbers and any data of that nature, but I do like the idea of storing the names and shipping addresses of people who voluntarily might want to create an account with the site that might use this plugin so if they shop there again, that kind of info is retained. Keep in mind, the data stored would be public information - the kind of thing you'd find in a phone book, or a peek in the record room of a courthouse. So nothing like storing SS#'s, medical histories or credit card numbers. Just stuff that would maybe let someone see past purchases, and retain some info to make a future checkout process a bit easier.
One of my colleagues suggested I still do something to enhance security a bit, since the name and shipping address would likely be passed to whatever payment gateway the site owner would choose to use. They suggested I use "one-way encryption." Now, I'm not a huge security freak, but I'm pretty sure this involves (one aspect anyway) stuff like MD5 hashes with salts, or the like. So this confuses me, because I wouldn't have the slightest idea of where to look to see how to use that kind of thing with my code, and/or if it will work when passing that kind of data to PayPal or Google Checkout, or Mal's, or what have you.
So I suppose this isn't an "I need code examples" kind of question, but more of a "please enlighten me, because I'm sort of a dunce" kind of question. (which, I'm sure, makes people feel much better about the fact that I'm writing a shopping cart plugin LOL)
One way encryption is used to store information in the database that you don't need back out of the database again in its unencrypted stage (hence the one-way moniker). It could, in a more general sense, be used to demonstrate that two different people (or systems) are in possession of the same piece of data. Git, for instance, uses hashes to check if files (and indeed entire directory structures) are identical.
Generally in an ecomm contect hashes are used for passwords (and sometimes credit cards) because as the site owner, you don't need to retain the actual password, you just need a function to be able to determine if the password currently being sent by the user is the same as the one previously provided. So in order to authenticate a user you would pass the password provided through the encryption algorithm (MD5, SHA, etc) in order to get a 'hash'. If the hash matches the hash previously generated and stored in the database, you know the password is the same.
WordPress uses salted hashes to store it's passwords. If you open up your wp_users table in the database you'll see the hashes.
Upside to this system is that if someone steals your database, they don't get the original passwords, just the hash values which the thief can't then use to log in to your users' Facebook, banking, etc sites (if your user has used the same password). Actually, they can't even use the hashes to log in to the site they were stolen from as hashing a hash produces a different hash.
The salt provides a measure of protection against dictionary attacks on the hash. There are databases available of mappings between common passwords and hash values where the hash values have been generated by regularly used one way hash functions. If, when generating the hash, you tack a salt value on to the end of your password string (eg my password becomes abc123salt), you can still do the comparison against the hash value you've previously generated and stored if you use the same salt value each time.
You wouldn't one way hash something like an address or phone number (or something along those lines) if you need to use it in the future again in its raw form, say to for instance pre-populate a checkout field for a logged in user.
Best practices would also involve just not storing data that you don't need again in the future, if you don't need the phone number in the future, don't store it. If you store the response transaction number from the payment gateway, you can use this for fraud investigations and leave the storage of all of the other data up to the gateway.
I'll leave it to others to discuss the relative merits of MD5 vs. SHA vs ??? hashing systems. Note, there's functions built in to PHP to do the hashing.

Using a guid for displaying "secure" invoices

I've created a web site for student management (martial arts schools). Which includes invoicing students. Currently the only way my users can do this is by printing the invoices and handing them to the students. I'd like to create a way for the students to go to their invoice online.
I've been considering using GUIDs for the students, and using that as the parameter for the query string to the invoice. (http://thesite.com/invoice.php?guid=E3D3D122-5AB6-4405-96EC-7C0579710813)
The invoice would be a read-only page, and allow no access to the rest of the site. So I'm not to worried about packet sniffing (I don't believe some sniffing traffic in a coffee shop is a concern, if all they have access to is a random student invoice).
I am worried about someone being able to guess, or get to a specific set of invoices (i.e. all the invoices of a competitor).
I feel like I'm either crazy for considering it, or it's a relativity standard practice. I'm just not sure which. And SO is a great sanity check.
Thanks
That's actually a good, secure process; you lose the readability of the URL, of course, but if that's not much of a concern, that's a good solution. It's certainly not guessable.
As an added security measure, you might want to put in place logging of invoice accesses.
I would take it one step further and store the invoice as a password protected pdf document. This achieves several things:
the document is read only (a web page is too, but a pdf is harder for the end user to change)
the student also requires a password to access the info in the document so even if someone guesses the GUID (or more likely gets a shortcut/url mailed to them) then they can't see what is in the document (they won't be able to see the amount, which school it is for, etc.)
even if the document is retrieved from a web cache it isn't viewable without the password
it is printer friendly
it should be easily viewable on other devices

Resources