How to verify HSTS is working as expected in Rails application? - ruby-on-rails

Most of the documentation talks about adding config.force_ssl = true which provides HSTS to Rails application. Well, how can I make sure its working as expected? How can I test HSTS header is added for every request? Any help is much appreciated.

Use curl -I https://your_website.domain or browser developer tools to view response headers. You're interested in the Strict-Transport-Security header:
curl -I https://www.ssllabs.com/
HTTP/2 200
date: Fri, 23 Apr 2021 15:25:17 GMT
server: Apache
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
strict-transport-security: max-age=31536000 <-- this one
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-frame-options: DENY
content-type: text/html;charset=ISO-8859-1
content-language: en-US
content-length: 6587
set-cookie: ...
content-security-policy: ...

Related

Getting no 304 response in Chrome/Safari but via curl

I've got a strange issue and I'm running out of ideas. In my Rails(4.2)-App I'm using the fresh_when-Method to invalidate client caches for my blog pages:
def show
#post = Post.find(params[:id])
fresh_when #post
end
With curl everything works out fine, sending the matching Etag gives me a 304 response:
celmare$ curl -i -H 'If-None-Match: "3b4dd96aac692c03ce623db459c9cef2"' https://grosse.io/blog
Response:
HTTP/1.1 304 Not Modified
Connection: keep-alive
Status: 304 Not Modified
Last-Modified: Sun, 04 Oct 2015 10:41:08 GMT
Cache-Control: max-age=0, private, must-revalidate
Strict-Transport-Security: max-age=31536000
X-XSS-Protection: 1; mode=block
X-Request-Id: 68a0ecd2-3fac-4004-ac1e-fd6d14780f61
ETag: "3b4dd96aac692c03ce623db459c9cef2"
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.006207
X-Content-Type-Options: nosniff
Date: Thu, 29 Oct 2015 13:17:02 GMT
X-Powered-By: Phusion Passenger 5.0.15
Server: nginx/1.8.0 + Phusion Passenger 5.0.15
When I open the page in the browser (e.g. Chrome Version 47.0.2526.35 beta (64-bit)) I always get 200 although the Etag still matches:
Request headers:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Cookie:_gat=1; _syscfg_net_v2_session=eGFlYk83Z0kwUE9IYmtUVHg1Z1ppbHF2eFBrUitiTDBsRG1Kbml2bW8vQVZ6YW4xM0ZuRTNOS0w2VmVLM1ZaN0czZno3N0Y2MWpiUWNjQUV0YkVlaXhCZUJyZlJWWEVIZVpPclFaaHZxdFNncjNBVVg3MFR2SE0yWDRUaklsSlRMbmw4OVQrQmlDRHBIbmRSMS9VVml3PT0tLTYvUGdURTRaRjNXSU9WOTdOY1F3OEE9PQ%3D%3D--3bafbda7d522c61cd9fd04898c2c6a4bac06131b; _ga=GA1.2.235147781.1445350582
Host:grosse.io
If-Modified-Since:Sun, 04 Oct 2015 10:41:08 GMT
If-None-Match:W/"3b4dd96aac692c03ce623db459c9cef2"
Referer:https://grosse.io/blog
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.35 Safari/537.36
Response headers:
Cache-Control:max-age=0, private, must-revalidate
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Thu, 29 Oct 2015 13:16:48 GMT
ETag:W/"3b4dd96aac692c03ce623db459c9cef2"
Last-Modified:Sun, 04 Oct 2015 10:41:08 GMT
Server:nginx/1.8.0 + Phusion Passenger 5.0.15
Set-Cookie:_syscfg_net_v2_session=MUtjWlQyY1ZFZnF2TzlvTDJkdnpmMDhqVmhoVld5YkJDdHl5NUtIdXJTY1VZQ1AzV1NVMjF1alFDSE9NKzliOGhzcmc4S3FLajRmNGFZUjltQzdPNDg4SW51aUxGU2xDd0FxVi82UFZneE5YU1FnTjJVSFhpL3RCQkNYdjlFVTlyZVRRU0ZPdG83UFNVbjVyckJmZ0R3PT0tLXh4Zzg0cjhBSTZKbVpkayttanpwUFE9PQ%3D%3D--dc404af2428a17085bea4b40a3f4f0fc6ef01e50; path=/; secure; HttpOnly
Status:200 OK
Strict-Transport-Security:max-age=31536000
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Powered-By:Phusion Passenger 5.0.15
X-Request-Id:0633095f-b95d-4339-8e62-8b15683c2d8c
X-Runtime:0.034172
X-XSS-Protection:1; mode=block
And on top: In my local env it's working with the same browser. I can hardly imagine that it is a NGINX thing because the everything is configured very defaulty. Could it be something with HTTPS?
Any ideas? Thanks in advance.
Ok, I found the cause. It's a problem with NGINXs gzip compression in combination with weak "W/" Etags. Will try upgrading NGINX or using a Patch.
Adding etag on; after gzip on; in nginx.conf fixed the problem from 1.7.4 and newer.

Nginx X-Frame-Options

i use nginx 1.8.0 under centOS 6.7 which serving Ruby On Rails 4.2.3 application.
The Problem:
I need to enable iframe options for all domains so tried this:
X-Frame-Options: *
then when i check headers i see it twice 1 time with SAMEORIGIN and one time with *, here is the response:
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Sun, 01 Nov 2015 15:48:32 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Status: 200 OK
Strict-Transport-Security: max-age=31536000
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
ETag: W/"d14b3de05fb18ebe4a94774c8f209e7f"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: guess_locale=en; path=/; secure
Set-Cookie: _admin_numgames_com_session=Y3N0QjR2NXY0VFlZMlVnMHJLZC9WbUVraldZYjhpeHo0UG41akpaZE1rb0tQWS9YeGpkcklTRmViUU5aVmJpUElCcWpMaFJWQmpIWHRSazI4TE9QdTgvQ2VVRGYrSW9VcjA4eWVCMVlsUHJRejR1WmNoQWZoL2hGeVA1ZHp5YWxPdFZ4S25ydEtTamVnbFlZMEhJRDdXalQ2MU93T24vWnR6b28wM0NvYS82Nm1XMGV2Njh4djIzR1RNb2w3WTVHUDM3cVl3NnVrQnJ1WTMyU3I4dVBjY3RORWRQSlk2VmhNVnRVelZRbHRVWT0tLU9DYVBIZUxoUXlLN2VmZ01VNEhab3c9PQ%3D%3D--fa2a9d6817b5464b82a2babd784ed098f2526eeb; path=/; secure; HttpOnly
X-Request-Id: 4762503a-a9a8-41ce-b1a7-26269b7e9184
X-Runtime: 0.963198
X-Frame-Options: *
there is only 1 time declare this option so why i see it twice? and how do i remove this option so any one will be able to use my domain with iFrame?
OK so i found the solution and Rails was the problem he sent the header, just needed to add into production.rb file:
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'ALLOWALL'
}

Remove Http header response

I am working on a project which requires a client to make an api call to
my
rails application and it to return XML without any http header info.
its currently returning:
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Content-Type: application/xml; charset=
X-Ua-Compatible: IE=Edge
X-Request-Id: c5602cd7eb23ca8137bef8bb1f0a4f8a
X-Runtime: 0.027900
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-11-22)
Date: Wed, 18 Jun 2014 05:27:48 GMT
Content-Length: 529
Connection: Keep-Alive
Set-Cookie: _session_id=a8039d615674feec206e6c55a7a7afc8; path=/;
HttpOnly
<?xml version="1.0" encoding="UTF-8"?>
<cXML>
<Response>
<Status code="200" text="OK"/>
<StartPage>
<URL>http://localhost:3000/foobar/BAh7DDoNYmFza2V0aWRJI...
</StartPage>
</Response>
</cXML>
Can anyone help to remove all the http headers within the controller or any
config? which is below section.
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Content-Type: application/xml; charset=
X-Ua-Compatible: IE=Edge
X-Request-Id: c5602cd7eb23ca8137bef8bb1f0a4f8a
X-Runtime: 0.027900
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-11-22)
Date: Wed, 18 Jun 2014 05:27:48 GMT
Content-Length: 529
Connection: Keep-Alive
Set-Cookie: _session_id=a8039d615674feec206e6c55a7a7afc8; path=/;
HttpOnly
I am using nginx at the moment.
I have some says that this is kind of a nonsense request, since HTTP servers by
definition uses header to talk to one another. But I have also been informed that W3 think otherwise.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4
I have also googled around for hours attempting other solutions changing my rails controller without any success. Is the last resort possibly changing config in Nginx and wouldn't that effect the whole rails application and not just the api calls or is there a way to single out one call?
Thanks in advance.
T
This is a nonsense request, yeah. You can use the HttpHeadersMore module to remove most of the response headers. Something like this should do it:
location /your/api/path {
more_clear_headers '*';
}
However, you can't remove the Connections header without patching nginx. And even if you could, you can't remove the first line of the response ("HTTP/1.1 200 OK", in this case). Without that line, it isn't an HTTP response. You're going to have a hard time convincing an HTTP server to send non-HTTP responses.
To get what you're describing, I think you'll need a custom server that communicates over bare TCP sockets. This tutorial might help you out. Or maybe you could implement that part of your app in node.js (or another tool)?

