先日 Pwned Together: Hacking dev.to という記事を見かけた。
dev.to ではブログ投稿機能において {% gist <gist url> %} という記法を使用することでいい感じに gist を挿入してくれるらしい。

html = <<~HTML
  <div class="ltag_gist-liquid-tag">
      <script id="gist-ltag" src="#{@link}.js"></script>
  </div>
HTML

上記記事ではドメインの正規表現不備を利用して gist.github.com 以外のドメインから読み込む XSS を紹介していた。
この修正後のコミットを見ると、イベントハンドラが削除できていないのでまだXSS可能であることがわかる。

{% gist https://gist.github.com/mrtc0/bfbdd3757a18c7a85542c4948139fbb8 "onload=alert(document.domain) %}

alert

これを報告したのだけど、修正コミット を見ると不十分感…
この正規表現だと「 https://gist.github.com/<username>/<hash> に一致する行がある場合にマッチする」という意味になる。

そのため途中に \n を挿入してやると True になる。

[1] pry(main)> link = "https://gist.github.com/mrtc0/bfbdd3757a18c7a85542c4948139fbb8 \n\"onload=alert(document.domain)"
=> "https://gist.github.com/mrtc0/bfbdd3757a18c7a85542c4948139fbb8 \n\"onload=alert(document.domain)"
[1] pry(main)> (link =~ /^https\:\/\/gist\.github\.com\/([a-zA-Z0-9\-]){1,39}\/([a-zA-Z0-9]){32}\s$/)&.zero?
=> true

ただしこの場合、\n の前に %20 が入っているため gist をいい感じに表示する JS の中で fetch エラーになってタグ自体がHTMLに反映されずXSSできない。
ウーンと悩んでいたけどパッと解法が思い浮かばなかったので、「 \Z の方が良いんじゃない?」みたいなメールを送ったら修正された。

https://github.com/thepracticaldev/dev.to/blob/master/app/liquid_tags/gist_tag.rb#L41

ところで、dev.to には脆弱性報奨金 があって以下のような記述がある。

  • Low risk vulnerabilities will be rewarded with $50 USD.
  • Medium risk vulnerabilities will be rewarded with $100 USD.
  • High risk vulnerabilities will be rewarded with $150 USD.

今回は Stored XSS となるし https://dev.to/antogarand/pwned-together-hacking-devto-hkd でも $150 もらってるので、自分もてっきり貰えるのかと思っていたら全く反応がない…

それどころか「修正したよ!」みたいなメールもなくてこっそり修正されていて悲しい…

速攻で修正されたから良いのだけど、こういう雑な対応やられるけどバグハンター側としてもモチベーションなくなるのでやめてほしい。
「報告して修正されたけど報奨金もらえていないんだ… 😢」みたいなマイルドな感じでこの記事を dev.to にも書こうか悩んでいる。

09/26 追記 $150 もらえました!!!! Thank you dev.to !