Q:

How do I control multiply-nested embedding of my iframe? 

Domain example1.com embeds my iframe.  
Domain example2.com embeds an iframe served from example1.com. 
I would set X-Frame-Options: ALLOW FROM *.example1.com as well as  Content-Security-Policy with frame-ancestors. 
But then the browser does not allow showing the iframe content, because the window's domain is example2.com  which  does not equal example1.com. 
How can I require whitelisting for the embedder (example1.com) and also for the embedder's embedder (example2.com)? 

A:

CSP frame-ancestors already does what you want. 

Content-Security-Policy: frame-ancestors [...] checks the entire ancestor chain.  If any parent document doesn't match the source whitelist, your document will not be loaded. 
If your chain is top(child(grandchild)), this policy for grandchild would pass:
Content-Security-Policy: frame-ancestors top child

But none of these:
 Content-Security-Policy: frame-ancestors top
 Content-Security-Policy: frame-ancestors child
 Content-Security-Policy: frame-ancestors 'none'

X-Frame-Options: allow-from [...] only checks a single ancestor.  The de-facto implementation in most browsers is that it checks the top origin but no origins in between. 
If your chain is top(child(grandchild)), this directive for grandchild would work:
X-Frame-Options: allow-from http://top/

But none of these:
X-Frame-Options: allow-from http://child/
X-Frame-Options: sameorigin
X-Frame-Options: deny

The W3C CSP2 specification also explains the difference:

7.7.1.  Relation to X-Frame-Options
This directive is similar to the X-Frame-Options header that several user agents have implemented.  The 'none' source expression is roughly equivalent to that header’s DENY, 'self' to SAMEORIGIN, and so on.  The major difference is that many user agents implement SAMEORIGIN such that it only matches against the top-level document’s location.  This directive checks each ancestor.  If any ancestor doesn’t match, the load is cancelled. [ RFC7034]

(Source)

