Links within email that can edit data in database - django

I apologize if this is trivial but I thought this would be easy to find but I think the problem is that I'm not sure what I'm looking for.
Basically, I want to send out an email to a customer who had their pickup missed by the pickup truck to help reschedule a new date or cancel the pickup all together depending on which link in the email they clicked.
Using pk's and ID's seemed like a security flaw to link into any view as the URL could be easily altered. What protocols/libraries would I need to use to accomplish such a task? Do I just assign a UUID to each customer in my database and go off that?

Having a UUID to represent the user would be fine, but keep in mind it's just a speed bump. E-mails aren't safe and can be read by a 3rd party. Even with UUID's someone can impersonate another. It sounds like it's a rather low risk issue, though. What's the worst case here? Do you have ways to mitigate it through customer support?
If you wanted to make things more secure, you'd just have a link that would require authentication to make changes to their order. It's a balance between friction with your users and security.
It seems you have the right ideas already. I'd suggest not user pk's just because they are often incremental and it's easy to just iterate through all your customers. UUIDs just increases the number space significantly that it should deter people from doing it assuming there isn't anything to be gained.

Related

Provision product with strip and dj-stripe

I'm using stripe with DRF and on top of that, I've implemented the library dj-stripe.
Everything works so far but I'm not really sure how to provision my product now. I do have access to the subscription and customer object for every user but these objects are quite complicated / big. I can't really do something like if user.subscription -> do this since the subscription could be e. g. deleted, inactive. I also need a more granular solution since I need to apply limits like:
if subscription.plan.product === "Entry Plan":
# allow user to only create 5 instances
I can't really find information on how to do this elegantly and consistently for an entire app.
If you're looking at the Subscription object for a customer, then yes you will need to check the status of the Subscription to ensure it's still active. dj-stripe appears to have a helper for this.
The implementation of provisioning access to your application/products is up to you, because it depends heavily on your business needs. If you have specific questions about challenges beyond the subscription status, I suggesting asking those clearly so that they can be addressed, but there is no concise way to explain how to generally provision access.
As I side note, I recommended reaching out to the author of dj-stripe with a thank you and ask what you can do to help get the docs for checking subscriptions fleshed out.

Is it feasible to have a single sign on page for multiple datasources?

I am in the beginning stages of planning a web application using ColdFusion and SQL Server 2012.
In researching the pros and cons of using multiple databases (one per customer) vs one large database, for my purposes I have decided multiple databases would be the best approach.
With this in mind I am now wondering the best way to proceed regarding logging clients in. I have two thoughts here:
I could use sub-domains with each one being for a specific client. The sub-domain also being the datasource name.
I could have a single sign on page with the datasource for this client stored in a universal users table.
I like the idea of option 2 best however I am wondering how this may work in the real world. Making each user unique would not be ideal (although I suppose I could make this off of an email address instead of a username).
I was thinking of maybe adding something along the lines of a "company code" that would need to be entered along with the username and password.
I feel like this may be asking too much of clients though.
With all of this said, would you advise going with option 1 or option 2? Would also love to hear any thoughts or ideas that may differ.
Thanks!
If you are expecting to have a large amount of data per client, it may be a good idea to split each client into their own database.
You can create a global database that contains client information, client datasource, settings, etc. for each client and then set the client database in the application.cfc.
This also makes it easier at the end if a client request their data or you would like to remove a client from the system.

long term cookie

I'm looking for a way for users to be able to connect to my application easily, but rarely. What I want to do is be able to store a cookie with a 1 year life on the user's computer. If they access the website while the cookie is active, they will be automatically logged in.
My proposed solution is this: Upon initial login, create a cookie with the users IP address, last login date, and random number, all hashed together. I will also store their user ID and IP address in cookies as well. These values will also be stored in the database. If after a few months they access the site again, the IP address, ID, and hash match the values in the database, then they are automatically logged in. A new hash is computed. If any of these don't match, then the user will be prompted to log in again.
Are there any obvious security flaws to this design? I am not worried about IP addresses changing, this will be for professors on a university campus.
Thanks in advance,
--Dave
Your question does not make it clear how this system is any different from any other standard long-life cookie. Those are used across the web without significant security problems, so I see no reason you could not also use a cookie in a similar fashion.
Are there any obvious security flaws
to this design?
No.
I would say it's definitely a security risk if someone figures out the system. To be honest, I would rethink that setup, at least the storing it in a database part. Not to mention the fact that cookies very rarely stay on someone's computer for a year anyway, most people clean them far more frequently.
But since you asked, creating it is pretty easy:
$expire = time()+(60*60*24*365);
setcookie("login", "mycookie", $expire, "", "yoursite.com" );
Instead of "mycookie" you could insert that token you were talking about. Hope that helps a little.

Spam proof hit counter in Django