Twitter oauth/request_token API using Fiddler results in 401 error

I am trying to use fiddler to test the oauth/request_token api but am getting a 'Failed to validate oauth signature and token' 401 error. I copied the authorization header values directly from my application and added an oauth_callback header. I am trying to follow the example in the following documentation:
https://dev.twitter.com/docs/api/1/post/oauth/request_token.
Any help would be greatly appreciated.
REQUEST:
POST https://api.twitter.com/oauth/request_token HTTP/1.1
Authorization: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A61921%2Ftwitter%2Fprocesscallback", oauth_consumer_key="XXXXXXXXXXXXXXXXXXXXX", oauth_nonce="53891723ad7b32501c669d97f56c6d47", oauth_signature="qzN516EVspIA0NWBbpND83YcTr4%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1402955245",
oauth_token="2514015781-KqTbOPPag7p0CYQ6xByIibV3WEk8xLsWrhb9U4M",
oauth_version="1.0"
Host: api.twitter.com
Content-Length: 0
RESPONSE:
HTTP/1.1 401 Unauthorized
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-length: 44
content-type: text/html; charset=utf-8
date: Mon, 16 Jun 2014 21:54:56 GMT
expires: Tue, 31 Mar 1981 05:00:00 GMT
last-modified: Mon, 16 Jun 2014 21:54:56 GMT
pragma: no-cache
server: tfe
set-cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCEIJraZGAToHaWQiJTlmOTQ3Y2MyYWNlMTkx%250AYTMyYzVlZmYyMTA4ZjU4ZTdkIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--3afebfe1105e8a7315baba72651e76a24f53e6d2; domain=.twitter.com; path=/; secure; HttpOnly
set-cookie: guest_id=v1%3A140295569643962216; Domain=.twitter.com; Path=/; Expires=Wed, 15-Jun-2016 21:54:56 UTC
status: 401 Unauthorized
strict-transport-security: max-age=631138519
vary: Accept-Encoding
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-mid: d31abfd0b6cbb0aa6434a6ffc6efdfac089ab0a5
x-runtime: 0.01273
x-transaction: 2dd94ca53f553801
x-ua-compatible: IE=edge,chrome=1
x-xss-protection: 1; mode=block
Failed to validate oauth signature and token

Google cloud print get access token

I want to call /search method of Google cloud print from my webServer.
I am using OAuth web server guide obtaining a refresh_token/access_token to use with scopes:
https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile
Then I am calling search Api but I am obtaining a 403 forbidden.
Request DefaultHttpRequest(chunked: false)
POST /cloudprint/search HTTP/1.1
Host: www.google.com
Content-Type: text/plain; charset=utf-8
Authorization: OAuth yb29.1.AADtN_U9PYyVhGpcS-8MpFhfGVbT4KsZKEoIX2HGePwoNXypjrSwVsS0pGzmaqhktfGBAQ
Connection: keep-alive
Accept: */*
User-Agent: NING/1.0
Content-Length: 0
Response DefaultHttpResponse(chunked: true)
HTTP/1.1 403 Forbidden
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Tue, 03 Dec 2013 17:05:09 GMT
Set-Cookie: NID=67=MQJFdl-YkMdz875n1J2yVNmeUeAvsjVtDGlNvGkNLZdNTHX3YbnStNx9Vg_MiRsmht6hj3XrwJcPJEQeFLlnYKqt2Of1xHJ5HDwNJgOB3svOdnN-JRFcPxYt4AU10eSM;Domain=.google.com;Path=/;Expires=Wed, 04-Jun-2014 17:05:09 GMT;HttpOnly
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic
Transfer-Encoding: chunked
Is the scope correct?
What am I doing wrong?
Your scopes are wrong. The correct scope is https://www.googleapis.com/auth/cloudprint
I think this related to your HTTP Header 'Authorization'.
When playing at https://developers.google.com/oauthplayground/, I see the generated requests use 'Authorization: Bearer your-token', instead of 'Authorization: OAuth your-token'.

Resources