I need to build an application that will only serve people in my workplace. Currently, everyone has a specific company email, which has a unique domain and format.
I created a regular expression that only validates our company email addresses, and configured the application to require email confirmation. This seems like it should be sufficient, unless a malicious person:
Finds a flaw in my expression.
Finds a way around confirmation.
Somehow gets a company email address.
I feel like this isn't secure enough though. Maybe I need to take it one more step, with some kind of pre-approved email list or something?
I'm curious if anyone else has faced this problem. (Most likely.)
Ok, here is my solution:
This will enable a second level of security:
On the User model, create a boolean field called user_active.
Then, create an Admin page that will only allow your admins to check/uncheck accounts.
Then, you can call User.user_active? before logging your users in.
This makes it much harder for somebody who manages to sneak around your security to access your app.
This would be a pain with tons of users, but if you only have 200 or so, this will work.
Related
I'm not sure that this is a stack overflow appropriate question. If not, I'd appreciate a pointer to a more appropriate forum, as I haven't been able to find one.
I have a small website project that gets a few hundred daily unique users and on average I get one or two people to create an account per day. Yesterday I noticed that more users were signing up (like about 50) and today another 150 users signed up. Wonderful, right? Except that then I noticed that while the emails look legitimate, all of the usernames ended in same letters. My site requires that email be confirmed before a user gets any additional access and none of these accounts have confirmed their email. There is no apparent regularity to the creation of these accounts other than that it is happening with slowly increasing frequency.
My first question is, what is the most effective way to prevent this with the least user impact. The only thing that I can think of is adding a captcha step as part of account registration. I really dislike captcha so if anyone has a better idea for a general solution to this I'd appreciate it.
I'm also interested in this: What could this malicious user be gaining by doing this? It's not yet anything other than a minor nuisance to me. The accounts are easily identifiable and they're not (yet) being created at a rate that could represent anything like a denial of service attack. The only thing I can think is that they're trying to confirm that these emails are registered on my site. But I can't think why that would be useful. Also, if the email addresses are real, they're using my site to spam those email, but the spam is a registration confirmation for my site. So I guess they might eventually get my email provider to shut me down if they keep this up.
Thanks in advance for any help, even if that's a redirect to a different forum.
Other possibly useful information:
My site is hosted on Azure using asp.net mvc5 with identity framework
I believe that the emails are legitimate because my email provider
shows a very small bounce rate (like 1%) on these emails.
There are 2 more options which are SMS-Confirmation(by limiting the phone number), and IP restriction.
Rails has some very good methods for role based authorization, e.g., cancan
But how can you grant authorization to specific pages, rather than controllers/actions.
For example, take the case of an app that contains a receipt or invoice model. A User can log in and generate an invoice. The User then needs to send his customer a URL to that invoice. The customer should not be able to access invoices of other customers, particularly important as Rails generates sequential and easily guessable path names (e.g., /invoices/1, /invoices/2, etc.).
Ideally the customer should not need to signup to view these pages. One solution might be to generate a random password on Invoice creation, and send this to the customer to unlock that page specific page.
This sounds like an issue that should be reasonably common, but after Googling I have not found much information of use (though I may be using incorrect search terms).
So I would like to know:
Is this something I should be attempting with Rails?
Are there any gems or example apps that I could study?
What are the potential considerations/ pitfalls of this approach?
Hi if the user you wish to have access was registered in the system it would be no issue at all as you could generate a permission record.
How ever your concern with the predictable urls can be easily solved by :
FriendlyID(https://github.com/norman/friendly_id)
or my personal favourite
Vanity permalinks (http://blog.teamtreehouse.com/creating-vanity-urls-in-rails)
Ideally the customer should not need to signup to view these pages. One solution might be to generate a random password on Invoice creation, and send this to the customer to unlock that page specific page.
So anyone with the information should be able to access it. One solution is to obfuscate the url or use a UUID, so don't give out /invoices/1, instead give /invoices/8a20ae59-30d5-41b6-86d3-ac66e3b43e9d. The url is unguessable. Still the url is the only piece of information one needs to access the contents.
If you want two-factor authorization, then the easiest way is to use http basic auth, generate a password from the url and your secret_base, and send it to the user separately. As it's generated, you don't need to store it, you can always check it by generating it again.
In all of my Rails applications I have a User model with name, email and password attributes (among others).
This seems to be the standard approach when building Rails apps.
The more Rails apps I build, the more I begin to wonder why the User.name is even necessary.
Wouldn't it be easier to just omit the user name everywhere right from the start?
From a user perspective, the sign up process will become easier. Instead of filling in four fields (username, email, password, and password confirmation), the user will have to fill in only three.
According to some usability experts this might increase the number of sign ups.
In addition to that, users will also have to remember less data, i.e. only their email address (which most people have memorized anyway).
So what might be negative implications of this approach?
I couldn't think of any so far.
You might need to make emails from your app personalized, maybe with greetings such as `Dear <%= username %>.
This doesn't mean you have to put name as one of the sign-up fields. You can put in the update form only, when the user edits their profile. Then you can make the edit_user_registration_path the after_sign_up_path_for devise.
I don't think using username is "standart" approach with rails apps. In fact, devise's vanilla approach is using only email on models.
However, being able to accept username or email has many other advantages. You may have other scenarios where users do not register at all. I mean, perhaps you are also creating accounts for users without any registration and you don't know their emails, if so using email will not be an option.
In some applications, we use more then 3 authentication strategies. Some users do not have a username or email at all..
In short, i think it really depends on your scenarios. But i am sure that using both email and username is not a rails convention.
If the main goal is a frictionless signup process then an OAUTH strategy would be the best way to go (4 fields of info down to two clicks), however you may want to collect the user info at a later time for a more personalized feel depending on what info you can capture from the callback.
I'm using devise/cancan for my app and everything is pretty sound -- provided a user creates an account and signs in.
What I'd like to do is allow a user to get started without creating an account. And then sign up if they want to actually save their work.
Has anybody come across this before? Should I be figuring out how to create dummy accounts with devise? Or allowing unauthorized users access to creating models in my app via CanCan?
I could go into detail about how I've been thinking about approaching this, but it feels like a pretty obvious use case that somebody has come up with a nice solution for.
Thanks in advance,
Mike
If you go with creating dummy accounts, you would have to track the user somehow via a cookie and cache the values in that cookie in your db. Cancan does allow for guest accounts via the ability model. For example:
user ||= User.new # Guest user, for users who are not registered or don't have an account yet
Which is enough you to you started with applying permissions for non registered users. Note though, tracking by cookie alone is not very reliable and can lead to some type of security hazard (i.e. by means of cookie hijacking). User, one day, can also decide to clear out his cookies.
If need be, I would suggest letting the user do minimal interaction with a guest account and motivating the user to sign up / register with Devise as much as possible.
Hope that helps!
I actually am considering the same problem, I have a scheduling app that makes a calendar. To get over the problem I'm thinking that you use
user ||= User.new
Like was suggested above and using cookies to get the data to the database once the user creates an account.
This would mean that you would not have to worry about clearing out cookies because they would create an account if they want to save data.
I have been thinking for a good while about how to tackle the problem of implementing an ID based user system while using ASP.NET MVC. My goals, much like StackOverflow's system are as follows:
Allow the users to change their nicknames without the "avoid duplicate" restriction.
Allow the users to authenticate via OpenID (not with password for the time being).
I wanted to avoid as much rework as possible, so I at first thought of using the membership, role and (perhaps) profile providers, but I found they were username based.
I thought of adapting the hell out of the SqlMembershipProvider, by using the username field to store the IDs and throwing UnsupportedException on password based methods and the like, just so as to be able to use the other systems. But it feels unwieldy and kludgy (if possible to do at all).
On the other hand, maybe I should roll up my own user system, but I'm not sure if even if I can't use the providers, I can still use some of MVC's features (plug my code in with MVC somewhere, I can think of AuthorizeAttribute off the top my head).
So I was wondering if anyone had run into the same design problem, and what solutions they had come up with.
The more detail the better!
I had to set up a quick membership system for a client, they had some requirements that didn't allow me to use the built-in right off the bat nor the time to build what they wanted. I have plans to eventually roll-out a complete membership management system, but like you, I needed something now. I went with the following plan, which will, eventually, allow me to swap out the built-in providers for my own - time constraints and deadlines suck:
I have my own Personal User Table (PT) - MembershipId, UserName, Email, superflous profile info. This is what the app uses for any user information. It's a class, it can be cached, saved in the http context, cookie - however you want to handle your user info.
I then set up the SqlProfileProvider for authentication, authorization, and roles. I don't use the profile provider (even for trivial settings) because it's a pain in MVC. I made no changes to the built-in providers. This is what I'm using for authentication and authorization.
When creating a user, my code does the following:
Check PT for user name and email, per my rules
Create Guid - MembershipId
Create MembershipUser, the MembershipId is the username (the email is irrelevant and not used), and user password, question and answer, etc.
Create the user in PT with the profile values and use MembershipId as the PrimaryKey.
On login, I get the MembershipId from PT, validate against Membership with the MembershipId and the password and I'm done..
When deleting a user, I do the following:
Check PT for user, make sure I can/should delete
Get MemberShipId
Use a transaction
Delete from PT
User Membership.DeleteUser(MembershipId, true) - this ensures that the user is deleted from teh membership and other aspnet_ tables
commit
And it works as expected :)
A few things:
User.Identity.Name will be the MembershipId (Guid). This is used for SignIn and Role management. My PT is where the user's info (save the password) is saved. I can change user names, emails, etc with no impact on Membership or Roles because Membership is based on the PrimaryKey from PT.
The signin requires an extra DB hit because you need to query PT to get the MembershipId to validate against (you could cache).
The built-in auth system is really heavy - if you look at the sprocs you will see all the hoops it goes through to validate a user. I'd recommend eventually getting away from it. But in a tight spot, it does a good job - and if you don't have a milion users, I don;t think it'd be a problem.
I didn't consider OpenId and I'm not sure how you would integrate it, although I think you could probably do the same thing as above and instead of validating against actual credentials (after they come back validated form OpenId) just log in the user using the MembershipId (don;t validate against Membership).
For me, the main point behind this was that the app uses a custom user model, allowing for changes to user name, email, names, etc. Without impacting the auth and roles. When I am ready to change to the complete system, I can change it without worrying about the impact to the app.
Kenji,
I would recommend looking at some of the existing OpenID providers for ASP.NET. It should be fairly easy to make them work with MVC.
Erick
Forgo the use of SqlMembershipProvider. The only thing it would really offer you is an out of the box admin interface. The rest that it brings would be a nuisance.
Just use the sql membership provider and add a stored proc to change the username at the database level.