Category: Security

Using Ruby gems is safe, right? We're a nice community of friendly beings that act towards the same goal: making Ruby better. But is that true? Can we just blindly use libraries, without making sure, that they are what they are supposed to be?

Learn how you can take over a gem, what you can do with it once you have it and what you can do to protect yourself against several types of attacks you're exposed to on a daily basis. Let's exploit the Ruby gems world, and its data together.

Slides are available here.

Nginx: Block access to certain parts of your app based on visitor country

It may be a good idea to enable some parts of your application based on a user country. You could do this on an application level:

require 'geoip'

# Controller code...
before_action do
  fail NotAllowed unless Country.allowed?(request.remote_ip)
end

But why would you want to store non-business logic like this in your app? ;) There's a much better solution: you can use the Nginx GeoIP Module.

To do so, you need to have Nginx compiled with a ngx_http_geoip_module. Run:

nginx -V

to see Nginx details. Look for --with-http_geoip_module. If you have it, you can use the GeoIP database with your Nginx instance.

Install the GeoIp database:

sudo apt-get install geoip-database libgeoip1
# you can also download it from here: http://geolite.maxmind.com

it will be stored in /usr/share/GeoIP/.

Now you need to edit /etc/nginx/nginx.conf file. Put following code in the http section:

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
  default no;
  PL yes;
  US yes;

We decided to blacklist every country except Poland and USA. Full list of countries and their appropriate codes can be found here. Of course instead of whitelisting you could always blacklist:

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
  default yes;
  PL no;
  US no;

This code won't block anything. It will just assign a yes/no value to a $geoip_country_code variable. You can then use it in your server block to allow/disallow access to certain parts of your application:

server {
  server_name  www.yourdomain.com;
  client_max_body_size 32M;
  keepalive_timeout 5;

  # Some other settings here

  error_page 403 /403.html;

  location /admin {
    if ($allowed_country = no) {
      return 403;
    }

    if (-f $request_filename) {
      break;
    }

    if (!-f $request_filename) {
      proxy_pass proxypasstargetsomewhere;
      break;
    }
  }
}

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