Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Which doctype and root element to use #72

Open
zcorpan opened this issue Jul 3, 2020 · 2 comments
Open

Which doctype and root element to use #72

zcorpan opened this issue Jul 3, 2020 · 2 comments

Comments

@zcorpan
Copy link

zcorpan commented Jul 3, 2020

Spun off from #70 (comment)

Doctype should be <!doctype html>

OK, I worry a bit that we are relying too much on the MIME type if we don't have a <!doctype mapml> or root mapml element, but maybe that is misplaced concern, as I don't fully understand what these <!doctype html> and root html are used for.

The MIME type is appropriate for switching processing generally. The doctype is used for switching between quirks mode, limited-quirks and no-quirks, but shouldn't be used as a mechanism for new switches. With a new MIME type, the HTML parser can be configured to force no-quirks and thus make the doctype optional. This is already done for <iframe srcdoc="...">.

For the root element, what would it do? It mostly doesn't do anything in HTML, and MapML could similarly not do anything with it.

(or maybe allow omitting it for new MIME type)

Yes. Again I'm a little fuzzy about the implication of not having a doctype and relying solely on the MIME type.

There are two cases:

  • MapML document loaded from <layer src>
  • MapML document loaded in a browsing context (top-level or in <iframe src> etc)

In the first case, you could ignore even the MIME type, but that is not recommended because ignoring MIME types have a history of security problems and the trend is to enforce MIME types where possible. You could allow both text/html and text/mapml, but being strict and only successfully loading text/mapml seems better for security:

  • it's not possible to use <layer src> pointing to victim HTML page and have it leak information
  • if MapML documents are loaded with scripting disabled or other sandboxing restrictions, allowing text/html in <layer> can allow attackers to trick users into loading the MapML document in a top-level browsing context (e.g. by emailing a link or through ads) and circumvent those restrictions.

In the second case, you'd need something if there is to be a processing difference between showing an HTML document and showing a MapML document (which appears to be desired). The MIME type is the right tool here I think.

When loading from local file system, it's more common to have file extensions be the equivalent source of truth as MIME types do on the web. But this might need cooperation from the OS for some OSes. I don't know enough about how this works, but having HTML and MapML needing different processing and not being able to tell them apart from sniffing seems like it can be a problem. It might even be a problem on the web.

That said, if we want a sniffable signature for MapML, those are most effective if the signature is required to be right at the start and be a fixed amount of bytes (like XML's "<?xml "). Those bytes could be the characters "<!doctype mapml>" (ascii case-insensitive). But again this would be sniffing to verify the format and happen before the HTML parser consumes those characters.

@prushforth
Copy link
Member

I have questions that probably stem from not understanding the security issues here. Bear with me, please.

There are two cases:

  • MapML document loaded from <layer src>

You could allow both text/html and text/mapml, but being strict and only successfully loading text/mapml seems better for security:

Loading a mapml document OR an HTML document from <layer src> is appropriate, I think, if mapml is a set of elements in html. It hinges on the rendering model, which hasn't been thoroughly discussed, but which I think if you load html, you need to treat the html as map content; mapml is inherently designed to be map content. Also, <layer src> would be browsing context, wouldn't it? Just a context that is rendered on top of other contexts, and one that wouldn't allow script to run, I think, like <img src="*.svg">.

  • it's not possible to use <layer src> pointing to victim HTML page and have it leak information

What information would be leaked? I am free to point my <iframe src> at your html page, after all. So if what I mention above is conceivable (<layer src> is a context), it would be a similar situation, but maybe safer if script from your page is disallowed.

  • if MapML documents are loaded with scripting disabled or other sandboxing restrictions, allowing text/html in <layer> can allow attackers to trick users into loading the MapML document in a top-level browsing context (e.g. by emailing a link or through ads) and circumvent those restrictions.

I don't understand this. Scripting would be disabled imho. Why would loading a text/mapml document into a top level context be something to circumvent? I think it's like when you have the URL of a png file, the browser generates a page around the url, with an embedded <img src="link-to-png">. Similarly, when the browser encounters a URL to a text/mapml response i.e. I paste such a URL into the URL bar, it could generate an html page, with an embedded <layer src="link-to-mapml"></layer> element.

In the second case, you'd need something if there is to be a processing difference between showing an HTML document and showing a MapML document (which appears to be desired). The MIME type is the right tool here I think.

Correct, I think, per the discussion above?

When loading from local file system, it's more common to have file extensions be the equivalent source of truth as MIME types do on the web. But this might need cooperation from the OS for some OSes. I don't know enough about how this works, but having HTML and MapML needing different processing and not being able to tell them apart from sniffing seems like it can be a problem. It might even be a problem on the web.

That said, if we want a sniffable signature for MapML, those are most effective if the signature is required to be right at the start and be a fixed amount of bytes (like XML's "<?xml "). Those bytes could be the characters "<!doctype mapml>" (ascii case-insensitive). But again this would be sniffing to verify the format and happen before the HTML parser consumes those characters.

Are you saying that the <!doctype mapml> is the right approach (when the media type switching isn't available so you have to sniff)? In the case that we adopt the xhtml namespace, <?xml would not be enough to switch processing to "generate-HTML-document-to-wrap-the-map-layer" mode. Maybe that was why I landed on <mapml>, but I think it would still have to be in the xhtml namespace when the <!doctype mapml> isn't present.

@Malvoz Malvoz pinned this issue Aug 5, 2020
@prushforth
Copy link
Member

prushforth commented Jul 28, 2022

@zcorpan We recently completed a feature on the mapml-extension that allows it to intercept responses to top-level contexts (tabs) that are returned with the text/mapml content-type, which is then "wrapped" in a synthesized html document with generated <mapml-viewer><layer- src="url of the resource"></layer->. This is along the lines of how a browser seems to deal with media types that it recognizes e.g. images.

In doing this work, we noticed that the browser will similarly wrap a text/mapml response in a synthesized html document containing a <pre> element containing the unparsed string value of the original response (presumably the fallback to text/plain from text/mapml because it's unrecognized). In contrast, when we serve it as a MapML document (<mapml-> root element, xhtml namespace, xml syntax, application/xml content-type), if we intercept the content-type after the document is received and force it to "reload" with the content-type forced to be text/html (not certain that it really reloads, seems to do something slightly less than reloading), it puts the parsed original document into the body element, which conveniently allows us to use querySelector to retrieve it without further parsing hoops.

My question here is, and perhaps it's more of a comment than a question :-), is that if the browser recognized text/mapml as a media type, it would not be necessary to have the root <mapml-> element or a mapml doctype, if we proposed to add a <mapml> element to HTML that would be display:none by default. This way, no parser changes (apart from new elements) would be required. If someone served a document as text/html or text/mapml that had <mapml> as its root, the (standard) behaviour of putting that element in the body would be appropriate (because in the future the browser will recognize text/mapml as such).

Your thoughts below, appreciated as usual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants