Rails安全会话和cookie不能与CDN一起使用

时间:2018-06-25 15:38:15

标签: ruby-on-rails amazon-web-services session cookies session-cookies

我的设置如下所示:仅带有https和EC2 Instnace原始http的CloudFront CDN(对CloudFront的所有请求都是https,从CloudFront到ec2的所有请求都是http)

如果我在应用程序中将安全性设置为 true ,则会话和cookie将不再保存在任何浏览器中。如果我将其设置为 false ,则它可以在大多数浏览器中使用,但是在Safari中不起作用

Rails.application.config.session_store :cookie_store, key: '_K_session', secure: true

我的目标是使会话适用于所有浏览器。我真的不需要安全的会话设置。

这是我简化的Terraform设置:

resource "aws_cloudfront_distribution" "main_rails_app" {
  origin {
    domain_name = "${aws_elastic_beanstalk_environment.main_rails_app.cname}"
    origin_id   = "${var.cf_main_rails_app_origin_id}"

    custom_origin_config {
      http_port              = "80"
      https_port             = "443"
      origin_protocol_policy = "http-only"
      origin_ssl_protocols   = ["TLSv1.1"]
    }
  }
  default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD", "OPTIONS"]
    target_origin_id = "${var.cf_main_rails_app_origin_id}"

    forwarded_values {
      query_string = true
      headers      = ["*"]

      cookies {
        forward = "all"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }
  viewer_certificate {
    # cloudfront_default_certificate = true
    acm_certificate_arn      = "${data.aws_acm_certificate.some_domain.arn}"
    minimum_protocol_version = "TLSv1.1_2016"
    ssl_support_method       = "sni-only"
  }
  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }
}

2 个答案:

答案 0 :(得分:1)

Cookie存储正在执行应做的工作,Rails在未加密的会话上收到了Cookie,CF至EC2的存储未加密。

您有几种选择。

  1. the documentation
  2. 保持安全:错误,因为您已经信任CF和EC2之间的连接。

Encrypt traffic between ec2 and cf if you want to set to secure: true. And force-ssl redirect as well.

http://guides.rubyonrails.org/v5.0/security.html

答案 1 :(得分:1)

结果证明,即使表单托管在同一域中,而其他一些浏览器也没有,Safari仍会发送Location标头。位置标头值(cdn url)将与应用程序URL(ec2 url)不匹配,并且该请求在rails中将被标记为无效。我使用的是protect_from_forgery而不是protect_from_forgery with: :exception,花了我相当长的时间才能看到,因为我没有收到任何明显的错误。我的解决方案是禁用此设置:

Rails.application.config.action_controller.forgery_protection_origin_check = false

此设置的默认状态已在Rails 5中翻转。