惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
K
Kaspersky official blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
aimingoo的专栏
aimingoo的专栏
M
MIT News - Artificial intelligence
小众软件
小众软件
云风的 BLOG
云风的 BLOG
腾讯CDC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
Stack Overflow Blog
Stack Overflow Blog
量子位
S
Secure Thoughts
G
GRAHAM CLULEY
C
CXSECURITY Database RSS Feed - CXSecurity.com
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
T
Threat Research - Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
G
Google Developers Blog
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Martin Fowler
Martin Fowler
The GitHub Blog
The GitHub Blog
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 聂微东
宝玉的分享
宝玉的分享
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
S
Security Affairs
Help Net Security
Help Net Security
博客园 - 三生石上(FineUI控件)
AWS News Blog
AWS News Blog
博客园 - 叶小钗
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V2EX - 技术
V2EX - 技术
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
H
Heimdal Security Blog
W
WeLiveSecurity
C
Check Point Blog

CodePen

433: CodePen 2.0 is Backward Compatible with Any Classic Pen or Project 432: Trends of 2026 (So Far) 431: Versions are Deeply Integrated into CodePen Chris’ Corner: Layers of Layers 430: The Wild World of Keyboard Shortcuts in Web Apps Chris’ Corner: Makin’ Stuff 429: Why CodePen Rebuilt Its Realtime Service Chris’ Corner: The Edge, Man 428: Improving The Entire Billing System (is Very Worth It) Chris’ Corner: Design Chris’ Corner: A11Y 427: Next.js and The Journey of SSR 426: Browserslist in CodePen 2.0 Chris’ Corner: Finding Type Chris’ Corner: View Transitions 425: Help Your Users Help You with Debug Logs Chris’ Corner: Check It B4 U Wreck It Chris’ Corner: Import Maps 424: File List Optimization Chris’ Corner: ZIP first? 423: 2.0 Templates Chris’ Corner: URLs 422: Supporting Packages Chris’ Corner: Share What You Do 421: View Control of the 2.0 Editor Chris’ Corner: Design Chris’ Corner: Even Grids Chris’ Corner: Processing 420: What are Blocks? Chris’ Corner: Anchors 419: Why 2.0? Chris’ Corner: Cool Things Chris’ Corner: SVG Tools 418: CodeMirror 6 Chris’ Corner: All Together Now Chris’ Corner: Light & Boxes Chris’ Corner: Lovingly Esoteric CSS Chris’ Corner: Type Chris’ Corner: Two Liners Chris’ Corner: Type Chris’ Corner: Freshly-Fallen CSS Chris’ Corner: Cloud Four Chris’ Corner: HTML Chris’ Corner: Web Components Chris’ Corner: Kagi Blog Typography 417: Iframe Allow Attribute Saga Chris’ Corner: Cursors Chris’ Corner: Browser Feature Testing 416: Upgrading Next.js & React Chris’ Corner: AI Browsers 415: Babel Choices 414: Apollo (and the Almighty Cache) Chris’ Corner: Stage 2 413: Still indie after all these years Chris’ Corner: Design (and you’re going to like it) 412: 2.0 Embedded Pens Chris’ Corner: Discontent 411: The Power of Tree-Sitter Chris’ Corner: Word Search 410: Trying to help humans in an industry that is becoming increasingly non-human Chris’ Corner: Little Bits of CSS 409: Our Own Script Injection Chris’ Corner: Terminological Fading 408: Proxied Third-Party JavaScript Chris’ Corner: Simple, Accessible Multi-Select UI 407: Our Own CDN Chris’ Corner: Clever Clever 406: Hot Trends of 2025 Chris’ Corner: Pretty Palettes 405: Elasticsearch → Postgres Search Chris’ Corner: Faces Chris’ Corner: Browser Wars Micro Edition 404: Preventing Infinite Loops from Crashing the Browser Chris’ Corner: Scroll-Driven Excitement 403: Privacy & Permissions Chris’ Corner: AI for me, AI for thee 402: Bookmarks Chris’ Corner: We Can Have Nice Things 401: Outgoing Email Chris’ Corner: Tokens Chris’ Corner: Modern CSS Features Coming Together Chris’ Corner: Liquid Ass Chris Corner: For The Sake of It Chris’ Corner: Type Stuff! Chris’ Corner: Doing a Good Job Chris’ Corner: Design Do’s and Don’ts Chris’ Corner: CSS Deep Cuts Chris’ Corner: GSAP, more like FREESap Chris’ Corner: Reacting Chris’ Corner: Rounded Triangle Boxes and Our Shapely Future Chris’ Corner: Fairly Fresh CSS Chris’ Corner: 10 HTML Hits Chris’ Corner: CSS Powered Componentry Chris’ Corner: The New Web Safe Chris’ Corner: PerformanCSS Chris’ Corner: Color Accessibility Chris’ Corner: onChange Chris’ Corner: Accessible Takes Chris’ Corner: Creative Coding
Google Chrome & Iframe `allow` Permissions Problems
Chris Coyier · 2025-10-21 · via CodePen

