Inline handlers built as onclick="fn('${esc(id)}')" were injectable:
esc() turns ' into ', which the browser decodes back to ' before
the JS runs, so an id like x');alert(1);// broke out of the string.
Ids can come from a restored backup file or a synced catalog. Add
SunSafe.jsArg (JSON.stringify + HTML escape) and use it in all 24
handlers across app-runtime.js and index.html, including the new
banquet-menu ones. Verified locally: an id containing a JS payload
is passed through as a plain string and nothing executes.
Also replace the Settings version label that still showed
v17.6.0 · 2026.09.07 with the current release, and bump the script
cache-busting string so the fix reaches browsers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 12:24:36 +03:00
5 changed files with 24 additions and 23 deletions
renderCategoryTabs();ensureCatalogTools();constcatalogSearch=$('sunCatalogSearch');if(catalogSearch){constboxMode=[0,5].includes(Number(activeCat));catalogSearch.placeholder=boxMode?'Поиск по № бокса':'Поиск по позиции';catalogSearch.inputMode=boxMode?'numeric':'search';}consttitle=document.querySelector('#new .catalog h1');if(title)title.textContent=catName(activeCat);
constempty=items.length?'':`<div class="catalog-empty">${catalogQuery?'По вашему запросу ничего не найдено.':`В разделе «${esc(cat.name)}» пока нет позиций.`}</div>`;
check([...index.matchAll(/@page\{([^}]*)\}/g)].every(m=>/size:A4/i.test(m[1])),'compact @page rules use A4');
check(sw.includes('v81-20260912-account-center-loader')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js')&&sw.includes('offer-workspace-v1769.js'),'service worker cache is v17.7.3');
check(index.includes('20260916-v18-1-2-banquet-menu-tab')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.7.3');
check(index.includes('20260920-v18-1-3-handler-hardening')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.7.3');
check(performance.includes('SunAttachmentGuard')&&performance.includes('TARGET=2*1024*1024'),'chat photo auto-compression is versioned');
check(performance.includes("rpc('sun_dev_dashboard')")&&performance.includes('server_size')&&performance.includes('storage_size'),'Developer Console server/storage counters are versioned');
check(performance.includes('MEMORY_REFRESH_MS=30000')&&performance.includes('MEMORY_TIMEOUT_MS=8000')&&performance.includes('memoryPromise'),'Developer Console memory refresh is bounded');
@ -65,7 +65,7 @@ check(offerWorkspace.includes('PDF и предпросмотр')&&offerWorkspace
check(offerWorkspace.includes('SunClassicOfferPDFV1767')&&offerWorkspace.includes('finalGallery=galleryFor'),'custom gallery is injected into PDF renderer');
check(releaseManifest.offerWorkspaceTabs===true&&releaseManifest.offerTemplatesSeparateTab===true&&releaseManifest.offerTwoCustomGalleryPhotos===true,'release manifest records offer workspace changes');
check(pkg.version==='17.7.3','package version is v17.7.3');
check(index.includes('20260916-v18-1-2-banquet-menu-tab'),'index cache bust is v17.7.3');
check(index.includes('20260920-v18-1-3-handler-hardening'),'index cache bust is v17.7.3');
check(sw.includes('v81-20260912-account-center-loader')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js'),'PWA caches v17.7.3 client foundation modules');
check(fs.existsSync(path.join(root,'public/core/data-layer-v1773.js'))&&fs.existsSync(path.join(root,'public/core/server-automation-v1770.js')),'data layer and server automation modules exist');
check(ux.includes('CateriumServerAutomationV1770?.enabled'),'cloud browser auto completion is disabled when server automation is active');
if(!sw.includes('20260912-account-center-loader')||!sw.includes('login-signature-v1776.js')||!sw.includes('data-layer-v1773.js')||!sw.includes('server-automation-v1770.js')||!sw.includes('offer-workspace-v1769.js')||sw.includes('offer-gallery-data.js'))fail('service worker cache is stale');elseok('PWA cache updated for login refresh');
if(html.includes('20260907-v17-6-0-stability-security')||html.includes('20260909-v17-7-3-clients-server-read')||!html.includes('20260916-v18-1-2-banquet-menu-tab')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');elseok('index cache-busting is current');
if(html.includes('20260907-v17-6-0-stability-security')||html.includes('20260909-v17-7-3-clients-server-read')||!html.includes('20260920-v18-1-3-handler-hardening')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');elseok('index cache-busting is current');
if(performance.includes('records.forEach(r=>r.addedNodes.forEach(n=>{if(n.nodeType===1)scan(n)}));enhanceDeveloperMemory()'))fail('Developer Console memory refresh is still coupled to MutationObserver');elseok('Developer Console memory refresh loop removed');
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.