慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

Hacker News

Introducing Claude Opus 4.7 Qwen Studio The Future of Everything is Lies, I Guess: Where Do We Go From Here? GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Ancient DNA reveals pervasive directional selection across West Eurasia [pdf] Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome Show HN: Libretto – Making AI browser automations deterministic US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Unexpected €54k billing spike in 13 hours: Firebase browser key without API restrictions used for Gemini requests Retrofitting JIT Compilers into C Interpreters IPv6 traffic crosses the 50% mark The Accursèd Alphabetical Clock Cybersecurity Looks Like Proof of Work Now Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent When moving fast, talking is the first thing to break Too much discussion of the XOR swap trick Introduction to Spherical Harmonics for Graphics Programmers The Grand Line Building a Z-Machine in the worst possible language High-Level Rust: Getting 80% of the Benefits with 20% of the Pain GitHub - duguyue100/midnight-captain: Inspired by Midnight Commander, tailored to my taste. How to build a `git diff` driver · Jamie Tanna | Software Engineer Center for Responsible, Decentralized Intelligence at Berkeley The Local Universe’s Expansion Rate Is Clearer Than Ever, but Still Doesn’t Add Up - A new synthesis of astronomical measurements confirms a persistent mismatch that could point to physics beyond current models The air throughout our homes is infused with microplastics. But there are things you can do to breathe less of them The disturbing white paper Red Hat is trying to erase from the internet – OSnews The Future of Everything is Lies, I Guess: Annoyances ‘Abhorrent’: the inside story of the Polymarket gamblers betting millions on war Productive procrastination — Max van IJsselmuiden maps, territory and LMs 447 Terabytes per Square Centimetre at Zero Retention Energy: Non-Volatile Memory at the Atomic Scale on Fluorographane Show HN: Pardonned.com – A searchable database of US Pardons 20 Years on AWS and Never Not My Job The Seasons are Wrong
瞬息之页之安
2026-05-20 · via Hacker News

吾筑之。小应用,或微服务,视之如何耳。以其所为,安从来之?初即本怀。滥施之域,实有之:一应用,纳受公网任意HTML,正招不欲之目者。

初,研设既毕,吾乃专意于结构化之安全检视。吾有安全代理之技,久所砥砺,此诚试之良机。遂命 Codex 以此技为鉴,检视是应用。复申之曰:勿囿于技所覆,倘有他见,吾欲知之。

余文所述,乃详述所标之弱处及所施之缓解之法.

所上传之HTML,可直接于应用之源执行.

此乃亟需关注之关键问题.

事: /api/pages/:id/content返所上传之原始HTML为text/html 自主应用源起。寻常界面后注入CSP,载于沙盒化blob iframe,然攻击者可共享直API URL,绕此隔离。

风险: 同源存储型XSS。虽今应用用户状态微薄,然此可致钓鱼、源滥用、未来权限提升及针对管理员之攻击。

建议之修正: 加设HTTP层防护于内容响应:至少须有Content-Security-Policysandbox allow-scripts,并辅以上传页面的CSP,及X-Content-Type-Options: nosniff。或可返内容为附件,或移不可信内容至别源。

应此之道,首在确保页面路由涵括下列标头:

Content-Security-Policy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'"
Permissions-Policy = "camera=(), geolocation=(), microphone=(), payment=(), usb=()"
Referrer-Policy = "no-referrer"
X-Content-Type-Options = "nosniff"

權限政策向未廣泛可用,故截至本文撰寫之時,五月十五日,二零二六,僅影響基於Chromium之瀏覽器。

getPageContent函數現返回HTML,並設置以下標頭:

{
  "Content-Type": "text/html; charset=utf-8",
  "Cache-Control": "no-store",
  "X-Robots-Tag": "noindex",
  "Content-Security-Policy": buildUploadedPageHttpCsp(),
  "X-Content-Type-Options": "nosniff",
}

關於內容安全政策,吾人始於:

`sandbox allow-scripts; ${buildUploadedPageCsp()}`;

復加buildUploadedPageCsp之結果:

return [
  "default-src 'none'",
  `script-src ${scripts}`,
  `style-src ${styles}`,
  "font-src https://fonts.gstatic.com",
  "img-src data: blob:",
  "media-src data: blob:",
  "object-src 'none'",
  "base-uri 'none'",
  "form-action 'none'",
].join("; ");

script-srcstyle-src 之设,'unsafe-inline' 之启,许以下列之内容递送网络:

const TRUSTED_CDN_ORIGINS = [
  "https://cdn.jsdelivr.net",
  "https://unpkg.com",
  "https://cdnjs.cloudflare.com",
] as const;

。此列中,惟 fonts.googleapis.com 得入 style-src,俾 CSS 得载,而 https://fonts.gstatic.com 则明许于字型文件自身。二者皆非脚本之源。

。亦须谨记,所上传之页,乃于沙盒中呈现。iframe

<iframe
  id="page-iframe"
  class="page-iframe"
  sandbox="allow-scripts"
  title="${`Shared ephemeral page ${pageId}`}"
></iframe>

中危之患

复有中危之患数事待解:

无上传/举报之限

患状:凡人可屡上传二兆字节之页,并屡举报之。

患险:存储之费滥,功能之召滥,Netlify Forms之扰,及审核之乱。

所拟之策:为上传/举报之行添加速率限制或配额,善者依IP或用户代理指纹于边缘或功能层施行。待滥行确凿,方可思CAPTCHA/Turnstile,以避用户之烦。

首议者速率限制也。凡调用应限速率之途,此即首验:此请可否允行?

偶有所思。速率限制之理,其一部分基于RATE_LIMIT_SECRET——此乃以OpenSSL所生之应用密钥,经Netlify之敏感环境变量而示于应用。此密钥之源,藏于1Password之库,虽于本地开发亦严加守护;其读自1Password,借Varlock而得,未尝以明文存于.env之文件也。

检核速率之限,实为迂回之途,愿君稍待。首务当取速率之秘钥。若系统不能取之,则戛然而止,众行者皆无由进。吾将受警于Sentry,以特定之rate_limit_secret_missing事件为凭。倘诸事配置得宜,则此阻隔当永无由现。

欲验速率限制之有无,须先备数事:

  • 吾等之秘钥
  • 角色哈希
  • 主体哈希
  • 密钥
  • 策略之类型
  • 既有之记录

吾知吾有密钥,故须计算吾之哈希。哈希之由,在于安危与隐秘——吾不欲存此为明文,尤以构成角色哈希之要素为甚。

函数hashValue取二参数:valuesecret:二哈希之中,密钥皆同此限速之密。至于行者之哈希,其值乃用户IP与用户代理之合。

:于函数之内,首呼crypto.subtle.importKey,以化吾密为CryptoKey,俾可与Web Crypto API相用:

// importKey(format, keyData, algorithm, extractable, keyUsages)
const key = await crypto.subtle.importKey(
  "raw",
  new TextEncoder().encode(secret),
  { name: "HMAC", hash: "SHA-256" },
  false,
  ["sign"],
);

:吾既明其素形,乃化吾密自文字为Uint8Array 之用,TextEncoder.encode 以为之设,extractable 乃为 false,而用之限于署名。若诸事顺遂,今已得吾之 CryptoKey

次第,乃 crypto.subtle.sign

// sign(algorithm, key, data)
const signature = await crypto.subtle.sign(
  "HMAC",
  key,
  new TextEncoder().encode(value),
);

吾等既定其术,以吾之 CryptoKey 付之,复用 TextEncoder,化吾值于 Uint8Array — 形式也。sign 期之。其果为 ArrayBuffer。继而化之为 Uint8Array,每八位各缀以两字之十六进制符(不足者前置零以补),而合之:

return Array.from(new Uint8Array(signature), (byte) =>
  byte.toString(16).padStart(2, "0"),
).join("");

。如是得字符串若 "0aff0380..." — 此即吾之哈希也。

警之。:吾亦以为,此散列之记,不宜久存。犹若其页,每时辰必有一cron,删去已过之期者。一记永不出于Blob之库,过其有用之时。

:既得吾二散列,次乃取key

function rateLimitKey(name: RateLimitName, actorHash: string, subjectHash: string): string {
  return `${RATE_LIMIT_PREFIX}/${name}/${actorHash}/${subjectHash}.json`;
}

初见似为文件路径。然实为存速率限制条目时所用之钥。Netlify Blobs(Netlify块)斜杠界定乃有意为之,盖因得列某前缀下所有条目——譬如,store.list({ prefix: "rate-limits/" })句首之词,未完。.json扩展仅乃习俗耳。

末三者较为直白。其策有三可能——uploadreport,或failedDelete— 定于一常数之中RATE_LIMITS其言明每窗容试之数,及窗之长短。

吾辈乃尝试以钥索现有之速率限制记录,将所得之果,递与之。activeRecord

function activeRecord(
  existing: RateLimitRecord | null,
  now: number,
  windowMs: number,
): RateLimitRecord {
  if (!existing || existing.resetAt <= now) {
    return { count: 0, resetAt: now + windowMs };
  }

  return existing;
}

若无记录存焉,或窗口已过,则新启之。否则,用旧记录。自此,验之甚明:若尝试之数将逾其限,则阻其请,并录Sentry之事件。若非,则更新记录,许其请通过。

管理员删除令无蛮力之防

事端:删除之端点,纳无限承载令牌之尝试,行直截字符串相较。

风险:令牌脆弱或泄,可遭屡次攻伐。

潜在之修正:须求长随机令牌,限速失败之删除,录失败之尝试,且于可行处用恒时相较。

删除之符循同法于限速之秘:以OpenSSL生之,藏于1Password,未尝入源码之控,复经Netlify之秘境示于服务器,其秘境标为机要。

如前所述,页面与API路由均已实施速率限制,失败尝试则记录于Sentry。余下之项——常数时间比较——乃吾所接受之暂时风险。其他缓解措施既已完备,直接字符串比较似可接受。若君有异见,请示知。

吾亦赖之Netlify 之速率限制 以护平台之安全。

管理者审核,可纳跨源标记之URL。

疑事pageIdFromUrl 自URL之源,提取/p/:id

危险:伪造之报如https://evil.example/p/real-id,若评审者信此流程,则可令管理界面授权删除真实之本地页ID。

:需url.origin === window.location.origin方得启删。

所治者,惟于getIdFromUrl稍增一语耳:

if (url.origin !== window.location.origin) {
  return null;
}

若所从来者不类,则函数返null,余者之管束者,谨防虚pageId,而后乃系诸事。

卑/固守之

报二事于此.

主应用缺全域安全头.

问题: 无CSP,frame-ancestorsReferrer-Policy,或Permissions-Policy未于应用壳或管理界面配置.

建议之策: 加Netlify头。尤宜用frame-ancestors 'none' 以御点击劫持,且于可信应用壳中设紧密之CSP。

如前所述,应用壳今行以下标题于全域:

[headers.values]
Content-Security-Policy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'"
Permissions-Policy = "camera=(), geolocation=(), microphone=(), payment=(), usb=()"
Referrer-Policy = "no-referrer"
X-Content-Type-Options = "nosniff"

所受HTML或后败CSP注入

疑案:服务器验证容有仅具文体的HTML文书,而 injectCsp 则需 <html><head>

风险:部分上传内容呈现为应用错误。

修正:使验证与呈现要求相符,或以解析/序列化方式注入,而非正则表达式。

此显我已不安之虑。虽提交之HTML有验证,然似非定规。吾严整之。今提交之HTML须经数步:首确吾得值,其为字符串,且去空后非空。次验其总字节不超过二兆之限。终乃解析文档。解析5库,并验其果含作者所供htmlhead之素。惟其如是,乃可继以上传。

结论

细察此事,实为值得。其间显露出真问题——如同源XSS之危——,当亟治之。或犹有未逮,此念将萦绕于心。然此应用经此一番功夫,已显著增其固。

欲观其全貌,源码可供浏览。若君见吾所遗或有所思以固之,请开一题——吾愿与君共臻其善。