If you’re a CodePen user, this shouldn’t affect you aside from potentially seeing some console noise while we work this out. Carry on!

At CodePen we have Embedded Pens which are shown in an <iframe>. These contain user-authored code served from a non-same-origin URL. We like to be both safe and as permissive as possible with what we allow users to build and test.

The sandbox attribute helps us with safety and while there are some issues with it that we’ll get to later, this is mostly about the allow attribute.

Say a user wants to use the navigator.clipboard.writeText() API. So they write JavaScript like:

button.onclick = async () => {
  try {
    await navigator.clipboard.writeText(`some text`);
    console.log('Content copied to clipboard');
  } catch (err) {
    console.error('Failed to copy: ', err);
  }
}Code language: JavaScript (javascript)

The Embedded Pen is placed on arbitrary origins, for example: chriscoyier.net. The src of the <iframe> is at codepen.io, so there is an origin mismatch there. Since the JavaScript in the iframe is not same-origin, it is subject to permissions policies.

Without the allow attribute on our <iframe> it would throw an error when the user tries to execute that JavaScript.

Failed to copy:  NotAllowedError: Failed to execute 'writeText' on 'Clipboard': The Clipboard API has been blocked because of a permissions policy applied to the current document. See https://crbug.com/414348233 for more details.

This is an easy fix. We make sure that allow attribute is on the <iframe>, like this, targeting the exact feature we want to allow at any origin:

<iframe
  src="https://codepen.io/..." 
  allow="clipboard-write *;">
</iframe>Code language: HTML, XML (xml)

But here’s where the problem comes in…

The (new) Nested Iframe Issue

CodePen’s Embedded Pens have a nested <iframe> structure like this:

The code essentially looks like this, illustrated with the iframe page content inline.

<iframe src="https://codepen.io/...">
  CodePen UI

  <iframe src="...">
    User-Authored Code
  </iframe>
</iframe>Code language: HTML, XML (xml)

To support the JavaScript APIs, we need to put the allow attribute on the Preview iframe like this:

<iframe src="https://codepen.io/...">
  CodePen UI

  <iframe 
     src="..." 
     allow="clipboard-write *;"
  >
    User-Authored Code
  </iframe>
</iframe>Code language: HTML, XML (xml)

Uh-oh! Now we have a problem.

Recently (Chrome 136+) this error gets thrown as soon as the nested iframe has the allow attribute:

[Violation] Potential permissions policy violation: clipboard-write is not allowed in this document.

With our complete list (which I’ll include below), these error logs are very intense and noisy:

Error messages in a developer console indicating various permissions policy violations for different APIs.

Can’t we just put the allow attributes on both <iframe>s?

Yes and no.

Now we run into a second problem that we’ve been working around for many years.

Every browser has a different set of allow attribute values that it supports. If you use a value that isn’t supported, it throws console errors or warnings about those attributes. This is noisy or scary to users who might think it’s their own code causing the issue, and it’s entirely outside of their control.

The list of allow values for Google Chrome

We need all of these values in the allow attribute for users to test safe browser APIs. We constantly adjust to add new APIs, often that our users ask for directly.

<iframe
  allow="accelerometer *; bluetooth *; camera *; clipboard-read *; clipboard-write *; display-capture *; encrypted-media *; geolocation *; gyroscope *; language-detector *; language-model *; microphone *; midi *; rewriter *; serial *; summarizer *; translator *; web-share *; writer *; xr-spatial-tracking *"
></iframe>Code language: HTML, XML (xml)

There are even some quite-new AI-related attributes reflecting brand new browser APIs.

Example of allow value errors

If were to ship those allow attribute values on all <iframe>s that we generate for Embedded Pens, here’s what it would look like in Firefox:

A list of unsupported feature policy warnings displayed in a console log, indicating various feature names that are not recognized or supported.
At the moment, Firefox actually displays three sets of these warnings. That’s a lot of console noise.

Safari, at the moment, isn’t displaying errors or warnings about unsupported allow attribute values, but I believe they have in the past.

Chrome itself throws warnings. If I include an unknown policy like fartsandwich, it will throw a warning like:

Unrecognized feature: 'fartsandwich'.

Those AI-related attributes require a trial which also throw warnings, so most users get that noise as well.

Error messages displayed in a console related to unsupported origin trials and unrecognized features.

We Need To Do User-Agent Sniffing (sorry!)

To avoid all this noise and stop scaring users, we detect the user-agent client-side and generate the iframe attributes based on what browser we’re pretty sure it is.

Here’s our current data and choices for the allow attribute:
export default {
  allowAttributes: {
    chrome: [
      'accelerometer',
      'bluetooth',
      'camera',
      'clipboard-read',
      'clipboard-write',
      'display-capture',
      'encrypted-media',
      'geolocation',
      'gyroscope',
      'language-detector',
      'language-model',
      'microphone',
      'midi',
      'rewriter',
      'serial',
      'summarizer',
      'translator',
      'web-share',
      'writer',
      'xr-spatial-tracking'
    ],
    firefox: [
      'camera',
      'display-capture',
      'geolocation',
      'microphone',
      'web-share'
    ],
    default: [
      'accelerometer',
      'ambient-light-sensor',
      'camera',
      'display-capture',
      'encrypted-media',
      'geolocation',
      'gyroscope',
      'microphone',
      'midi',
      'payment',
      'serial',
      'vr',
      'web-share',
      'xr-spatial-tracking'
    ]
  }
};Code language: CSS (css)

We’ve been around long enough to know that user-agent sniffing is rife with problems. We’ve also been around long enough that you gotta do what you gotta do to solve problems. While we don’t love it, we’ve been doing this for many years and it’s mostly worked.

Can’t Sniff Without ‘Script.

Unfortunately the user-agent sniffing is limited to where a script can run on the parent page which has the <iframe>:

<script>
  /*
    We need to user-agent sniff at *this* level
    so we can generate the allow attributes
    when the iframe is created.
  */
</script>
<iframe src="..." allow="..."></iframe>Code language: HTML, XML (xml)

CodePen has a couple of features where the <iframe> is provided directly, not generated, so there’s no script that runs on the parent page.

  1. Direct <iframe> embeds. Users choose this in situations where they can’t run JavaScript directly on the page it’s going (e.g. RSS, restrictive CMSs, etc)
  2. oEmbed API. A server-side call returns an <iframe> to be embedded.

The nested structure of our embeds has helped us here where that first level of iframe can attempt to user-agent sniff and apply the correct allow attributes to the internal Preview iframe.

The problem now is that if we’re expected to provide the allow attributes directly, we can’t know which set of attributes to provide, because any browser in the world could potentially be loading that iframe.

Solutions?

Are the allow attributes on “parent” iframes really necessary?

Was this a regression? Or is this a feature? It sorta seems like the issue is that it’s possible for nested iframes to loosen permissions on a parent, which could be a security issue? It would be good to know where we fall here.

Could browsers just stop erroring or warning about unsupported allow attributes?

Looks like that’s what Safari is doing and that seems OK?

If this is the case, we could just ship the complete set of allow attributes to all browsers. A little verbose but prevents needing to user-agent sniff.

This could also help with the problem of needing to “keep up” with these attributes quite as much. For example, if Firefox starts to support the “rewriter” value, then it’ll just start working. This is better than some confused or disappointed user writing to CodePen Support about it. Even being rather engaged with web platform news, we find it hard to catch when these very niche features evolve and need iframe attribute changes.

Could browsers give us API access to what allow attributes are supported?

Can the browser just tell us which ones it supports and then we could verify our list against that? Navigator.allow?

We’d likely still need our own list of the safe attributes we want to support, and this would still limit the implementation to where a script can run on the parent page, but an API could provide better insight than a hardcoded browser list.

Also…

  • It’s not just the allow attribute. We also maintain browser-specific sets for the sandbox attribute. Right now, this isn’t affected by the nesting issues, but we could see it going that road.
  • This isn’t entirely about nested iframes. We use one level of iframe anywhere on codepen.io we show a preview of a Pen, and we need allow attributes there also. This is less of an immediate problem because of the user-agent sniffing JS we have access to do get them right, but ideally we wouldn’t have to do that at all.