I already looked at the most popular Django hit counter solutions and none of them seem to solve the issue of spamming the refresh button.
Do I really have to log the IP of every visitor to keep them from artificially boosting page view counts by spamming the refresh button (or writing a quick and dirty script to do it for them)?
More information
So right now you can inflate your view count with the following few lines of Python code. Which is so little that you don't really need to write a script, you could just type it into an interactive session:
from urllib import urlopen
num_of_times_to_hit_page = 100
url_of_the_page = "http://example.com"
for x in range(num_of_times_to_hit_page):
urlopen(url_of_the_page)
Solution I'll probably use
To me, it's a pretty rough situation when you need to do a bunch of writes to the database on EVERY page view, but I guess it can't be helped. I'm going to implement IP logging due to several users artificially inflating their view count. It's not that they're bad people or even bad users.
See the answer about solving the problem with caching... I'm going to pursue that route first. Will update with results.
For what it's worth, it seems Stack Overflow is using cookies (I can't increment my own view count, but it increased when I visited the site in another browser.)
I think that the benefit is just too much, and this sort of 'cheating' is just too easy right now.
Thanks for the help everyone!
Logging an IP is probably the safest. It's not perfect, but it's better than cookies and less annoying to users than requiring a signup. That said, I'd recommend not bothering with saving these in a DB. Instead, use Django's low-level caching framework. The key would be the ip and the value a simple boolean. Even a file-based cache should be pretty fast, though go with memchached as the cache backend if you really expect heavy traffic.
Something like this should work:
ip = request.META['REMOTE_ADDR']
has_voted = cache.get(ip)
if not has_voted:
cache.set(ip, True)
#code to save vote goes here
There is no foolproof way of preventing someone from artificially inflating a count. Rather, there's the extent to which you're willing to spend time making it more difficult for them to do so:
Not at all (they click refresh button)
Set a cookie, check cookie to see if they were already there (they clear cookies)
Log IP addresses (the fake a different IP every time)
Require signin with an email they respond from (they sign up for multiple email accounts)
So, in the end, you just need to pick the level of effort you want to go to in order to prevent that users from abusing the system.
You could send them a cookie when they access it and then check for that cookie. It can still be gamed, but it's a bit harder.

In a website with no users, are cookies the only way to prevent people from repeating actions?

I'm creating a website and I don't want to have user/membership.
However, people using the site can do things like vote and flag questionable content. Is the only way to identify and prevent users from doing this repeatedly by using cookies?
I realize a user can just clear their cookies but I can't think of another way.
Suggestions for this scenario?
Well you could map a cookie + ip-adress in a datarecord in your database. To identify the user. So if the ip exists in the database, you simply just add the cookie, but check the cookie first to avoid unessesary database calls.
This is not optimal though, since schools etc might have the same ips on a lot of computers.
You can always just adapt openid!
Marko & Visage are correct,
Just to add though, you might want to store each vote with the timestamp,IP, etc... so at least if someone does try to "game" your site, you'd be able to rollback sets of votes made from the same location or within a very short amount of time (i.e. from a bot)
+1 To all that others have already said. Here's another middle-way idea:
Use cookies as primary means of limiting voting. If a cookie is not found, check the IP address. Allow no more than, say, 1 vote per 5 minutes from the same IP.
Cookies are not enough, as you said it could be cleared/expired.
IP address tracking is also not an option because of DHCP and firewalls.
The only thing that is ~100% sure is users, but then again, one person can register multiple accounts.
I'll go with cookies, as the simplest ant least obtrusive way. If someone really wants to play the system, he will find a way whatever you try to prevent it.
Even with membership a user can register multiple times and vote.
Cookies are one way to handle this but people who know that they can delete cookie can vote again.
You can catch the IP of the voter and restrict based on that. But many people will have same IP.
Sadly there is no other way.
Yes, you are right.
HTTP is stateless, so there is no way of determining if the origin of a request you receive now is the same or different to the origin of a request you received, say, 5 minutes ago.
Cookies are the only way around this. Even server side sessions rely on cookies to maintain session identity across requests (ignoring the security nightmare of passing the sesison ID in the URL, which anyone with malicious intent can sidestep trivially).
There will always be people gaming the system if it suits them. Moreover, if you make it such that you don't need cookies at all you'd be open to very simple attacks.
I think you'll want to consider ways to increase the economic cost of users operating under a cloud of suspicion.
For example, if a user with the same cookie tries to re-submit the vote, that can obviously be stopped easily.
If a user with a different cookie but from the same IP does the same thing, it could be coming from a proxy/firewall so you may want to be cautious and force them to do something extra, like a simple CAPTCHA. Once they've done this, if they behave properly nothing new is required as long as their new cookie stays with them.
This implies that people without cookies can still participate, but they have to re-enter the letter sequence or whatever each time. A hassle, but they're likely used to sites not working without cookies. They'd be able to make an exception if required.
You really won't be able to deal with users sitting over a pool of IPs (real or otherwise) and exploiting new and dynamic attack vectors on your site. In that case, their economic investment will be more than yours and, frankly, you'll lose. At that point, you're just competing to maintain the rules of your system. That's when you should explore requiring signup/email/mobile/SMS confirmation to up the ante.
You can add GET variables and URL parts to serve as cookies - some sites do that to allow logins and/or tracking when cookies are disabled. Generate the part using source IP and user agent string, for example.
site.com/vote?cookie=123456
site.com/vote/cookie123456