Saat sebuah tugas dibuat di Newton, dua pihak harus menyetujui sebelum Gateway melanjutkan: pengguna, dan aplikasi yang bertindak atas nama mereka. Dokumentasi menjelaskannya sebagai sebuah rantai — tanda tangan aplikasi diharapkan memiliki makna spesifik: "kami melihat persetujuan pengguna, kami memverifikasinya, dan hanya setelah itu kami menambahkan persetujuan kami sendiri." Saya ingin melihat apakah konstruksi sebenarnya dari tanda tangan kedua itu benar-benar memastikan urutan tersebut, atau hanya sekadar menegaskan bahwa itu terjadi.

 

Ini yang dijelaskan. Kedua tanda tangan memverifikasi terhadap pesan dasar yang sama — sebuah ringkasan (digest) yang dibangun dari policy client dan intent hash, dengan referensi data dilipat ke dalamnya. Pengguna menandatanganinya. Aplikasi juga menandatanganinya. Gateway menerima tugas setelah kedua tanda tangan itu sesuai dengan kunci publik masing-masing. Dan tujuan yang dinyatakan dari tanda tangan aplikasi adalah untuk membuktikan bahwa aplikasi tersebut menerima dan memverifikasi persetujuan pengguna sebelum menambahkan persetujuannya sendiri.

 

Itu merupakan klaim yang berarti jika benar, karena itulah yang mencegah aplikasi yang nakal atau ceroboh mengotorisasi akses data atas nama pengguna tanpa pengguna tersebut benar-benar menyetujui. Aplikasi ini tidak sekadar mengatakan "Saya menyetujui intent ini." Ia mengatakan "Saya mengonfirmasi bahwa orang nyata menyetujui intent ini, dan inilah tanda tangan saya sebagai bukti bahwa saya memeriksanya."

 

Tapi lihat apa yang sebenarnya ditandatangani oleh aplikasi. Yang ditandatangani adalah digest yang sama yang ditandatangani pengguna — bukan digest yang memasukkan bytes tanda tangan pengguna sebagai salah satu input-nya. Jika pesan penandatanganan aplikasi dibangun dengan meng-hash bytes tanda tangan aktual pengguna, maka menghasilkan tanda tangan aplikasi yang valid akan secara kriptografis mustahil tanpa terlebih dahulu memiliki tanda tangan pengguna yang nyata — keduanya akan saling dirangkai sejak konstruksi, dan klaim "diverifikasi sebelum menyetujui" akan dipaksakan oleh matematikanya sendiri, bukan hanya oleh siapa pun yang mengoperasikan aplikasi tersebut secara jujur. Namun, itu bukan yang dideskripsikan.

Aplikasi menandatangani kombinasi intent dan referensi data secara langsung, terlepas dari apa pun yang dilakukan pengguna atau tidak ditandatanganinya.

 

Artinya, sejauh yang bisa saya simpulkan dari dokumentasi, sebuah aplikasi bisa menghitung digest yang sama sendiri — ia sudah mengetahui client kebijakannya, dan ia lah yang pertama kali menyusun intent serta referensi data — lalu menghasilkan ko-tanda tangan yang valid tanpa tanda tangan pengguna pernah sampai padanya. Pemeriksaan Gateway adalah "apakah kedua tanda tangan valid secara independen atas pesan ini," bukan "apakah tanda tangan aplikasi bergantung pada tanda tangan pengguna." Dua persetujuan yang diproduksi secara independen terhadap pernyataan yang sama, bagi verifikator, tampak identik dengan satu persetujuan yang memang secara nyata dikondisikan oleh persetujuan lainnya.

 

Saya ingin berhati-hati tentang apa yang dilakukan dan tidak berarti. Ini tidak berarti persetujuan pengguna bisa dipalsukan — tanda tangan pengguna sendiri tetap harus ada dan dapat diverifikasi dengan sendirinya, dan tidak ada di sini yang memungkinkan penyerang memalsukannya. Yang dimaksud lebih sempit dan spesifik: jaminan pengurutan — klaim bahwa tanda tangan aplikasi secara khusus mewakili "saya memeriksa tanda tangan pengguna terlebih dahulu" — tidak tampak sebagai sesuatu yang dipaksakan oleh kriptografi. Ini lebih dekat pada ekspektasi operasional yang ditetapkan pada perilaku aplikasi yang jujur, bukan sifat yang dijamin secara matematis oleh skema tanda tangan ganda.

Sebuah aplikasi yang menandatangani lebih dulu, atau menandatangani tanpa sama sekali menerima tanda tangan pengguna, dan hanya kebetulan bahwa pengguna kemudian menandatangani digest yang sama melalui kanal lain, akan menghasilkan sebuah tugas yang terlihat, di-chain, identik dengan tugas yang urutannya terjadi persis seperti yang dimaksudkan.

 

Apakah celah itu penting sepenuhnya bergantung pada apa yang bisa dilakukan oleh aplikasi yang sudah dikompromikan atau ceroboh dengannya. Jika model risiko praktisnya hanya "seseorang bisa memalsukan sebuah tugas tanpa adanya persetujuan pengguna yang nyata sama sekali," maka ini tidak membuka apa pun yang baru — kedua tanda tangan nyata tetap harus ada. Tapi jika bagian dari skema ini dimaksudkan untuk menangkap adalah skenario ketika sebuah aplikasi memberi stempel karet pada niat tanpa benar-benar memeriksa siapa yang berada di baliknya — suatu mode kegagalan yang berbeda dari pemalsuan terang-terangan — maka konstruksi digest sebagaimana didokumentasikan tidak tampak menutup celah itu.

 

Jadi pertanyaan terbukanya tepat: apakah ada sesuatu di luar pesan penandatanganan spesifik ini — log peristiwa on-chain yang terpisah, persyaratan audit off-chain, pemeriksaan pengurutan dari sisi Gateway saat setiap tanda tangan tiba — yang benar-benar menegakkan urutan "diverifikasi terlebih dahulu sebelum menyetujui" yang dijelaskan dokumentasinya?

Atau apakah pengurutan itu merupakan kebijakan yang dipercaya untuk diikuti oleh aplikasi, di atas skema kriptografis yang dengan sendirinya tidak bisa membedakan antara aplikasi yang memeriksa dan aplikasi yang tidak memeriksa?

 @NewtonProtocol #Newt $NEWT $T $CLO