Rails app on Heroku - Please recommend defensive programming techniques - ruby-on-rails

I've just put a Rails app live on heroku.com which services some touchscreen kiosks and have had my first taste of malicious users with some bogus service bookings. I would like some suggestions on audit data which I can log to help me to track down or otherwise discourage or prevent such malicious activities.
Some brief background - I have designed a Rails based website which is targeted towards the Tourist industry and allows customers to book accommodation and other tourist related services such as boat trips. We run this application on touchscreen kiosks (think 6.5 foot tall units with 40" touch screens) and email notifications of bookings to service providers.
What I'm looking for is suggestions on things that I can record at the point of bookings (and other transactions) taking place so that I can help to authenticate valid bookings and record details which can be used later to trace these bogus bookings. I might then add this information to a black-list to block these machines from creating further problems.
I'm already recording the request.remote_ip address but would ideally like to be able to record the hostname of the remote_ip as well since the IP address might change dynamically. Is this possible? Should I create a random key and store it as a cookie to identify each client machine uniquely?
I'm not looking to prosecute every person who makes a bogus booking, I just want to be able to discourage, prevent or track such malicious activity and would appreciate any suggestions on how best I can do this.
Many thanks,
Craig.

The question is a bit vague I think. You need to look at what you know: what actually IS a non-valid bogus booking? How did you personally figure out that some particular booking was bogus? Did someone tell you, did you figure it out from the data yourself?
You first need to gather all the bits and pieces you have of bogus bookings, and if there is a pattern then that is what you implement as a filter. I mean if someone knew a booking was bogus, why did your system not know it?
Logging IP addresses and hostnames is kind of futile..you'll never catch whoever did it this way. Why not validate up-front with credit card numbers or minimum a confirmed e-mail address? If you have an up-front credit card number then you have a direct link to the person for disputes and/or blocking further attempts by card number. IP addresses are too hard to track.
An IP address can be converted to a hostname by a reverse lookup, but if the IP changes the hostname changes too. If you alreay log an IP, you can always do a reverse lookup later, but I don't really see the value of knowing the host name(?).

Related

Is AmazonAWS creating non-genuine hits? How can I verify?

I have a site that logs a "hit (via saving a record to a Hits table that captures the date/time and IP of the machine whenever the detail page is loaded)" whenever a user brings up a detail page for a particular item so that admins can see how many hits that particular item gets. We get random instances where items are being hit multiple times/day in twos. So, in the data, it looks like a user is viewing an item, but the site is logging their hit twice in the database (same item, same date/time, same IP Address, etc.). Most hits are only being recorded once, and all my testing has lead to assurance the site is working appropriately. I'm noticing that particular IP Addresses are causing double hits. When I do Reverse IP searches, all the "double hits" are tied to IP Addresses that trace back to Amazonaws in northern Virginia, on the other side of the country. Our site is used locally, and the single hits are coming from IPs that trace back to local areas. Is there a bot hitting my site from afar? Should I block Amazonaws in Azure (which is where my site is hosted) or is that going to lock out genuine users? Is there a way I can detect whether a hit is genuine in my code (my site is in .Net MVC)? Has anyone faced a similar situation in the past?
Note: This IS RELEVANT to software engineering because a part of the question is asking how I can verify in my code that a hit is genuine!!!!!!!!!!!!!!!!!!
Basically, what I found out (no thanks to the elitist user who downvoted my question and offered no contribution) is that, my hit counter is being inflated by web crawlers. The quick and dirty solution is to implement a robots.txt file to block crawlers from hitting that page. Of course, that comes with the sacrifice that my client's site will no longer come up, should the public do a google search for the product being offered.
One alternative is the hidden link method; in which we put a hidden page on the site that no human user would ever access. When a bot hits that page, we record the IP in a "blacklist" table. Then, before our real hit counter logs a hit, it checks the user's IP against the blacklist.
Another alternative is to implement a blacklist of known User-Agents used by bots. We check the user's credentials against that list in order to determine whether a user is a bot.
Neither of these solutions are 100% though.
These are fairly adequate responses to my question. Of course, since this is StackExchange (or StackOverflow or StackYourMomma or whatever it is), people are just going to downvote your question and act like you're beneath a response because you didn't follow all the little bull crap rules that come along with being a member of the SE/SO/SYM community.

Persistent way to recognize web clients other than using ip address?

I am creating a site where anyone is able to upvote and downvote content.
For the launch, I wish to not force people to create accounts in order to do this. However, without accounts, what is a reliable way to ensure people don't vote on the same content more than once?
The methods that I've looked at are ip based tracking and cookie/session based tracking.
Both have problems.
I am targeting a college campus, and so many users could potentially have the same ip (through their dorm or apartment). Whereas cookies/sessions are very easily exploitable if the user deletes their sessions or even uses a script to vote.
(Being a college campus, there's probably many tech savvy students who may do this)
As far as technology goes, are there more reliable ways to accomplish this?
You have very few options here. Cookies were invented for just this kind of thing, but as you know they can be deleted or altered by those who know how. If there were a reliable, easy way to do this, it would have a catchy name and be well documented all over the web.

How to restrict purchases to ONLY IP addresses in the United States using Ruby/Rails?

I have a client who has a requirement that they can't sell particular products 'outside the United States'.
They'd prefer that users can see the site, but when they try to checkout present a message indicating they are outside the United States.
Their site is built in Rails 2.3.8.
Check out the GeoIP gem (make sure to read the instructions, you need to download the GeoLiteCity or GeoLiteCountry database in order for it to work). It uses MaxMind's GeoIP database and can give you the country (or city, in the case of the city database) of an IP address, with some accuracy. There is a commercial database with better accuracy available, which I would recommend for your use case.
However, be advised that this is by no means a definitive solution. Some customers will be turned away wrongfully, and some will be able to order even though they should not. Things like satellite connections, proxy servers and VPN services make IP location impossible, and no database is 100% complete or correct.
What you're looking for is some kind of rough geolocation. One way to get this is to query a DNS zone designed specifically for this; one such zone is described at http://countries.nerd.dk.
I am from Ukraine. And when a particular US shop doesn't want to sell products overseas it usually specifies in the policy/faq/etc that only US bank issued payment cards are accepted.
That seems for me the best solution to solve: "can't sell particular products 'outside the United States'. "
As there are package/mail/freight forwarding companies which can be used by a potential client of that customer though residing outside US but whom the customer won't have to ship directly. That customer would still benefit from those sales but are freed from dialing with burden associated with overseas shipping.
And when you will solve it with geolocation, that customer would still be able making additional money, when people would still be using the site through different kind of proxies, if that customer will be worth it. :)
You can use their data that you pull into your database to check the user's IP address. http://www.ipligence.com/geolocation/ (you still have to worry about proxying)
I would also check where your shipping it to (checking addresses like suggested above), also check the card address with the card backer like VISA, etc..
And suggested above, your money processing agent shouldn't allow any transactions from outside the U.S. on particular items (if possible)
But I did read your statement SOME products may not be allowed to be sold outside the U.S. So you'll need a way to mark those products in your system and then let the user know they are unable to purchase those items, but continue on with others in the cart.
You could use a Rack Middleware, but it will require that you fork it on Github first.
https://github.com/roja/rack-geo
At the moment this project gives you City and Organisation names based on the IP address of the computer making the request - you need Country Code too.
You could add it to the code relatively easily here: https://github.com/roja/rack-geo/blob/master/lib/rack/geo.rb
You could then set a Rack environment variable to indicate if the request is from the USA, in the call method:
Rack::Request.new(env)["born"] = "...in the USA"
Add it to your config file:
config.middleware.use Rack::Geo
And then in your controller you can test if the request has this environment variable set appropriately and redirect to a 'sorry you must be from the USA' page:
if params['born'] == "...in the USA"
redirect_to "/not_from_round_here"
end
Bear in mind that IP address sniffing is fallible. I often take trains in the UK and end up with Google in German.
A geoip alternative is can be found here: http://humbuckercode.co.uk/licks/gems/geoip/
Uses the maxmind libraries, easy to set up, no schema updates needed, fast

Is it possible to track the country where a user is accessing a particular website?

I wish to track a user's country from where my website is accesed .
ex; if a customer from a particular is accessing say america how to trace that the user is actually from america.
Is there any way
What you are talking about is called GeoIP and there are many ways to do it. Normally this is done using a third party that has a mapping of IP addresses to physical locations.
This is of course not 100% accurate, as people may be using VPNs, TOR or simply spoofing addresses.
It's not possible in all cases, but most IP addresses can be mapped to a location (even down to the city). There are quite a large number of such geomapping services.
Use MaxMind service.
http://www.maxmind.com/app/javascript_city
They got free and paid versions.
You can determine the country of the IP address of last proxy that a user is using. This is often their country, but not always.
Users can set out to obscure it e.g. by using TOR or another proxy service.
Or their ISPs might be passing them through NAT or through other countries.
And what do you do with the information? Offer them the site in their presumed-native language? Or customise your contact details appropriately?
So you have to think carefully about how you use this information. It is a good idea to present a page in the native language that you think the user is surfing from, but you must make it easy and obvious for the user to change their country. Not all surfers in any given country actually speak the language, and not all people can call toll-free numbers, and not all people in one country are wanting support that's specific to their country, they may be seeking support for when they are elsewhere or for a friend etc.

Detect company names that are visiting my site

I'd like to use visitor IP addresses into a company name. This will be used for displaying something like "Hello visitor from Apple Inc." . Note I am looking for the company name, not the domain name. Extra points for determining the originating country. The app is written in Ruby on Rails, but examples in other languages will do. Thanks!
There are databases for this kind of thing, but they are hardly 100% accurate, so I'd think long and hard before using them to make assumptions regarding content you present to your visitors. If you still want to do it, here are two companies that offer databases that include organization level detail:
http://www.maxmind.com/app/ip-location
http://www.ip2location.com/
Edit to clarify based on additional answers:
The organization level detail in the databases from these vendors is different than ISP information, which is what the others are referring to. The databases from the vendors above are actually assigned organizational information based on research, not reverse lookup on IP ownership.
For starters, know that often it is impossible - e.g. many people's connection will be from Insight, or Comcast, or whatever their ISP is. I'm not sure if your intended feature is all that snazzy if you greet me as being "from" Insight Broadband.
You're very likely to get this more wrong than right, but you can get this from a whois client.
For example, to see owners of US addresses (at least), you can whois from the CLI to play around:
whois -h whois.arin.net 17.18.19.20

Resources