Lompat ke konten
Raizel/atelier
← Semua catatan
Security engineering3 menit baca

Data placeholder berhenti tidak berbahaya begitu ia terbit

Dua URL placeholder di file data situs ini diam-diam berubah menjadi pernyataan identitas yang dikirim ke mesin pencari. Tidak ada yang error, dan typecheck lolos — masalahnya baru terlihat saat membaca output JSON-LD.

  • Structured data
  • Schema.org
  • RFC 9116
  • Code review

Ketika portofolio ini masih kerangka, saya isi daftar sosial dengan nilai sementara: https://github.com/ dan https://www.linkedin.com/. Keduanya URL sah, bisa diklik, dan terlihat benar di footer — hanya belum menunjuk ke profil siapa pun. Kebiasaan yang wajar, dan tidak berbahaya selama nilainya hanya dipakai sebagai href.

Lalu halaman utama mendapat structured data Schema.org, dan node Person punya properti sameAs. Properti itu bukan tautan; ia pernyataan. Isinya berarti 'entitas ini adalah entitas yang sama dengan yang berada di URL berikut' — dan itu salah satu sinyal yang dipakai mesin pencari untuk merekonsiliasi identitas antar situs.

Filter yang benar untuk alasan yang salah

Kodenya sudah memfilter, dan filternya masuk akal saat ditulis: daftar sosial juga memuat entri mailto:, dan mailto bukan profil web. Jadi saya buang apa pun yang tidak berawalan http. Yang lolos tepat kedua placeholder itu.

ts
// sebelum — menahan mailto:, meloloskan placeholder
const sameAs = socials
  .map((item) => item.href)
  .filter((href) => href.startsWith("http"));
// ["https://github.com/", "https://www.linkedin.com/"]

// sesudah — URL tanpa segmen path bukan profil, jadi tidak terbit
function isProfileUrl(href: string): boolean {
  if (!href.startsWith("http")) return false;
  try {
    return new URL(href).pathname.replace(/\/+$/, "").length > 0;
  } catch {
    return false;
  }
}

Perhatikan bahwa hasilnya bisa menjadi array kosong, dan array kosong juga tidak boleh dikirim. "sameAs": [] adalah pernyataan bahwa orang ini tidak punya profil lain di mana pun; menghilangkan propertinya berarti belum ada yang dinyatakan. Yang kedua itu yang benar selama datanya belum diisi.

Pola yang sama, satu tingkat lebih serius

Alamat email di file yang sama mengalami hal serupa, dan konsekuensinya lebih besar. Awalnya ia hanya mengisi tombol mailto. Kemudian ia dipakai sebagai field Contact di /.well-known/security.txt — dokumen yang gunanya persis satu: memberi tahu peneliti keamanan ke mana melaporkan kerentanan. Placeholder di tempat itu bukan lagi kosmetik; ia kanal pelaporan yang tidak ada, dipublikasikan sebagai kanal yang ada.

Yang membuat kelas bug ini sulit ditangkap: nilainya tidak pernah salah secara tipe, tidak pernah melempar error, dan tidak pernah terlihat rusak di UI. Yang berubah bukan datanya, tapi jumlah tempat yang membacanya — dan sebagian tempat baru itu punya arti yang berbeda dari tempat asalnya.

  • Placeholder aman selama satu konsumen; berisiko begitu konsumen kedua menafsirkannya sebagai fakta.
  • Ada pembacanya yang bukan manusia — crawler dan peneliti keamanan tidak bisa menebak bahwa sesuatu masih sementara.
  • Filter yang ditulis untuk satu tujuan (buang mailto) tidak otomatis menahan tujuan lain (buang non-profil).
  • Validasi di titik terbit, bukan di titik isi: sumbernya akan selalu sempat berisi nilai sementara.