【インターンレポート】社内で開発されているソフトウェアのセキュリティ診断を行いました

はじめに

技術職 就業型コースのインターンシップに参加した仲西朋也です。今回、LINEのサービス全般のセキュリティ強化を担う、アプリケーションセキュリティチームに所属し、実際の業務内容を体験することができました。このレポートでは、インターン期間中に取り組んだ内容について紹介します。

社内で開発されているソフトウェアのセキュリティ診断

インターン期間中、実際に与えられる業務内容とは別に、自身でやってみたいことを考え、実際にさせて頂く機会がありました。僕は、社内で開発されているソフトウェアのセキュリティ診断を行うことにしました。LINEでは、ユーザーに提供するサービス自体の開発以外にも、社内で利用するためのフレームワークやミドルウェアなどの開発も盛んに行われています。これらは、ソースコードが外部に公開されていないものが大部分を占めており、セキュリティの問題を見つけやすいと考えました。

セキュリティの診断を行う中で、興味を引いた脆弱性としてCRLFインジェクションというものがありました。HTTPのメッセージには大きく分けて、開始行、ヘッダ(header)と本文(body)の3つの部分があります。これらを識別するための区切りとして、改行文字の[CR][LF](ASCIIコード0x0d、0x0a)を使用します。また、ヘッダにはヘッダ名と値のペアを複数指定することができますが、これらの区切りも基本的には[CR][LF]を利用します。

今回、診断したソフトウェアには、クライアント側からのリクエストパラメータを利用して、他のサーバーに送信するリクエストのヘッダの値を設定するという処理がありました。

ここで、ヘッダに利用する値に[CR][LF]が含まれていると、リクエストを受け取ったサーバー側では、ヘッダや本文のための区切り文字として解釈してしまう恐れがあります。そうすると、攻撃者は開発者の意図しないヘッダや本文を送信できてしまいます。このような脆弱性をCRLFインジェクションと呼びます。

CRLFインジェクションによって、一般的には以下のような攻撃が可能になります。

  • Set-Cookieヘッダを利用したCookieの固定化
  • Locationヘッダを利用したリダイレクト
  • HTTPメッセージ本文の改ざん
  • レスポンス分割によるキャッシュ汚染

対策としては、以下のようなものが挙げられます。

  • ユーザーからの入力をHTTPヘッダの値として利用しない
  • ユーザーからの入力を利用する場合には、CRLFが含まれないようにチェックを行う

今回のケースでは、一部の例外を除き、ヘッダの値に[CR][LF]が入っている文字列を設定しようとするとサーバー側でエラーが発生します。これによって、他サーバーへのリクエストの意図しない場所に[CR][LF]が挿入されることがなくなり、攻撃は成立しません。ここでエラーとならない一部の例外が、HTTP/1.1を規定したRFC 2616に記載されているLWSである場合です。LWSは、ヘッダの値を複数行に渡って記述するために利用する文字列です。RFC 2616では、[CR][LF]に続いて、[SP](ASCIIコード0x20)または[HT](ASCIIコード0x09)がある(LWS)場合にはヘッダの区切りではなく、前のヘッダの値の続きとして解釈するように規定されています。

しかし、このLWSを通常の[CR][LF]と同じように解釈してしまうケースがあります。それがInternet Explorerの実装で、LWSを許可してしまうと、CRLFインジェクションと同様の攻撃が成立してしまいます。幸いなことに、今回診断したソフトウェアでは、Internet Explorerにこのようなヘッダを送信してしまうこともありませんでした。

本来、これはInternet Explorer側の実装の問題に思えるのですが、https://www.mbsd.jp/blog/20150730.html の記事によると、この問題を修正しないという回答だったようです。また、HTTP/1.1の最新の改訂版であるRFC 7230では、このようなリクエストを生成することを禁止しています。よって、この対策としては、RFC 7230に従って、LWS(RFC 7230ではobs-fold)をヘッダに含むHTTPメッセージを生成しないことが挙げられます。

今回診断したソフトウェアでは、ヘッダの値のチェックにNettyというフレームワークの機能を利用していました。Nettyの利用方法によっては、Internet ExplorerへHTTPメッセージを送信する場合のチェックが不十分であると言えます。この問題については、GitHub上で報告を行いました。https://github.com/netty/netty/issues/10574

リスクアセスメント業務

リスクアセスメント業務では、LINEのサービスのリリース前にセキュリティ上の問題や潜在的なリスクがあるかどうかを診断します。サービスの開発者と連絡を取りながら、サービスが利用できる環境やソースコードを提供してもらい、診断で問題が見つかった場合には、修正をしてもらった上で、この修正にも問題がないかどうかの確認を行います。

この業務を行った際に、とある脆弱性を開発者側に修正してほしいということを伝えました。その後、どのようにこの脆弱性が利用され、攻撃が成立するのかという説明を開発者側に求められるということがありました。見つかった問題が実際の攻撃とならなくても、他の脆弱性と組み合わせることで攻撃が成立してしまうことがあります。よって、潜在的なリスクがどのように発現するのかを考え、説明できる能力も非常に大切だと感じました。

全体を通しての感想

今回のインターンでは、社員と同様に実際の業務を行うことができました。そのため、インターン生だからといって、過去にあった脆弱性への閲覧が制限されていたということもなく、様々な脆弱性の例を見ることができました。今回所属したチームでは、LINE Security Bug Bounty Program(https://bugbounty.linecorp.com/ja/)の運営も行っており、実際に日々届けられている脆弱性レポートを見ることができたのも、非常に面白かったです。また、様々なサービスを提供しているLINEで、どのようにシステムが構築されているのか、どのようなライブラリやフレームワークを利用しているのかを知ることができたのも良かったです。

今年は、リモートワークという形での開催となり、朝早く起きて出社する必要がないというのは非常に楽な点でした。ただ、社員の方と直接的なコミュニケーションをとる機会や、オフィスに実際に行くことができる機会が少なかったのは少し残念でした。

インターン期間中にお世話になったアプリケーションセキュリティチームで働いている社員の方は、皆さんセキュリティの知識が豊富で、インターン期間中に様々なアドバイスを頂くことができました。このようなハイレベルな環境で働くことができ、自分としても、とても貴重な経験となりました。セキュリティに興味のある方は今後開催されるインターンにぜひ挑戦してみてください。

Related Post