Exclude not working for Rack::SSL - ruby

I currently have a sinatra project that I am trying to add SSL to so I tried to add Rack::SSL which worked fine, but I'd like to have it disabled in development mode.
class Blog < Sinatra::Base
use Rack::SSL, :exclude => lambda { |env| ENV['RACK_ENV'] != 'production' }
...
This is the code I have and ENV['RACK_ENV'] is returning 'development' when I pry, but for some reason when I try to hit my site locally it's still trying to redirect to https.

I got caught out by this last week. Turns out I'd enabled HTTP Strict Transport Security (HSTS) too, which meant once a cookie for the site had been served over HTTPS the browser would prevent any future requests to the non-HTTPS version of the site.
Thought I'd mention it just incase you've got the same.

This works, chrome just had the redirect cached from before I added this so I thought it wasn't working. Worked fine in an incognito window.

Related

how force a Ruby Sintra app to redirect http to https

I have a classic Sinatra app which at some point just stopped redirecting http requests to https. (I'm not sure when it stopped automatically redirecting, perhaps in the last year or so when I upgraded some things including the Sinatra gem to v 2.2)
The Gemfile.lock has:
rack-ssl (1.4.1)
The app initialization contains:
require 'rack/ssl'
use Rack::SSL
None of that has changed in my code.
But currently, if I navigate to http://www.myapp.com it stays on http, instead of redirecting to https like it used to.
I've also tried adding
set :force_ssl, true
But that had no effect.

Force HTTPS for app deployed in google app engine

If an application developed to support only HTTP. What configuration we should do in google app engine, that it force developer to have HTTPS support. We can add an entry(for handler) in "app.yaml", but in order to redirection. Just want to know anything else we can do to prevent such thing(in short should work with HTTPS only). Probably we can do something from ingress/loadbalancer/ssl etc but that's looks paid and don't want that currently.
You just have to set secure: always in app.yaml for your route handlers. Any call to your app from http will automatically get redirected to https
I was having trouble putting a whole site over HTTPS, so searching I found a solution that worked for me:
https://cloud.google.com/appengine/docs/standard/python3/config/appref
what it says is that you can change your app.yaml file and place in the handlers
- url: /.*
secure: always
redirect_http_response_code: 301
script: auto

Blacklist URLs with headless Chrome

I'm trying to block URLs in my specs, achieving something like I had when using capybara_webkit:
Capybara::Webkit.configure do |config|
config.block_url("*google*")
config.allow_url('*my_website.com')
end
After reading this article, I tried to do something like:
require 'webmock/rspec'
module WebmockConfig
def self.default_disabled_urls
[
'*google*'
]
end
end
WebMock.disable_net_connect!(allow_localhost: true)
WebMock.disable_net_connect!(allow: WebmockConfig.default_disabled_urls)
but I'm getting
Real HTTP connections are disabled. Unregistered request: POST http://127.0.0.1/session
even if that should be solved by WebMock.disable_net_connect!(allow_localhost: true).
When running the specs without WebMock.disable_net_connect!(allow: WebmockConfig.default_disabled_urls), everything is working fine.
The capybara-webkit white/blacklisting affects the requests made by the browser, whereas WebMock can only affect requests made by your app. This means WebMock is useless for what you want since it wouldn't actually stop your browser from loading anything from google, etc. To do that while using the selenium driver you need to use a programmable proxy like puffing-billy which will allow you to customize the responses for any matching requests the browser makes.
To configure a driver using headless chrome and puffing_billy you could do something like
Capybara.register_driver :headless_chrome do |app|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
browser_options.headless!
browser_options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
Whether or not you need any other options is dependent on your system config, etc but you should be able to tell by looking at your current driver registration.
The allow_localhost: true settings are overwritten by allow: WebmockConfig.default_disabled_urls you have to call WebMock.disable_net_connect! once with both settings or by adding 'localhost', '127.0.0.1' entries into self.default_disabled_urls

Simplest method of enforcing HTTPS for Heroku Ruby Sinatra app

I have an app I created on Heroku which is written in Ruby (not rails) and Sinatra.
It is hosted on the default herokuapp domain so I can address the app with both HTTP and HTTPS.
The app requests user credentials which I forward on to an HTTPS call so the forwarding part is secure.
I want to ensure my users always connect securely to my app so the credentials aren't passed in clear text.
Despite lots of research, I've not found a solution to this simple requirement.
Is there a simple solution without changing my app to Ruby rails or otherwise?
Thanks,
Alan
I use a helper that looks like this:
def https_required!
if settings.production? && request.scheme == 'http'
headers['Location'] = request.url.sub('http', 'https')
halt 301, "https required\n"
end
end
I can then add it to any single route I want to force to https, or use it in the before filter to force on a set of urls:
before "/admin/*" do
https_required!
end
Redirect in a Before Filter
This is untested, but it should work. If not, or if it needs additional refinement, it should at least give you a reasonable starting point.
before do
redirect request.url.sub('http', 'https') unless request.secure?
end
See Also
Filters
Request Object
RackSsl::Enforcer

Jruby sinatra app routing issue within the post route handler ( warbler generated war file sub-uri deployment )

I implemented a small jruby sinatra app and if i run it directly on
WEBrick locally all the routings work perfectly. However when I deploy
the war file (i use warbler) to a server instance (like
"example.com/myapp" or "localhost:8080/myapp") I have routing
issues within the post requests.
For example:
get '/login' do
slim :login
end
post '/login' do
session.clear
login_correct? = check_password (params[:user], params[:pass])
if(login_correct?)
session[:user] = params[:user]
redirect to('/')
else
redirect to('/login')
end
end
get '/redirect' do
redirect to('/login')
end
Here the 3rd route handler (get '/redirect' do ..) redirects to
localhost:8080/myapp/login properly with status code 303, however 2nd route handler redirects
to localhost:8080/login with status code 404.
What should i do so that redirections in post route handler works
properly when i deploy the app?
Thanks a lot!
UPDATE on Solution: After checking the code again and again I realized that the problem was me using form action = '/login' in slim:login instead of form action= "#{url('/login')}". So it wasn't even handled by the post route handler since the post request was sent to localhost:8080/login but I thought it was route handler who is redirecting it to there..
try setting set :prefixed_redirects, true with Sinatra
(it should than use rack.env['SCRIPT_NAME'] with redirects)
UPDATE: even without the set :prefixed_redirects, true (default is false) works perfectly fine under Trinidad (which should behave the same as Warbler since bot use JRuby-Rack) ... request.env['SCRIPT_NAME'] is set to the /context_path correctly.
I would try updating (if they're not the latest) JRuby-Rack/Warbler as well as Sinatra as a last resort, otherwise this probably needs a detailed look at what's going on (esp. if SCRIPT_NAME is set correctly).

Resources