caterium-app/public/core/sun-safe.js
pavlov346346-source 0fc359dda6
Some checks failed
Caterium QA / qa (push) Failing after 8m6s
fix: harden inline handlers against id injection, fix stale version label
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

34 lines
1.6 KiB
JavaScript

(()=>{
'use strict';
const escapeHTML=value=>String(value??'').replace(/[&<>"']/g,ch=>({
'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'
})[ch]);
const escapeAttr=escapeHTML;
const idToken=value=>String(value??'').replace(/[^a-zA-Z0-9_-]/g,'');
const jsArg=value=>escapeHTML(JSON.stringify(String(value??'')));
const safeImageSrc=value=>{
const s=String(value??'').trim();
if(!s)return '';
if(/^data:image\/(?:png|jpe?g|webp|gif);base64,[a-z0-9+/=\s]+$/i.test(s))return s;
if(/^(?:\.\/|\.\.\/|\/)?[a-z0-9_./-]+\.(?:png|jpe?g|webp|gif)(?:[?#][^\s]*)?$/i.test(s))return s;
if(/^blob:[a-z0-9-]+:/i.test(s))return s;
return '';
};
const setText=(node,value)=>{if(node)node.textContent=String(value??'');return node};
const insertBefore=(parent,node,reference=null)=>{
if(!parent||!node)return node;
if(reference&&reference.parentNode===parent)parent.insertBefore(node,reference);else parent.appendChild(node);
return node;
};
window.SunSafe=Object.freeze({escapeHTML,escapeAttr,idToken,jsArg,safeImageSrc,setText,insertBefore});
// Small bootstrap for account/profile UI. Keeping it here makes the account
// center available on every Caterium screen without touching the legacy monolith.
if(!document.getElementById('cateriumAccountCenterV1780Script')){
const script=document.createElement('script');
script.id='cateriumAccountCenterV1780Script';
script.src='core/account-center-v1780.js?v=20260912-v17-8-0-account-center-2';
script.async=true;
document.head.appendChild(script);
}
})();