この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
最近会社においてあるグランツーリスモをやっているもこ@札幌オフィスです。
Lambda@Edgeを利用してオリジンから送られる Set-Cookie
を書き換えて、送信されるCookie全てにSecure属性とHttOnlyを付けてみました。
コード
今回利用したコードはこんな形になっています。
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
for (const cookie of response.headers['set-cookie']) {
cookie.value += "; Secure; HttpOnly"
}
callback(null, response);
}
利用方法
オリジンから送信されてくる情報を書き換える必要があるため、CloudFrontイベントは"オリジンレスポンス"を利用します。
また、CloudFrontの設定、「Forward Cookies」をAllなどに変更する必要があります。(キャッシュのヒット率は下がります。)
関数を作成し
上記コードを貼り付け
ロールを作成し、保存します。
上のアクションから「Lambda@Edgeへのデプロイ」を選択し、
デプロイ先のCloudFrontを選択し、CloudFrontイベントををオリジンレスポンスに変更します。
User <-> CloudFront(Lambda@Edge) <-> ALB <-> EC2
のような環境を作成し、
適当なCookieを投げるようなアプリケーションを作り、EC2上に起動しました。
const express = require('express')
const app = express();
app.get('/', (req, res) => {
res
.cookie('hoge', 'hoge')
.cookie('test', 'test')
.status(200).send('OK');
})
app.listen(80)
ALBを叩いてSet-Cookieヘッダーが追加されているのを確認します。
$ curl -I xxxxx-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com
HTTP/1.1 200 OK
Date: Fri, 20 Sep 2019 8:14:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 2
Connection: keep-alive
X-Powered-By: Express
Set-Cookie: hoge=hoge; Path=/
Set-Cookie: test=test; Path=/
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
Lambda@EdgeのCloudFrontへのデプロイが終わり、curlで叩いてみると、正常に ; Secure; HttpOnly
が追加されているのを確認出来ます。
$ curl -I http://xxxxx.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 2
Connection: keep-alive
Server: CloudFront
Date: Fri, 20 Sep 2019 8:12:23 GMT
X-Powered-By: Express
Set-Cookie: hoge=hoge; Path=/; Secure; HttpOnly
Set-Cookie: test=test; Path=/; Secure; HttpOnly
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
X-Cache: Miss from cloudfront
Via: 1.1 171d3bd7ed02f868a62075a1caaa7993.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT53
X-Amz-Cf-Id: Fm3nsyZ2_N7viWjvfQ_DSjz9B9lR45Rz0JHQBrAgg3qHBmZtSIf9Ag==
また、HttpOnlyの効果により document.cookie
の取得も出来なくなっているのが確認できます。
まとめ
CloudFrontのオリジンレスポンスを利用すると、アプリケーション側ではなくLambda@Edge側で強制的にヘッダーを書き換えることが出来るので、とても便利です。
Lambda@Edgeの使い方次第ではサーバーレスではない環境に対してもサーバーレスチックな使い方が出来ると思います。
誰かのお役に立てれば幸いです。