画像アップロードサービスをセキュアにして運用したいメモ

## 背景

画像をアップロードしてなにか処理して(e.g. 背景を抜いたり, なにかロゴを付加したり)結果を返す web サービスを作りたい.
web3 時代や, GPU 機械学習処理を見据えて自前サーバで実行したい.
(AWS とかで実行は考えない)

とりあえずは CPU で行う.

VPS + nginx を建て, 自身のサーバに proxy(リダイレクト)するとする(VPS 上では動かさない)

サーバプロセスは C/C++ とし, コンテナ(sandbox)実行するものとする.

## 懸念事項

* GB 単位のデータをアップロードされ帯域を食いつぶされたりしないか
  * nginx あたりで帯域制御, 1 ファイルの最大サイズを設定できるのでないか 
* メタ情報などに悪意あるコードを仕込まれてしまわないか => 画像ライブラリでセキュアなもの or 自作を選ぶ
  * Sandboxing in Linux with zero lines of code https://blog.cloudflare.com/sandboxing-in-linux-with-zero-lines-of-code/ では ImageMagick の脆弱性の例を挙げている(そもそも ImageMagick とかを素で使うのが危険ではあるが...) 
* 公序良俗に反する画像などをアップロードされないか
  * とりあえずは NSFW フィルターを通すのがよいか. 

その他, 一般的なところ

「クラウドサービス提供における情報セキュリティ対策ガイドライン（第3版）」（案）に対する意見募集の結果及び「クラウドサービス提供における情報セキュリティ対策ガイドライン（第3版）」の公表
https://www.soumu.go.jp/menu_news/s-news/01cyber01_02000001_00121.html


## 2022/10 時点での方針

wasm で頑張る.

https://bytecodealliance.org/articles/wasmtime-1-0-fast-safe-and-production-ready

wasmtime(WASM ランタイム)が 1.0 になったので, サーバーで WASM 動かすのも安全にできるようになりました :tada: 

## 画像ライブラリ

とりあえずは ImageMagick.wasm https://github.com/dlemstra/magick-wasm つかっとけばよさそう.

libpng, libjpeg あたりは最近のであれば十分 fuzzing などされており大丈夫そうではある(メタ情報に悪意あるコードを埋め込まれリモートコード実行されない). sandboxing 実行すれば万一リモートコード実行されても大丈夫... カナ :thinking: 

ただコンテナ(sandbox 環境)として musl + runc みたいなのを選んだ場合は libpng とかビルドめんどいので, stb_image などを使うことになろう.

https://github.com/nothings/stb/blob/master/stb_image.h

あとは png であれば fpng(サービスが繁盛してきて PNG のデコード/エンコード速度が問題になってきたら)

https://github.com/richgel999/fpng

fpng は, LLVM fuzzer を数日動かした限りでは問題ないかんじであった.

### DNG, Camera RAW 

tinydng で一部の DNG(Apple ProRAW 含む), Camera RAW が扱える.

https://github.com/syoyo/tinydng

LLVM fuzzer test は十分ではない.
 
## 動画のデコード

ffmpeg.wasm がありました!

https://github.com/ffmpegwasm/ffmpeg.wasm

## コンテナ実行

Docker でもいいかもだがなんかあんまり好きくない(動かしていたらいつの間にかディスク領域を大量に消費されていたなどの経験があるため).

2015 年時点の情報.

runC で aobench を動かす
https://qiita.com/syoyo/items/c8ef01113e972ceb7647

最近(2022 年)はどうじゃろ.


コンテナランタイム事情を整理してみる
https://qiita.com/cfg17771855/items/0c0f5df26ffcfe18a74d

ありがとうございます.

## WASM 実行

wasmtime 1.0 になったりで WASM ランタイムも成熟してきたので, 最近(2022/10)だと WASM(32bit)実行がよいでしょう.
コンテナ化すればよりセキュアに!

## C/C++ プログラムの作成

C/C++ でイチから書いて, システムコール使わないとか, あまり libc(glibc) や C++ STL(gnustl, libcxx) に依存しない C/C++ アプリを書くのもやりたいね.

STL については NanoSTL をちょこちょこ書いています.

https://github.com/lighttransport/nanostl

sandbox 環境用などの libc 置き換え Nanolibc はまったくできていない

https://github.com/lighttransport/nanolibc

(LLVM libc はどうなったかな?)

## NSFW 判定


https://github.com/yahoo/open_nsfw

NudeNet
https://praneethbedapudi.medium.com/nudenet-an-ensemble-of-neural-nets-for-nudity-detection-and-censoring-d9f3da721e3

https://github.com/infinitered/nsfwjs

最近(2022/10)だと nfswjs がいいんじゃろか(ブラウザでも, サーバ側でもうごかせる)

推論には時間かかるが, LAION + CLIP データセットで学習した NSFW フィルターありました!


https://github.com/LAION-AI/LAION-SAFETY

https://github.com/LAION-AI/CLIP-based-NSFW-Detector
(model 1 GB :sweat_smile: )

クライアントで動かすには難しそうなので, サーバ側で処理ですかね.

### 判定サービス

https://cloud.google.com/vision/docs/detecting-safe-search?hl=ja 

月 500 万枚までなら, 1000 枚ごとに $1.5. 1 枚あたり 0.2 円. 
ご予算や負荷に応じて...(↑の LAION の Detector 動かすには負荷多いときとか)

## TODO

* [ ] GPU のコンテナからのセキュアなアクセス方法(and GPU プロセスの sandbox)を調べる
  * Docker GPU のセキュリティはどうなったのかしらん