Series · 3 partsBrowser-to-Native Trust BoundariesPart 2 · You are here
- 1Extension Sandbox'taydı. Native Host Değildi.
- 2Sayfanın İzni Yoktu. Extension'ın Vardı.You are here
- 3Paket İmzalıydı. Güncelleme Yine de Bir Güvenlik Kararıydı.
60 saniyede güven sınırı
Bir web sayfasının extension yetkisini ödünç alması için extension API’lerine doğrudan erişmesi gerekmez. Nihai alıcının erişilebilirliği authorization sanacağı bir mesaj yolu yeterlidir.
Yaygın zincir zararsız görünür:
web sayfası
→ window.postMessage veya ortak DOM
→ isolated content script
→ runtime.sendMessage
→ extension service worker
→ yetkili browser API'si veya cross-origin request
Chrome, content script’leri sayfanın JavaScript ortamından izole olarak tanımlar. Bu özellik
değişkenleri ve execution state’i korur; DOM’dan, MessageEvent.data içinden veya sayfa kontrollü
bir attribute’tan okunan veriyi güvenilir yapmaz. Chrome’un mesajlaşma güvenliği rehberi nettir:
content script’ler service worker’dan daha az güvenilirdir, mesajları saldırgan tarafından
hazırlanmış olabilir ve onların tetikleyebildiği yetkili işlemler dar tutulmalıdır.
İkinci ve farklı bir rota da vardır. Bir extension externally_connectable tanımlayarak eşleşen
web sayfalarının doğrudan runtime.sendMessage() veya runtime.connect() çağırmasına izin
verebilir. Bu çağrılar onMessageExternal ya da onConnectExternal listener’ına ulaşır. Manifest
eşleşmesi bir giriş kuralıdır; operasyon seviyesinde authorization değildir.
Dolayısıyla araştırma sorusu şudur:
Sayfa kontrollü bir principal, service worker’ın sayfanın tek başına kullanamayacağı bir capability’yi yeni ve spesifik bir authorization kararı olmadan çalıştırmasını sağlayabiliyor mu?
Bu write-up, hipotezi sentetik bir lab ortamında kanıtlamak veya reddetmek için kontrollü bir yöntem kurar. Production target, gerçek hesap verisi veya yıkıcı etki gerektirmez.
Üç principal, iki mesaj yolu, tek deputy
Sayfa, content script ve service worker tek bir ürün akışına ait olsa bile ayrı principal’lardır. Yetkileri farklıdır:
| Principal | Browser’ın uyguladığı özellikler | Saldırganın etkileyebildiği özellikler | Tipik yetki |
|---|---|---|---|
| Web sayfası | Origin, frame ve document lifecycle | Page JavaScript, DOM, attribute, event ve uygulama state’i | Same-origin web capability’leri |
| Isolated content script | Extension kimliği ve izole JavaScript global’i | Sayfadan veya page messaging channel’dan alınan hemen her değer | Sınırlı extension API ve runtime message |
| Extension service worker | Extension origin’i, paket kodu ve yetkili API erişimi | Message body; bazen eski veya eksik workflow state’i | Host permission, tabs, storage ve downloads |
Service worker bir deputy’dir: kullanıcıya yönelik bir özellik adına yetki taşır. Daha düşük güven seviyesindeki principal operasyonu veya kaynağı seçerken deputy permission sağlıyorsa confused deputy haline gelir.
Platform kontrolleri gerçekte neyi garanti eder?
Security review sırasında platform kontrollerine çoğu zaman sağlayabileceklerinden daha geniş anlam yüklenir.
| Kontrol | Neyi kanıtlar | Neyi kanıtlamaz |
|---|---|---|
| Content-script isolated world | Page script content script’in JavaScript global’ini doğrudan okuyamaz | Ortak DOM veya explicit message üzerinden alınan veri güvenilirdir |
content_scripts.matches | Script’in hangi sayfalara inject edilebileceğini | O origin’deki her path, frame ve tenant tüm özellikleri kullanabilir |
all_frames: false | Declarative injection varsayılan olarak top frame’e yapılır | Top-frame mesajı halen onaylı olan document’ı tanımlar |
externally_connectable.matches | Hangi web page URL pattern’larının external channel açabileceğini | Caller açık olan her operasyonu çağırabilir |
runtime.onMessage | Mesaj internal extension messaging rotasından geldi | Page-derived payload veya talep edilen object yetkilidir |
runtime.onMessageExternal | Caller external extension messaging rotasını kullandı | Sender origin tek başına yeterli authorization’dır |
MessageSender | Listener’ın kullanabileceği browser-observed sender context’i | Payload içindeki aynı alanlar doğrudur veya istenen etki güvenlidir |
| Host permission | Extension context uzak bir origin’e erişebilir | Content script worker’a istediği URL’yi fetch ettirebilir |
| Kullanıcı kurulumu | Kullanıcı extension paketini ve permission prompt’u kabul etti | Gelecekteki her page action yeni bir kullanıcı kararıdır |
Chrome’un externally_connectable dokümantasyonu kritik bir scope farkını açıklar: matches
ayarı doğrudan bağlanan web sayfalarını kontrol eder ve content script’leri etkilemez. Bu
nedenle geniş bir content-script match ile birleşen window.postMessage relay,
externally_connectable olmasa bile dışarıdan erişilebilen ayrı bir yüzeydir.
Zafiyet kalıbı: authority injection
Tehlikeli message schema genellikle intent yerine authority taşır:
{
"action": "fetch",
"url": "https://internal-api.example/admin/export",
"method": "POST",
"headers": { "X-Workspace": "another-tenant" },
"body": "..."
}
Caller URL, method, header, tenant ve body’yi seçer. Service worker ise host permission, extension
cookie’leri veya authenticated network position sağlar. Handler yalnızca
action === "fetch" kontrolü yapsa bile destination ya da object’i yetkilendirmiş olmaz.
Capability odaklı schema bu sahipliği tersine çevirir:
{
"version": 1,
"operation": "read-current-project-summary",
"projectId": "project-17",
"requestId": "7de0d4c1-...",
"approvalId": "gesture-8b2f"
}
Extension sabit HTTPS endpoint’i, sabit method’u, izinli response alanlarını, mevcut tenant’ı ve seçili project’i güvenilir state’ten çözer. Caller bir network primitive değil, sınırlandırılmış identifier sağlar.
Tekrarlayan confused-deputy varyantları şunlardır:
| Varyant | Kaybedilen sınır | Gözlenebilir sonuç |
|---|---|---|
| Arbitrary cross-origin fetch | Sayfa URL’yi seçer; worker host permission sağlar | Sayfanın erişemediği kaynağı okumak veya değiştirmek |
| Tab authority borrowing | Sayfa tab ID veya navigation target seçer; worker tabs sağlar | Cross-tab disclosure, capture, script injection veya navigation |
| Storage oracle | Sayfa key veya namespace seçer; worker extension storage sağlar | Extension state disclosure veya corruption |
| Download deputy | Sayfa URL, filename veya open davranışı seçer; worker downloads sağlar | İstenmeyen dosya ya da yanıltıcı yerel artifact |
| External-message overreach | İzinli origin dispatcher içindeki her action’ı seçebilir | Onaylı entegrasyon ilgisiz capability’leri devralır |
| Port lifecycle confusion | Long-lived port document/account değişiminden sonra trusted kalır | Eski authorization yeni page state’e uygulanır |
| Response overexposure | Worker raw API output’u daha az güvenilen content script’e döndürür | Secret’lar page-reachable context’e sızar |
Zafiyet yalnızca “sayfa mesaj gönderebiliyor” değildir. Sayfanın tek başına yapabildiğiyle deputy’ye yaptırabildiği arasındaki kanıtlanmış farktır.
İki ingress rotası birleştirilmemeli
Internal listener ve external listener farklı sender toplulukları alır. Bunları alias haline getirmek browser’ın sağladığı değerli context’i yok eder.
// Tehlikeli: iki sender topluluğu aynı permissive dispatcher'a ulaşır.
const dispatch = (request, sender) => perform(request.action, request.args);
chrome.runtime.onMessage.addListener(dispatch);
chrome.runtime.onMessageExternal.addListener(dispatch);
Bir content script’ten gelen internal mesaj için service worker browser tarafından sağlanan
sender.id, sender.url, sender.origin, sender.tab, sender.frameId ve mevcut olduğunda
sender.documentId alanlarını değerlendirebilir. External web-page mesajında sender.url veya
sender.origin bağlanan sayfayı tanımlar; fakat sayfa ile listener arasında content script yoktur.
Başka bir extension için sender.id merkezi önemdedir. Politikanın ihtiyaç duyduğu alan eksikse
sistem fail-closed davranmalıdır.
Message body içine kopyalanmış origin, tab ID, frame ID, extension ID veya document ID kabul
etmeyin. Bunlar caller’ın iddiasıdır. Politika browser’ın out-of-band sağladığı sender nesnesini
kullanmalı; URL’leri suffix ya da substring ile değil URL parser ile normalize etmelidir.
Kontrollü sentetik lab
Lab’ı zararsız etkiler etrafında kurun:
- tek service worker ve tek content script içeren unpacked Manifest V3 extension;
- biri izinli, biri negative-control olan iki loopback veya rezerv test origin’i;
- sabit namespace kullanan
window.postMessagepage bridge; - yalnızca izinli test origin’i için ayrı
externally_connectablekaydı; project-17veproject-18içeren sahte project catalog;- onaylı project için memory içindeki counter’ı artıran tek privileged effect;
- sender context, karar ve counter değişimini kaydeden bağımsız event ledger.
Gerçek cookie, browser history, download, credential, remote administration interface veya production origin kullanmayın. Bir request’in sınırı geçtiğini kanıtlamak için counter yeterlidir.
Kasıtlı olarak güvensiz relay küçüktür:
// content-script.js — yalnızca kasıtlı güvensiz lab kalıbı
window.addEventListener("message", (event) => {
if (event.data?.namespace !== "lab-extension") return;
chrome.runtime.sendMessage(event.data.payload);
});
Bu kod event.source, mevcut page origin, message shape, operation, size veya document lifecycle
kontrolü yapmaz. Daha önemlisi, kusursuz bir event.source === window kontrolü bile yalnızca hangi
window’un event yayınladığını gösterir; sayfayı güvenilir yapmaz. MDN, cross-document messaging için
hem origin hem gerekirse source doğrulamasını önerir. Ancak bunlar admission fact’tir; service
worker yine de operation authorization yapmalıdır.
Mesaj göndermeden önce inventory
Handler ile etkileşim kurmadan önce kod ve policy haritasını çıkarın.
Manifest ve injection inventory
| Alan | Toplanacak evidence |
|---|---|
| Content-script matches | Exact scheme, host, path, exclusion ve dynamic registration’lar |
| Frame reach | all_frames, match_about_blank, match_origin_as_fallback |
| Execution world | ISOLATED veya MAIN; ortak DOM/event channel’ın gerekçesi |
| External callers | externally_connectable.matches, ID’ler ve wildcard kullanımı |
| Privileged permissions | permissions, host_permissions, optional grant ve activeTab |
| Web-accessible resources | Dışarı açılan path’ler ve bunları yükleyebilen siteler |
| Lifecycle | Service-worker restart, port reconnect ve state recovery davranışı |
Message ve effect inventory
| Alan | Sorular |
|---|---|
| Listener population | Internal message, external page, external extension, port veya one-shot? |
| Sender policy | Hangi browser-observed alanlar zorunlu, URL nasıl normalize ediliyor? |
| Schema | Unknown key, yanlış type, nesting ve oversized değer reddediliyor mu? |
| Dispatcher | Caller URL, method, script, tab, path, key veya command seçebiliyor mu? |
| Trusted state | Tenant, selected object, user gesture ve approval nereden geliyor? |
| Response | Content script veya external page’e hangi alanlar dönüyor? |
| Effect observer | Privileged action’ın gerçekleştiğini hangi bağımsız sinyal kanıtlıyor? |
| Denial observer | Reddedilen request’in hiç etki üretmediğini ne kanıtlıyor? |
Static code search; onMessage, onConnect, onMessageExternal, onConnectExternal,
sendMessage, connect, postMessage, custom DOM event ve privileged API çağrılarını bulmalıdır.
Her listener’ı son etkiye kadar izleyin. Generic dispatcher’a forward eden sanitized handler,
review’un son noktası değildir.
Sender context’i koruyun ve doğrulayın
Güvenli internal listener channel admission, schema validation ve authorization’ı ayırır:
const ALLOWED_ORIGIN = "https://app.lab.invalid";
const PROJECTS = new Set(["project-17"]);
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
const senderUrl = sender.url ? new URL(sender.url) : null;
const admitted =
sender.id === chrome.runtime.id &&
senderUrl?.origin === ALLOWED_ORIGIN &&
sender.frameId === 0 &&
typeof sender.documentId === "string";
if (!admitted) return false;
const valid =
message &&
message.version === 1 &&
message.operation === "read-current-project-summary" &&
typeof message.projectId === "string" &&
Object.keys(message).every((key) =>
["version", "operation", "projectId", "requestId", "approvalId"].includes(
key,
),
);
if (!valid || !PROJECTS.has(message.projectId)) {
sendResponse({ ok: false, code: "DENIED" });
return false;
}
void handleApprovedSummary(message, sender).then(sendResponse);
return true;
});
Bu bir kalıptır; doğrudan kullanılacak universal policy değildir. Bazı browser veya context’ler her
sender alanını sağlamaz ve browser compatibility test edilmelidir. Policy, eksik hangi değerin
denial üreteceğini belirtmelidir. Ayrıca approvalId, well-formed herhangi bir string kabul etmek
yerine trusted extension state’e bağlanmalıdır.
External rota kendi listener’ına ve daha küçük operation set’ine ihtiyaç duyar:
chrome.runtime.onMessageExternal.addListener(
(message, sender, sendResponse) => {
const origin = sender.url ? new URL(sender.url).origin : null;
if (origin !== "https://partner.lab.invalid") return false;
if (
message?.version !== 1 ||
message?.operation !== "extension-health" ||
Object.keys(message).some(
(key) => !["version", "operation", "requestId"].includes(key),
)
) {
sendResponse({ ok: false, code: "DENIED" });
return false;
}
sendResponse({ ok: true, state: "ready" });
return false;
},
);
Partner origin generic dispatcher değil, status capability alır. Origin allowlist kasıtlı olarak küçük bir protocol sağladığında daha güçlüdür.
Capability minimization string filtering’den üstündür
.., javascript: veya seçili domain’leri blocklamak caller’ı security primitive üzerinde söz
sahibi bırakır. Primitive’leri named ve dar capability’lerle değiştirin.
| Caller’dan almayın | Yerine bunu kabul edin | Trusted code içinde çözün |
|---|---|---|
| Tam URL ve HTTP method | Operation ve bounded object ID | Sabit HTTPS origin, path, method ve response alanları |
| Tab ID ve script source | Current-workflow action | Active approved tab ve paket içindeki script dosyası |
| Storage key veya namespace | Typed preference name | Sabit key map ve value schema |
| Filename ve download URL | Report ID | Server-side report URL ve güvenli üretilmiş filename |
| Raw HTML veya JavaScript | Structured display fields | Extension context’te text-only DOM construction |
| Arbitrary dispatcher action | Versioned operation union | Explicit handler ve default-deny |
Return value aynı kurala tabidir. Chrome, content script’e gönderilen verinin sayfaya sızabileceğini belirtir. Service worker yalnızca render için gereken minimum alanları döndürmeli; raw cross-origin response, authentication header, internal identifier veya geniş extension storage asla dönmemelidir.
Authorization’ı lifecycle’a bağlayın
Message policy connection anında doğru, effect anında yanlış olabilir. Single-page application’lar top-level document’ı değiştirmeden state’i değiştirir. Frame’ler navigate olur. Service worker durur ve yeniden başlar. Long-lived port disconnect ve reconnect olur. Queued request beklerken kullanıcı account veya workspace değiştirir.
High-impact request şunları bağlamalıdır:
MessageSenderiçindekitab.id,frameIdve desteklendiğindedocumentId;- normalize edilmiş page origin;
- extension tarafından görülen account veya tenant;
- extension tarafından çözülen selected object;
- gerçek user gesture veya explicit approval state;
- single-use nonce ve kısa expiry;
- tam operation ve response class.
Bağı effect’ten hemen önce yeniden doğrulayın. “Bu port trusted” şeklinde koşulsuz boolean tutmayın. Hangi document için, ne zamana kadar ve hangi işlemi yapmak üzere trusted olduğunu kaydedin. Navigation, account transition, worker restart, port disconnect veya permission change durumunda state’i geçersiz kılın.
Reproduction methodology: capability delta’yı kanıtlayın
Güvenli sonuç capability farkını canary’lerle gösterir:
- Baseline kurun. Test sayfasından inert counter operation’ı doğrudan deneyin. Sayfanın privileged counter’a kendi başına ulaşamadığını kaydedin.
- Ingress’i kaydedin. Content-script relay üzerinden tek well-formed request gönderin. Caller’ın kopyaladığı alanları değil, service worker’daki browser-observed sender alanlarını yakalayın.
- Effect’i bağımsız gözlemleyin. Üretilen request ID’yi counter ledger ile correlate edin. Success response supporting evidence’dır; effect proof değildir.
- Tek authorization boyutunu değiştirin. Negative-control origin, child frame, stale document, farklı project ID veya external route ile tekrarlayın.
- Vulnerable ve fixed build’i karşılaştırın. Approved request çalışmaya devam etmeli; her unauthorized varyant decision record üretmeli fakat counter’ı değiştirmemelidir.
- Lifecycle sınırlarını çalıştırın. Request’i replay etmeden önce navigate edin, account değiştirin, port’u yeniden bağlayın ve worker’ı restart edin.
- Lab’ı kaldırın. Extension’ı unload edin, synthetic state’i temizleyin ve iki ingress rotasının da artık erişilemediğini doğrulayın.
Her testte tek değişken değiştirin. Origin, frame, schema ve object aynı anda değişirse denial’ın hangi gate tarafından üretildiği anlaşılamaz.
Capability delta’yı gerçek cross-origin account data okuyarak, başka tab yakalayarak, gerçek download oluşturarak veya native host çağırarak göstermeyin. Canary effect authorization hatasını zararı büyütmeden kanıtlar.
Karar pipeline’ı
Evidence matrix
Mesajın alınmasını privileged effect’ten; privileged effect’i de unauthorized impact’ten ayırın.
| İddia | Positive evidence | Negative control | Güçlü sonuç |
|---|---|---|---|
| Sayfa content-script bridge’e ulaşır | Beklenen top document içinde namespaced event gözlenir | Foreign namespace ve child-frame event yok sayılır | Test edilen page-to-content ingress karakterize edildi |
| Content script service worker’a ulaşır | Browser sender context ve request ID kaydedilir | Extension page veya stale document mesajı ayrıştırılır | Listener test edilen sender class’ları tanır |
| External page rotası scoped’dur | İzinli lab origin yalnızca status operation’a ulaşır | Unlisted origin ve ilgisiz operation reddedilir | Direct external ingress origin ve capability ile sınırlıdır |
| Confused-deputy effect vardır | Page request normalde erişilemeyen canary değişimiyle correlate olur | Page-only baseline canary’yi değiştiremez | Extension authority gösterilen capability delta’yı oluşturdu |
| Object authorization çalışır | Approved project counter bir kez değişir | Unknown ve adjacent project ID değişmeden kalır | Caller test edilen izin dışı object’i seçemez |
| Lifecycle binding çalışır | Current document ve fresh approval başarılıdır | Navigation, expired approval ve replay etki üretmez | Test authority kaydedilen lifecycle dışına taşmaz |
| Response minimize edilmiştir | Caller yalnızca dokümante summary alanlarını alır | Secret/internal alan success ve error path’te yoktur | Test response worker’ın daha geniş verisini açmaz |
| Cleanup tamamdır | Extension ve synthetic state kaldırılır | Cleanup sonrası iki message rotası da başarısızdır | Lab test edilen bridge’i artık expose etmez |
Rejected response, hiçbir effect oluşmadığını kanıtlamaz. Independent ledger hem target hem adjacent canary’nin değişmediğini göstermelidir.
Test matrix
| Boyut | Varyantlar | Beklenen güvenli sonuç |
|---|---|---|
| Ingress route | Content relay, external page, external extension, extension UI | Her population için ayrı listener ve operation policy |
| Origin | Exact allowed, sibling subdomain, HTTP, opaque, unrelated | Yalnızca policy’nin istediği normalize exact origin ilerler |
| Source/frame | Top window, child frame, popup, replaced document | Yalnızca amaçlanan current frame ve document ilerler |
| Schema | Missing, extra, wrong type, array, deep nesting, oversized | Capability resolution öncesinde reject |
| Operation | Allowed, unknown, deprecated, case variation | Explicit versioned allowlist ve default-deny |
| Object | Current, adjacent, unknown, cross-tenant ID | Trusted state yalnızca approved object’i çözer |
| Approval | Fresh gesture, absent, expired, mismatched operation | High-impact operation matching fresh approval ister |
| Replay/lifecycle | Duplicate nonce, navigation, worker restart, account change | Authority kayıtlı binding dışına taşmaz |
| Response | Success, denial, timeout, upstream error | Privileged raw data içermeyen minimum stable schema |
| Cleanup | Extension’ı unload et ve registration’ları temizle | Direct ve relayed route artık kullanılamaz |
Hardening sırası
- Gerekmeyen rotaları kaldırın. Doğrudan page integration gerekmiyorsa
externally_connectableeklemeyin. Alışkanlıkla DOM veyapostMessagerelay kurmayın. - Injection’ı daraltın. Exact HTTPS match pattern, exclusion, top-frame-only execution ve
workflow uygunsa programmatic ya da
activeTabinjection kullanın. - Caller population’larını ayırın. Internal content message, extension page, external page ve external extension ayrı listener veya explicit route discriminator ister.
- Browser-observed sender fact kullanın. Exact origin normalize edip karşılaştırın. Policy’nin dayandığı frame/document alanlarını zorunlu kılın. Payload içindeki kopyalara güvenmeyin.
- Malformed protocol’ü reddedin. Schema’yı versionlayın, serialized size ve collection count sınırı koyun, unknown key reddedin ve discriminated operation allowlist kullanın.
- Authority’yi intent ile değiştirin. Caller named operation ve bounded identifier seçsin; trusted code URL, method, tab, storage key, filename ve packaged script seçsin.
- Sensitive effect’i fresh state’e bağlayın. Tenant, object, gesture, nonce, expiry, document ve operation tek authorization record içinde birleşsin.
- Response’u minimize edin. Content script’i sayfaya olası disclosure path olarak kabul edin.
- Transition anında geçersiz kılın. Navigation, account change, worker restart, disconnect ve permission change önceki authorization’ı sonlandırsın.
- Denial’ı effect olarak test edin. Her rejected request için privileged side effect’in sıfır olduğunu bağımsız doğrulayın.
Detection ve forensic sinyaller
Faydalı telemetry şunları içerir:
- extension ID, version, install source ve permission değişiklikleri;
- content-script registration, match scope, frame policy ve execution world;
- internal/external listener, port name ve request ID;
- browser-observed sender origin, tab, frame ve document identifier;
- secret payload yerine schema version, operation name ve object identifier;
- authorization gate, decision reason, approval age ve replay sonucu;
- çağrılan privileged API, destination class ve bounded response class;
- request çevresindeki navigation, account, worker ve port lifecycle event’leri;
- tek document’tan beklenmeyen request burst veya origin’ler arasında tekrarlayan denial;
- effect correlation ve adjacent canary’nin değişmediğine ilişkin kanıt.
Token, page content, sensitive query string içeren tam URL veya raw cross-origin response loglamayın. Security telemetry ikinci bir exfiltration rotasına dönüşmemelidir.
Finding’i raporlamak
Kesin bir finding title ödünç alınan capability’yi adlandırır:
Content-script relay caller tarafından seçilen URL’yi browser sender context veya object authorization doğrulamadan forward ettiği için page script, extension service worker’a authenticated cross-origin project request yaptırabiliyordu.
Rapor şunları içermelidir:
- exact browser, extension ve manifest version;
- iki ingress rotası ve ulaştıkları listener;
- effect ile ilgili manifest match pattern, frame scope ve permission;
- yakalanan browser-observed sender alanları;
- minimum message schema ve caller-controlled authority alanları;
- page-only baseline, approved canary, unauthorized canary ve independent effect evidence;
- origin, frame, document, operation, object, replay ve lifecycle için negative control;
- gerçek sensitive data kullanmadan gösterilen minimum capability delta;
- hem relay hem service-worker dispatcher içindeki root cause;
- blocklist yerine capability contract olarak ifade edilen remediation;
- cleanup proof ve kalan belirsizlik.
Severity, erişilebilir privileged effect ve caller population’a göre belirlenir. Tek exact partner origin’e sabit health response dönmek, geniş content-script match üzerinden erişilebilen arbitrary authenticated fetch ile aynı değildir. İddialar test edilen operation, origin, permission ve lifecycle state ile sınırlı kalmalıdır.
Nihai model
Güvenli tasarım “page data kullanılmadan önce sanitize edildi” değildir. Küçük bir authorization protocol’dür:
browser-observed sender
→ explicit ingress policy
→ versioned intent
→ trusted object resolution
→ fresh workflow authorization
→ tek bounded effect
→ minimum response
Isolated world değerlidir. Manifest match pattern değerlidir. externally_connectable değerlidir.
Fakat hiçbiri sayfaya service worker’ın ambient authority’sini vermez.
Extension ancak şu soruyu evidence ile cevaplayabildiğinde confused deputy olmaktan çıkar: Hangi principal, hangi named capability’yi, hangi object için, hangi fresh approval altında istedi ve tam olarak ne değişti?
Bu teknik not ne kadar güncel?
En son kaynak incelemesi, içerik güncellemesi veya yayın tarihi gösterilmektedir.
Birincil kamu kayıtları kontrol edildi. Ortama özgü davranış, ayrıca yeniden üretilmedikçe iddianın dışındadır.
- developer.chrome.com · messaging ↗
- developer.chrome.com · content-scripts ↗
- developer.chrome.com · externally-connectable ↗
- developer.chrome.com · network-requests ↗
- developer.chrome.com · stay-secure ↗
- developer.mozilla.org · postMessage ↗
- developer.mozilla.org · Content_scripts ↗
- developer.mozilla.org · onMessageExternal ↗
