Slide 1

Slide 1 text

S 3 o Õ é Ã È g B ‰ A W S l  S D K k ‡ X ( W _  r Ø M U R L k J Q ‰ Ñ ¹ È é Ð ü µ ë  1 ' J A W S D A Y S 2 0 2 6 × í Õ § Ã · ç Ê ë µ ü Ó ¹ è ~ Ł | *  @ r y o t a r o m o s a o  Á ç ó ¦ £ Á ç ë

Slide 2

Slide 2 text

© 2 025 GM O Flat t Sec urity Inc. A ll Ri ghts R e serve d. êñ9Ë Ma ts ui Ryot aro @r yotar om osao G M O F l a t t S e c u r i t y ( * ) × í Õ § Ã · ç Ê ë µ ü Ó ¹ è » å ê Æ £ ¨ ó ¸ Ë ¢ q  ' f ' f b Å 1 Ñ f  v Ñ î ƒ „  G M O F l a t t S e c u r i t y *  ˆ > k e > × í Õ § Ã · ç Ê ë µ ü Ó ¹ è k J D f W e b ¢ × ê ± ü · ç ó — ¯ é ¦ É  L L M ¢ × ê ± ü · ç ó n  1 ' : û Ú Í È ì ü · ç ó Æ ¹ È k fi ‰ A W S R e d T e a m E x p e r t  Ê o G C P n É 7 - £ s o » À h ê \ ü Ü ü É ™ ˙ Y S h

Slide 3

Slide 3 text

© 2 025 GM O Flat t Sec urity Inc. A ll Ri ghts R e serve d. êñ9Ë Ç ª ˆ g » À h ü Ü ü É n q ™ W ~ W ⁄ F  Õ é Ã È » À è h þ & W f O „ ‰ ¹ ß Æ -

Slide 4

Slide 4 text

© 2 025 GM O Flat t Sec urity Inc. A ll Ri ghts R e serve d. êñ9Ë Áçó ¦£ Áçë G M O F l a t t S e c u r i t y ( * ) × í Õ § à · ç Ê ë µ ü Ó ¹ è » å ê Æ £ ¨ ó ¸ Ë ¢ ( W e b ¢ × ê ± ü · ç ó — A P I : n Ö  ¯ é ¦ É : — Ú Í È ì ü · ç ó Æ ¹ È k fi ‰ O S C E 3 , O S C P j i n O f f S e c û n Ç < ™ Ý ¯ é ¦ É » å ê Æ £ n Ç < h W f H a c k T r i c k s n A R T E  G R T E  A z R T E h P w n e d L a b s n M C R T P  A C R T P ™ Ö Š G C R T P ™ Ö Š Y ‰ _ † Ö − D fi g D ‰

Slide 5

Slide 5 text

£so«éª±hÐó¸ü¸ ã ó ×  ? © 2 025 GM O Flat t Sec urity Inc. A ll Ri ghts R e serve d. êñ9Ë

Slide 6

Slide 6 text

Our Miss i on ¨ó¸ Ë ¢n Ì-™ K ‰ ‹ − ˆ O n ¨ ó ¸ Ë ¢ L ‡ n e O − k Æ - g M ‰ > ˆ ™  » å ê Æ £ b K › d O ‰ ˆ >

Slide 7

Slide 7 text

Ðłµü Ó¹  1 ' : û Ú Í È ì ü · ç ó Æ ¹ È ™ × í Õ § à · ç Ê ë µ ü Ó ¹ / A I g ˆ Ò — k Ð ł •¶û Ø ¦ : ³ ü É û Õ Ø n  ’ ‡ L D   • ¶ L  1 ' ™ ² – — k z ‰ AIûŽı: Ž ı — j » å ê Æ £ ì Ó å ü ™ ( A I ¨ ü ¸ § ó È g ! X k þ

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

,ånJÁøM 署名付きURLと 署名付きURLにおけるパストラバーサ AWS公式SDKにおけるパストラバーサ アプリケーション開発者の誤った実装によるパストラバーサ 署名付きURLとは 署名付きURLの権限まわりの仕様 署名付きURLの2つ形 S3のフラット構造 署名付きURLにおけるパストラバーサ AWS SDK for Go(v1) AWS SDK for JavaScript(v3

Slide 11

Slide 11 text

署名付きURLと r ØMURLho ûAm azon S3 nªÖ ¸§¯ÈkþY ‰B—j ¢¯» ¹) ™Ø W_ UR L û ˆ 8  S 3 n ª Ö ¸ § ¯ È ™ Í \ Y ‰ k o  Å † j ) P L Ø  U „ _ I A M n “ < Å 1  ‡ W O o þ a í ü ë ™ A s s u m e R o l e W f Ö Š W _ B — j “ < Å 1 ™ ( D f   . Í \ ™ L F Å † û S 3 k B ‰ ª Ö ¸ § ¯ È ™ B — k l ‰ W _ D 4  —  I A M “ < Å 1 ™  c f D j D º k þ W f B — k ª Ö ¸ § ¯ È n À ¦ ó í ü É / ¢ Ã × í ü É ™ 1 ï W _ D 4  k ) ( ï ý û ¢ × ê ± ü · ç ó µ ü Ð ü ™ L 1 [ Z k  ¯ é ¤ ¢ ó È h S 3 fi g ô ¥ ª Ö ¸ § ¯ È n  × á L g M  µ ü Ð ü n € w ™ ' E k J ˙ ï ý

Slide 12

Slide 12 text

署名付きURLと ‰ ) h t t p s : / / m y - f l a t t - b u c k e t . s 3 . a p - n o r t h e a s t - 1 . a m a z o n a w s . c o m / s a m p l e - i m a g e . j p g ? X - A m z - A l g o r i t h m = A W S 4 - H M A C - S H A 2 5 6 & X - A m z - C r e d e n t i a l = A K I A I O S F O D N N 7 E X A M P L E % 2 F 2 0 2 6 0 3 0 2 % 2 F a p - n o r t h e a s t - 1 % 2 F s 3 % 2 F a w s 4 _ r e q u e s t & X - A m z - D a t e = 2 0 2 6 0 3 0 2 T 1 3 3 1 5 0 Z & X - A m z - E x p i r e s = 3 6 0 0 & X - A m z - S i g n e d H e a d e r s = h o s t & X - A m z - S i g n a t u r e = a e e 0 3 9 9 4 e 6 3 b d 6 4 8 1 . . . my-flatt-bucketnsample-image.jpg™À¦óíüÉY‰r ØMURLn‰

Slide 13

Slide 13 text

署名付きURLと û U R L n z L C  r k ( D _ I A M ) P ê « L  þ a n Í \ k Å † j ) P ™  c f D ‰ 4  k P − ¢ ¯ » ¹ L 1 ï U „ ‰ < m y - f l a t t - b u c k e t n ª Ö ¸ § ¯ È k þ Y ‰ À ¦ ó í ü É ( n r Ø M U R L ™ z L W _ D 4  n I A M Ý ê · ü > 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 { " V e r s i o n " : " 2 0 1 2 - 1 0 - 1 7 " , " S t a t e m e n t " : [ { " S i d " : " A l l o w D o w n l o a d F r o m B u c k e t A " , " E f f e c t " : " A l l o w " , " A c t i o n " : [ " s 3 : G e t O b j e c t " ] , " R e s o u r c e " : [ " a r n : a w s : s 3 : : : m y - f l a t t - b u c k e t / * " ] } ] } r ØMURLn)P~‘−nÕØ

Slide 14

Slide 14 text

署名付きURLと パス形 バケット名をURLのパス部分に配置する形式 元々「2020年9月30日以降に作成されたバケットに対するパス形式のサポート廃止[1]」が予 定されていた。しかし、バケット名にドット(.)が含まれる環境でのSSL/TLS証明書の検証 課題[2]などの問題から延期している r ØMUR Ln2dn b htt ps: //s3. ${reg i on- cod e}. ama zo naw s. com/$ {bu cke t-n ame }/$ {obj ect -ke y} 仮想ホスト形 バケット名をサブドメインの一部として配置する形 [1]https://aws.amazon.com/jp/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story ht tp s:/ /${ bucket - name} .s 3.${ reg ion -co de}.ama zon aws.com/ ${obje ct-key} [2]https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-logging-s3.htm

Slide 15

Slide 15 text

署名付きURLにおけるパストラバーサ S3はOSのファイルシステムが持つようなディレクトリ構造は持たず、フラットな構造で オブジェクトを管理している マネジメントコンソールで見えているフォルダ的な概念はスラッシュでいい感じに区切っている だけにすぎな S3n ÕéÃÈË I n A m a z o n S 3 g e n e r a l p u r p o s e b u c k e t s , o b j e c t s a r e t h e p r i m a r y r e s o u r c e s , a n d o b j e c t s a r e s t o r e d i n b u c k e t s . A m a z o n S 3 g e n e r a l p u r p o s e b u c k e t s h a v e a f l a t s t r u c t u r e i n s t e a d o f a h i e r a r c h y l i k e y o u w o u l d s e e i n a f i l e s y s t e m . H o w e v e r , f o r t h e s a k e o f o r g a n i z a t i o n a l s i m p l i c i t y , t h e A m a z o n S 3 c o n s o l e s u p p o r t s t h e f o l d e r c o n c e p t a s a m e a n s o f g r o u p i n g o b j e c t s .  A m a z o n S 3 n N ( Ð ± Ã È g o  ª Ö ¸ § ¯ È L ; † j ê ½ ü ¹ g B −  ª Ö ¸ § ¯ È o Ð ± Ã È k < U „ ~ Y  A m a z o n S 3 N ( Ð ± Ã È o Õ é Ã È j Ë g B −  Õ ¡ ¤ ë · ¹ Æ à k ‰ › „ ‰ ‹ F j ” d o B − ~ [ fi  _ ` W  Ë ™  K − — Y O Y ‰ _ †  A m a z o n S 3 ³ ó ½ ü ë g o  ª Ö ¸ § ¯ È n ° ë ü ×  n ¹ Õ h W f Õ © ë À n ‡ õ ™ µ Ý ü È W f D ~ Y  [3 ]h https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-folders.htm

Slide 16

Slide 16 text

署名付きURLにおけるパストラバーサ S3はOSのファイルシステムが持つようなディレクトリ構造は持たず、フラットな構造で オブジェクトを管理している マネジメントコンソールで見えているフォルダ的な概念はスラッシュでいい感じに区切っている だけにすぎな S3n ÕéÃÈË I n A m a z o n S 3 g e n e r a l p u r p o s e b u c k e t s , o b j e c t s a r e t h e p r i m a r y r e s o u r c e s , a n d o b j e c t s a r e s t o r e d i n b u c k e t s . A m a z o n S 3 g e n e r a l p u r p o s e b u c k e t s h a v e a f l a t s t r u c t u r e i n s t e a d o f a h i e r a r c h y l i k e y o u w o u l d s e e i n a f i l e s y s t e m . H o w e v e r , f o r t h e s a k e o f o r g a n i z a t i o n a l s i m p l i c i t y , t h e A m a z o n S 3 c o n s o l e s u p p o r t s t h e f o l d e r c o n c e p t a s a m e a n s o f g r o u p i n g o b j e c t s .  A m a z o n S 3 n N ( Ð ± Ã È g o  ª Ö ¸ § ¯ È L ; † j ê ½ ü ¹ g B −  ª Ö ¸ § ¯ È o Ð ± Ã È k < U „ ~ Y  A m a z o n S 3 N ( Ð ± Ã È o Õ é Ã È j Ë g B −  Õ ¡ ¤ ë · ¹ Æ à k ‰ › „ ‰ ‹ F j ” d o B − ~ [ fi  _ ` W  Ë ™  K − — Y O Y ‰ _ †  A m a z o n S 3 ³ ó ½ ü ë g o  ª Ö ¸ § ¯ È n ° ë ü ×  n ¹ Õ h W f Õ © ë À n ‡ õ ™ µ Ý ü È W f D ~ Y  [3 ]h https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-folders.htm OS ìÙëg 囄 f D ‰ ‹ F j Ñ ¹ ÈéÐü µëo wMj D

Slide 17

Slide 17 text

署名付きURLにおけるパストラバーサ r ØMUR L nѹ È é ˜

Slide 18

Slide 18 text

署名付きURLにおけるパストラバーサ 1 2 3 4 5 6 7 8 9 1 0 1 1 f u n c g e n e r a t e P r e s i g n e d U R L ( t e n a n t I D , u s e r I n p u t F i l e n a m e s t r i n g ) ( s t r i n g , e r r o r ) { o b j e c t K e y : = f m t . S p r i n t f ( " t e n a n t s / % s / f i l e s / % s " , t e n a n t I D , u s e r I n p u t F i l e n a m e ) / / t e n a n t I d : " m y - t e n a n t " r e q , _ : = s 3 C l i e n t . G e t O b j e c t R e q u e s t ( & s 3 . G e t O b j e c t I n p u t { B u c k e t : a w s . S t r i n g ( " m y - b u c k e t " ) , K e y : a w s . S t r i n g ( o b j e c t K e y ) , } ) r e t u r n r e q . P r e s i g n ( 1 5 * t i m e . M i n u t e ) } ‰ ) Þ ë Á Æ Ê ó È n W e b ¢ × ê ± ü · ç ó k J D f S 3 Ð ± Ã È – n × ì Õ £ Ã ¯ ¹ g Æ Ê ó È Î k ª Ö ¸ § ¯ È ™ ¡  W f D ‰ 4  r Ø M U R L ™ ˜  Y ‰ N g  S D K – è — ¢ × ê ± ü · ç ó ³ ü É – g c ‘  L L ‘ „ ‰ h  . . / L ã z U „ f W ~ D   ó W j D Ð ± Ã È — ª Ö ¸ § ¯ È n r Ø M U R L L z L U „ f W ~ F  1 ' c‘M t e n a n t s / m y - t e n a n t / f i l e s / . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t c‘„ te nant s/o the r-t e nant /f iles / secre t. txt

Slide 19

Slide 19 text

署名付きURLにおけるパストラバーサ D — D —  ¦ Á o Æ Ê ó È Î k Ð ± Ã È (  W f ‰ K › '  + c ¹ 

Slide 20

Slide 20 text

署名付きURLにおけるパストラバーサ D — D —  ¦ Á o Æ Ê ó È Î k Ð ± Ã È (  W f ‰ K › '  + c ¹  

Slide 21

Slide 21 text

S„K›qY Sh 2つのAWS公式のSDKで署名付きURLのパストラバーサルを見つけた事例 SDK側で対策がされていても、アプリケーション開発者の実装ミスでパストラバーサル が起こるパター

Slide 22

Slide 22 text

AWS SDK for Go(v1)におけるパストラバーサ 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 f u n c ( c * S 3 ) G e t O b j e c t R e q u e s t ( i n p u t * G e t O b j e c t I n p u t ) ( r e q * r e q u e s t . R e q u e s t , o u t p u t * G e t O b j e c t O u t p u t ) { o p : = & r e q u e s t . O p e r a t i o n { N a m e : o p G e t O b j e c t , H T T P M e t h o d : " G E T " , H T T P P a t h : " / { B u c k e t } / { K e y + } " , } i f i n p u t = = n i l { i n p u t = & G e t O b j e c t I n p u t { } } o u t p u t = & G e t O b j e c t O u t p u t { } r e q = c . n e w R e q u e s t ( o p , i n p u t , o u t p u t ) r e t u r n } Go(v1)では、署名付きURLを発行する際にSDK内部で複数ステップを経て最終的なURLが 組み立てられる 発行されるURLの形式(パス形式 or 仮想ホスト形式)によって、パストラの影響が異な Requestオブジェクトの生 例えばGetObjectの場合、 GetObj ec tRequest()が呼 び出される HTTPPa th: "/{B uck et}/{ Key+}"というテンプレー トは、c.n ew Requestの内部処理でエンドポイント URL のパス部分にそのまま結合される
 (例: https://s3.us-east-1.amazonaws.com /{ Buc ke t}{ Ke y+} )

Slide 23

Slide 23 text

AWS SDK for Go(v1)におけるパストラバーサ 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 f u n c ( r * R e q u e s t ) S i g n ( ) e r r o r { r . B u i l d ( ) i f r . E r r o r ! = n i l { d e b u g L o g R e q E r r o r ( r , " B u i l d R e q u e s t " , n o t R e t r y i n g , r . E r r o r ) r e t u r n r . E r r o r } S a n i t i z e H o s t F o r H e a d e r ( r . H T T P R e q u e s t ) r . H a n d l e r s . S i g n . R u n ( r ) r e t u r n r . E r r o r } 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 f u n c u p d a t e E n d p o i n t F o r S 3 C o n f i g ( r * r e q u e s t . R e q u e s t , b u c k e t N a m e s t r i n g ) { f o r c e H o s t S t y l e : = a w s . B o o l V a l u e ( r . C o n f i g . S 3 F o r c e P a t h S t y l e ) a c c e l e r a t e : = a w s . B o o l V a l u e ( r . C o n f i g . S 3 U s e A c c e l e r a t e ) i f a c c e l e r a t e & & a c c e l e r a t e O p B l a c k l i s t . C o n t i n u e ( r ) { i f f o r c e H o s t S t y l e { i f r . C o n f i g . L o g g e r ! = n i l { r . C o n f i g . L o g g e r . L o g ( " E R R O R : . . . " ) } } u p d a t e E n d p o i n t F o r A c c e l e r a t e ( r , b u c k e t N a m e ) } e l s e i f ! f o r c e H o s t S t y l e & & r . O p e r a t i o n . N a m e ! = o p G e t B u c k e t L o c a t i o n { u p d a t e E n d p o i n t F o r H o s t S t y l e ( r , b u c k e t N a m e ) } } パス形式 / 仮想ホスト形式の判 Sign()内のr.Build()でURLの組み立てが行われ endpointHandlerから呼び出され updateEndpointForS3Config()によって、形式が決定
 され

Slide 24

Slide 24 text

AWS SDK for Go(v1)におけるパストラバーサ パス形式 / 仮想ホスト形式の判 バケット名がIPアドレス形式(例:192.0.2.1) バケット名に`..`が含まれている スキームがHTTPS(デフォルト)かつバケット名に`.`を含むな DNS ^™Ûn†ö aö UR Lb  S3 Forc ePath Sty le == true ѹb S3F orcePathS tyle == fals eÇÕ©ëÈ KdÐ±Ã È L DN S^ ™Û ѹb S3ForcePat hSty le == fa lseKd Ð±Ã È LDN S™Û îóÛ¹ Èb

Slide 25

Slide 25 text

AWS SDK for Go(v1)におけるパストラバーサ パス形式 / 仮想ホスト形式の判 仮想ホスト形式が選択された場合、moveBucketToHost()によってバケット名がサブドメインに移 removeBucketFromPath()によりパスから /{Bucket}が削除され 1 2 3 4 f u n c m o v e B u c k e t T o H o s t ( u * u r l . U R L , b u c k e t s t r i n g ) { u . H o s t = b u c k e t + " . " + u . H o s t r e m o v e B u c k e t F r o m P a t h ( u ) } 1 2 3 4 5 6 f u n c r e m o v e B u c k e t F r o m P a t h ( u * u r l . U R L ) { u . P a t h = s t r i n g s . R e p l a c e ( u . P a t h , " / { B u c k e t } " , " " , - 1 ) i f u . P a t h = = " " { u . P a t h = " / " } }

Slide 26

Slide 26 text

AWS SDK for Go(v1)におけるパストラバーサ 最後にrestxml.BuildHandlerが実 行され このハンドラの内部処理で呼び出さ れるbuildURI()によって、実際のバ ケット名やオブジェクトキーがテン プレートに埋め込まれ 1 2 3 4 5 6 7 8 9 1 0 1 1 f u n c b u i l d U R I ( u * u r l . U R L , v r e f l e c t . V a l u e , n a m e s t r i n g , t a g r e f l e c t . S t r u c t T a g ) e r r o r { v a l u e , e r r : = c o n v e r t T y p e ( v , t a g ) / / . . . u . P a t h = s t r i n g s . R e p l a c e ( u . P a t h , " { " + n a m e + " } " , v a l u e , - 1 ) u . P a t h = s t r i n g s . R e p l a c e ( u . P a t h , " { " + n a m e + " + } " , v a l u e , - 1 ) u . R a w P a t h = s t r i n g s . R e p l a c e ( u . R a w P a t h , " { " + n a m e + " } " , E s c a p e P a t h ( v a l u e , t r u e ) , - 1 ) u . R a w P a t h = s t r i n g s . R e p l a c e ( u . R a w P a t h , " { " + n a m e + " + } " , E s c a p e P a t h ( v a l u e , f a l s e ) , - 1 ) r e t u r n n i l } パラメータの展開とpath.Cleanによる正規

Slide 27

Slide 27 text

AWS SDK for Go(v1)におけるパストラバーサ パラメータ展開直後にcleanPath()が 呼ばれ cleanPath()の内部で呼ばれている path.Clean()はGoの標準ライブラリ で、パスの正規化を行う。
 そのため、バケット名やオブジェクト キーに含まれる..が解決されてしま う 1 2 3 i f ! a w s . B o o l V a l u e ( r . C o n f i g . D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g ) { c l e a n P a t h ( r . H T T P R e q u e s t . U R L ) } 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 f u n c c l e a n P a t h ( u * u r l . U R L ) { h a s S l a s h : = s t r i n g s . H a s S u f f i x ( u . P a t h , " / " ) / / c l e a n u p p a t h , r e m o v i n g d u p l i c a t e ` / ` u . P a t h = p a t h . C l e a n ( u . P a t h ) u . R a w P a t h = p a t h . C l e a n ( u . R a w P a t h ) i f h a s S l a s h & & ! s t r i n g s . H a s S u f f i x ( u . P a t h , " / " ) { u . P a t h + = " / " u . R a w P a t h + = " / " } } パラ メータの展開とpath.Clean()による正規

Slide 28

Slide 28 text

AWS SDK for Go(v1)におけるパストラバーサ Si gn() –nr.H andl ers .S ign .Ru n(r )k ‹cfD Ëf_ URLkþW fr LL ‘„‰ 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 f u n c ( r * R e q u e s t ) S i g n ( ) e r r o r { r . B u i l d ( ) i f r . E r r o r ! = n i l { d e b u g L o g R e q E r r o r ( r , " B u i l d R e q u e s t " , n o t R e t r y i n g , r . E r r o r ) r e t u r n r . E r r o r } S a n i t i z e H o s t F o r H e a d e r ( r . H T T P R e q u e s t ) r . H a n d l e r s . S i g n . R u n ( r ) r e t u r n r . E r r o r } URLに対する署

Slide 29

Slide 29 text

AWS SDK for Go(v1)におけるパストラバーサ ѹÈéÐü µëLz˜ Y‰wS‰ パス形式(同一バケット内のパストラバーサル ¹ÆÃ× Ñ¹n ¶K end poi ntHandl er „ /{ Buc ket} /{K ey+ } b u i l d U R I „ (  B u c k e t = m y - f l a t t - b u c k e t , K e y = f o o / . . / b a r /my- flatt-b ucket/fo o/../ bar path .Cl ean „ /my -fla tt-b ucke t/bar Ð ± Ã È – n × ì Õ £ à ¯ ¹ g Æ Ê ó È  â ™ W f D ‰ 4  k  Ö Æ Ê ó È n ª Ö ¸ § ¯ È n Í \ L ï ý

Slide 30

Slide 30 text

AWS SDK for Go(v1)におけるパストラバーサ ѹÈéÐü µëLz˜ Y‰wS‰ パス形式(バケット間のパストラバーサル r Ø M U R L n \  k ) ( W _ Ý ê · ü k   p Ð ± Ã È ™ Í \ Y ‰ ) P L B c _ 4  k Ð ± Ã È ™ * W f  . Í \ Y ‰ S h ï ý  ! ¹ é ¤ É ¹ÆÃ× Ñ¹n ¶K en dpoi ntHandl er „ /{ Buc ket} /{K ey+ } b u i l d U R I „ (  B u c k e t = m y - f l a t t - b u c k e t , K e y = t e s t . t x t / . . / . . / o t h e r - f l a t t - b u c k e t / s e c r e t . t x t / m y - f l a t t - b u c k e t / t e s t . t x t / . . / . . / o t h e r - f l a t t - b u c k e t / s e c r e t . t x t path .Cl ean „ /o the r-fl att -bu cke t/s ecr et. txt

Slide 31

Slide 31 text

AWS SDK for Go(v1)におけるパストラバーサ 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 { " V e r s i o n " : " 2 0 1 2 - 1 0 - 1 7 " , " S t a t e m e n t " : [ { " S i d " : " A l l o w D o w n l o a d A n d U p l o a d F r o m M u l t i p l e B u c k e t s " , " E f f e c t " : " A l l o w " , " A c t i o n " : [ " s 3 : G e t O b j e c t " , " s 3 : P u t O b j e c t " ] , " R e s o u r c e " : [ " a r n : a w s : s 3 : : : m y - f l a t t - b u c k e t / * " , " a r n : a w s : s 3 : : : o t h e r - f l a t t - b u c k e t / * " ] } ] } бà È*LïýjIAM Ýê ·ün ‰

Slide 32

Slide 32 text

AWS SDK for Go(v1)におけるパストラバーサ ѹÈéÐü µëLz˜ Y‰wS‰ 仮想ホスト形式(同一バケット内のパストラバーサル ¹ÆÃ× Ñ¹n ¶K end poi ntHandl er „ /{K ey+} b u i l d U R I „ (  B u c k e t = m y - f l a t t - b u c k e t , K e y = f o o / . . / b a r /foo/../bar path .Cl ean „ /b ar Ð ± Ã È – n × ì Õ £ à ¯ ¹ g Æ Ê ó È  â ™ W f D ‰ 4  k  Ö Æ Ê ó È n ª Ö ¸ § ¯ È n Í \ L ï ý

Slide 33

Slide 33 text

AWS SDK for Go(v1)におけるパストラバーサ AWS n »å êÆ£Á üàhn —−h − Ç Õ © ë È g Ñ ¹ n c ‘  L L ‘ „ ‰ ˇ Õ k š X W f D ‰ g ¢ L J −  „ ¹ ™ Û ' ™  Y ‰ _ † k Ê „ ‡ S n ˇ Õ ™ 

Slide 34

Slide 34 text

AWS SDK for Go(v1)におけるパストラバーサ þV 1 2 3 4 5 6 / / W i t h D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g s e t s a c o n f i g D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g v a l u e / / r e t u r n i n g a C o n f i g p o i n t e r f o r c h a i n i n g . f u n c ( c * C o n f i g ) W i t h D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g ( t b o o l ) * C o n f i g { c . D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g = & t r e t u r n c } - ı $ g B ‰ D i s a b l e R e s t P r o t o c o l U R I C l e a n i n g ™ ¹ k Y ‰ S h g  p a t h . C l e a n ( ) k ‹ ‰  ó W j D c ‘  ™ 2 P S h L g M ‰

Slide 35

Slide 35 text

AWS SDK for JavaScript v3におけるパストラバーサ 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 l e t b a s e U r l : s t r i n g | u n d e f i n e d ; i f ( u r l ) { b a s e U r l = u r l ; } e l s e i f ( p o l i c y ) { c o n s t r e s o u r c e s = g e t P o l i c y R e s o u r c e s ( p o l i c y ! ) ; i f ( ! r e s o u r c e s [ 0 ] ) { t h r o w n e w E r r o r ( " @ a w s - s d k / c l o u d f r o n t - s i g n e r : N o U R L p r o v i d e d a n d u n a b l e t o d e t e r m i n e U R L f r o m f i r s t p o l i c y s t a t e m e n t r e s o u r c e . " ) ; } b a s e U r l = r e s o u r c e s [ 0 ] . r e p l a c e ( " * : / / " , " h t t p s : / / " ) ; } JavaScript v3では、@aws-sdk/cloudfront-signerパッケージによるCloudFrontの署名付き URLの発行においてパストラバーサルの脆弱性が発生す baseUrlの決 g etSignedUrl()を呼び出す時に指定する引数に依存 url : urlの値そのまま policy : Resourceに指定されたUR

Slide 36

Slide 36 text

AWS SDK for JavaScript v3におけるパストラバーサ 1 2 3 4 5 6 c o n s t n e w U R L = n e w U R L ( b a s e U r l ! ) ; n e w U R L . s e a r c h = A r r a y . f r o m ( n e w U R L . s e a r c h P a r a m s . e n t r i e s ( ) ) . c o n c a t ( O b j e c t . e n t r i e s ( c l o u d f r o n t S i g n B u i l d e r . c r e a t e C l o u d f r o n t A t t r i b u t e ( ) ) ) . f i l t e r ( ( [ , v a l u e ] ) = > v a l u e ! = = u n d e f i n e d ) . m a p ( ( [ k e y , v a l u e ] ) = > ` $ { e n c o d e U R I C o m p o n e n t ( k e y ) } = $ { e n c o d e U R I C o m p o n e n t ( v a l u e ) } ` ) . j o i n ( " & " ) ; URLの正規化とパラメータの展 new URL()の URLコンストラクタを用いてURLオブジェクトを生 baseUrlの既存のパラメータに加え、署名パラメータを追

Slide 37

Slide 37 text

AWS SDK for JavaScript v3におけるパストラバーサ ѹÈéÐü µëLz˜ Y‰wS‰ Ð ± Ã È – n “ ï 6 ¡ L i  k - ı U „ f D j D 4  k Ð ± Ã È – n û  ª Ö ¸ § ¯ È x ¢ ¯ » ¹ Y ‰ S h L ï ý ¹ÆÃ× UR Ln¶ K g e t S i g n e d U r l | s ú W B (  u r l = h t t p s : / / f l a t t - d i s t r i b u t i o n . c l o u d f r o n t . n e t / f o o / . . / b a r h t t p s : / / f l a t t - d i s t r i b u t i o n . c l o u d f r o n t . n e t / f o o / . . / b a r new URL „ h t t p s : / / f l a t t - d i s t r i b u t i o n . c l o u d f r o n t . n e t / b a r

Slide 38

Slide 38 text

AWS SDK for Go(v1)におけるパストラバーサ AWS n »å êÆ£Á üàhn —−h − ‰ztn¬ û˘ßk^ Y‰ ‰ gB‰ Sh K› c j 1'h Wfn“ı U„jD I w o u l d l i k e t o i n f o r m y o u t h a t o u r C N A t e a m h a s e v a l u a t e d y o u r r e p o r t e d i s s u e f o r a C V E / G H S A a s s i g n m e n t a n d d e t e r m i n e d t h a t t h i s d o e s n o t q u a l i f y f o r a C V E u n d e r o u r p r o g r a m [ 1 ] a s t h i s i s s u e r e q u i r e s o v e r l y p e r m i s s i v e S 3 b u c k e t p o l i c i e s t o b e a p p l i e d . T h e c o n f i g u r a t i o n o f t h e s e p o l i c i e s f a l l u n d e r t h e c u s t o m e r s i d e o f t h e A W S S h a r e d R e s p o n s i b i l i t y M o d e l [ 2 ] .  C V E / G H S A r − S f n _ † k 1 J U „ _ O L ™ U ¡ W _ P œ  S n O L o C V E n þ a  g B ‰ h $ W ~ W _  S n O L o S 3 Ð ± Ã È Ý ê · ü h W f N p j ) P L i ( U „ f D ‰ Å † L B −  S „ › n Ý ê · ü n - ı o A W S S h a r e d R e s p o n s i b i l i t y M o d e l k J Q ‰ g ¢ t n ¬ û Ä ò k r S W ~ Y 

Slide 39

Slide 39 text

AWS SDK for JavaScript v3におけるパストラバーサ þV v 3 . 8 5 8 . 0 å M n Ð ü ¸ ç ó x h Ñ Ã ± ü ¸ ™ ¢ Ã × Ç ü È Y ‰ S h g Ñ ¹ È é Ð ü µ ë n z ˜ ™ Þ g M ‰

Slide 40

Slide 40 text

アプリケーション開発者が誤って正規化してしまうパター S D K t g þ V L U „ f D f ‡  ¢ × ê ± ü · ç ó ‰ z  L ¤ c f c ‘  W f W ~ F h Ñ ¹ È é Ð ü µ ë L w M f W ~ F 明示的に正規化 path.normalize (JavaScript) os.path.normpath (Python) java.nio.file.Path.normalize (Java パスの結合時に正規化 path.join (JavaScript) path.Join , filepath.Join (Go URL構築時に正規化 new URL (JavaScript) java.net.URI.resolve (Java) url.URL.ResolveReference (Go

Slide 41

Slide 41 text

アプリケーション開発者が誤って正規化してしまうパター :—kc‘™Y‰Ñ ¿üó path.normalize (JavaScript) os.path.normpath (Python) java.nio.file.Path.normalize (Java 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 c o n s t p a t h = r e q u i r e ( " p a t h " ) ; c o n s t { S 3 C l i e n t , G e t O b j e c t C o m m a n d } = r e q u i r e ( " @ a w s - s d k / c l i e n t - s 3 " ) ; c o n s t { g e t S i g n e d U r l } = r e q u i r e ( " @ a w s - s d k / s 3 - r e q u e s t - p r e s i g n e r " ) ; c o n s t s 3 C l i e n t = n e w S 3 C l i e n t ( { r e g i o n : " a p - n o r t h e a s t - 1 " } ) ; a s y n c f u n c t i o n g e n e r a t e P r e s i g n e d U r l W i t h N o r m a l i z e ( t e n a n t I d , u s e r I n p u t P a t h ) { / / t e n a n t I d : " m y - t e n a n t " / / u s e r I n p u t P a t h  ; …  n e ł : " . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " c o n s t r a w P a t h = ` t e n a n t s / $ { t e n a n t I d } / f i l e s / $ { u s e r I n p u t P a t h } ` ; / / c ‘  M : " t e n a n t s / m y - t e n a n t / f i l e s / . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " / / c ‘  „ : " t e n a n t s / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " c o n s t o b j e c t K e y = p a t h . n o r m a l i z e ( r a w P a t h ) ; c o n s t c o m m a n d = n e w G e t O b j e c t C o m m a n d ( { B u c k e t : p r o c e s s . e n v . B U C K E T _ N A M E , K e y : o b j e c t K e y , } ) ; r e t u r n a w a i t g e t S i g n e d U r l ( s 3 C l i e n t , c o m m a n d , { e x p i r e s I n : 3 6 0 0 } ) ; }

Slide 42

Slide 42 text

アプリケーション開発者が誤って正規化してしまうパター ѹ nPB kc ‘™Y‰ Ñ ¿ üó path.join (JavaScript) path.Join , filepath.Join (Go 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 c o n s t p a t h = r e q u i r e ( " p a t h " ) ; c o n s t { S 3 C l i e n t , G e t O b j e c t C o m m a n d } = r e q u i r e ( " @ a w s - s d k / c l i e n t - s 3 " ) ; c o n s t { g e t S i g n e d U r l } = r e q u i r e ( " @ a w s - s d k / s 3 - r e q u e s t - p r e s i g n e r " ) ; c o n s t s 3 C l i e n t = n e w S 3 C l i e n t ( { r e g i o n : " a p - n o r t h e a s t - 1 " } ) ; a s y n c f u n c t i o n g e n e r a t e P r e s i g n e d U r l W i t h P a t h J o i n ( t e n a n t I d , u s e r I n p u t F i l e n a m e ) { / / t e n a n t I d : " m y - t e n a n t " / / u s e r I n p u t F i l e n a m e  ; …  n e ł : " . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " / / c ‘  M : " t e n a n t s / m y - t e n a n t / f i l e s / . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " / / c ‘  „ : " t e n a n t s / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " c o n s t o b j e c t K e y = p a t h . j o i n ( " t e n a n t s " , t e n a n t I d , " f i l e s " , u s e r I n p u t F i l e n a m e ) ; c o n s t c o m m a n d = n e w G e t O b j e c t C o m m a n d ( { B u c k e t : p r o c e s s . e n v . B U C K E T _ N A M E , K e y : o b j e c t K e y , } ) ; r e t u r n a w a i t g e t S i g n e d U r l ( s 3 C l i e n t , c o m m a n d , { e x p i r e s I n : 3 6 0 0 } ) ; }

Slide 43

Slide 43 text

アプリケーション開発者が誤って正規化してしまうパター UR LË ÉBk c ‘™ Y‰Ñ¿üó new URL (JavaScript) java.net.URI.resolve (Java) url.URL.ResolveReference (Go 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 c o n s t { g e t S i g n e d U r l } = r e q u i r e ( " @ a w s - s d k / c l o u d f r o n t - s i g n e r " ) ; f u n c t i o n g e n e r a t e C l o u d F r o n t S i g n e d U r l ( u s e r I n p u t P a t h ) { / / u s e r I n p u t P a t h  ; …  n e ł : " . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " c o n s t r a w U r l = " h t t p s : / / d 1 1 1 1 1 1 a b c d e f 8 . c l o u d f r o n t . n e t / t e n a n t s / m y - t e n a n t / f i l e s / " + u s e r I n p u t P a t h ; / / c ‘  M : " h t t p s : / / d 1 1 1 1 1 1 a b c d e f 8 . c l o u d f r o n t . n e t / t e n a n t s / m y - t e n a n t / f i l e s / . . / . . / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " / / c ‘  „ : " h t t p s : / / d 1 1 1 1 1 1 a b c d e f 8 . c l o u d f r o n t . n e t / t e n a n t s / o t h e r - t e n a n t / f i l e s / s e c r e t . t x t " c o n s t u r l = n e w U R L ( r a w U r l ) ; r e t u r n g e t S i g n e d U r l ( { u r l : u r l . t o S t r i n g ( ) , k e y P a i r I d : " d u m m y K e y P a i r I d " , p r i v a t e K e y : d u m m y P r i v a t e K e y , d a t e L e s s T h a n : n e w D a t e ( D a t e . n o w ( ) + 3 6 0 0 * 1 0 0 0 ) . t o I S O S t r i n g ( ) , } ) ; }

Slide 44

Slide 44 text

~h† 2つのAWS SDKでパストラバーサルが見つかった 特にパス形式でURLが発行されると、バケット横断ができる可能性があ SDK側で適切な対策がされていても、アプリケーション開発者の実装ミスによっては
 脆弱性を生む可能性があ 署名付きURLを生成する過程で、SDK内部やアプリケーションコード内で正規化が行わ れ、意図しないバケットやオブジェクトの署名付きURLが発行されてしまうことで署名付 きURLにおけるパストラバーサル脆弱性が発生す 署名付きURLを生成する過程でパスの正規化をしない バケットの操作に対して、適切な権限設定をする(IAM Policy・バケットポリシー) バケット名を確認し、可能な限り署名付きURLでは仮想ホスト形式を使

Slide 45

Slide 45 text

B− LhFT V D~W _< J A W S D A Y S 2 0 2 6 × í Õ § Ã · ç Ê ë µ ü Ó ¹ è ~ Ł | *  @ r y o t a r o m o s a o  Á ç ó ¦ £ Á ç ë