Everything described below applies only to the client part implemented in JavaScript. Criticism of a technical nature (for example, a detour route) is welcome, but not a critique in the style of “what for”.
When developing a module for connecting applets to a certain platform (let's call it Hyper), there was a security problem, since the plug-in applet, besides the passive data block (content), also contains an active (code). And in the active block, an inattentive developer (attacker) can access the global window object and access variables or important kernel methods and make a substitution, which at best will simply lead to the collapse of the platform (within the browser of course), and at worst install various hooks not affecting the operation of the system, but intercepting the user's personal data. In the future, an unsuspecting user will use the “Watch from Bob” gadget, which collects information about it quietly or sends spam to addresses from the contact list.
The problem of collisions of global variables has already been considered and
a solution has been proposed to isolate the loadable code from the platform core code. Everyone knows that when creating a variable in the global namespace, it becomes a property of the window object. For example, var a = 10; same window.a = 10;
Our task is to isolate the kernel code so that third-party scripts could not access it. Isolation is based on creating an anonymous function and instantly calling this function to initialize local variables and objects.
Example: (function () {a = 10;}) (); The function is anonymous and will not be visible through the window object.
')
Let's get a simple kernel:
var Core = {};
Core.sName = "MyCore" ;
Core.MyMethod = function (sMyValue) {alert (sMyValue); }; * This source code was highlighted with Source Code Highlighter .
Isolate the core:
(function () {
var Core = {};
Core.sName = "MyCore" ;
Core.MyMethod = function (sMyValue) {alert (sMyValue); };
}) (); * This source code was highlighted with Source Code Highlighter .
Now create the applet download function:
Applet.Link = function (sCode, oContext) {(new Function (sCode)). Call (oContext); } where
sCode is the applet's executable code, oContext is an important parameter. More broadly, this is the notion of context from the desktop world. Who wrote in assembler under protected mode will understand what they mean. Briefly, the context contains information about the state of the system. In desktop applications, register information is stored there, i.e. the application itself can change them without disrupting the entire system. In our case, the context contains the variables and platform objects necessary for the applet to work. Our task when launching the execution applet is to create a context. To do this, we need to know which variables and platform methods the applet code needs. We will consider the already created objects. Suppose an applet needs the MyMethod method from the Core namespace.
We will do the creation of the context manually (in Hyper, this is all automated, there is an applet handle in xml format and the concept of ImportBlock, which lists imported variables and objects). The article for the assimilation of the material is all simplified. So we get the context: var oContext = {MyMethod: Core.MyMethod)}. Let's combine it all in the code:
(function () {
// Core module.
var Core = {};
Core.sName = "MyCore" ;
Core.MyClass = function () {};
Core.MyClass.prototype.MyMethod = function (sMyValue) {alert (sMyValue); };
// Applet module.
Applet = {};
Applet.Link = function (sCode, oContext) {( new Function (sCode)). Call (oContext); }
// Load applet module.
var sCode = "this.MyMethod ('Hello world');" ;
var oContext = {MyMethod: Core.MyMethod};
Applet.Link (sCode, oContext);
}) (); * This source code was highlighted with Source Code Highlighter .
What happens in the resulting code? An applet is created with the code: this.MyMethod ('Hello world'); Since the function with this code was launched in the context of the oContext object containing the property MyMethod, this property is available in the body of this function through this. Running the applet will output an alert with the text Hello world. Back to the attackers or just inattentive developers.
Applet # 1 was created with the code and launched for execution:
this .MyMethod = function () {alert ( "Hack !!!" )};
this .MyMethod ( 'Hello world !!!' ); * This source code was highlighted with Source Code Highlighter .
As a result, this applet will show an alert with the text Hack. The applet is trying to replace a method from the Core namespace, but in fact it will change the method only in its context. And so another applet using the same method will work fine.
Created applet # 2 with code and running for use:
Core.MyMethod = function () {alert ('Hack !!!'); };
Here the attacker brazenly tried to change the Core.MyMethod, but his applet will work with an error, because the Core is undefined and we know why.
And now all the code:
(function () {
// Core module.
var Core = {};
Core.sName = "MyCore" ;
Core.MyMethod = function (sMyValue) {alert (sMyValue); };
// Applet module.
Applet = {};
Applet.Link = function (sCode, oContext) {( new Function (sCode)). Call (oContext); };
// Load applet module from hacker # 1.
var sCode = "this.MyMethod = function () {alert ('Hack !!!'); }; this.MyMethod ('Hello world'); " ;
var oContext = {MyMethod: Core.MyMethod};
Applet.Link (sCode, oContext);
// Load applet module from hacker # 2.
var sCode = “Core.MyMethod = function () {alert ('Hack !!!'); }; " ;
var oContext = {MyMethod: Core.MyMethod};
Applet.Link (sCode, oContext);
// Load applet module from right developer.
var sCode = "this.MyMethod ('Hello world');" ;
var oContext = {MyMethod: Core.MyMethod};
Applet.Link (sCode, oContext);
}) ();
* This source code was highlighted with Source Code Highlighter .
IMPORTANT!!! When forming the context, it is necessary to watch out for the link to the object, otherwise the malicious applet will be able to replace the whole object with the methods and the whole platform will work with the malicious code. The problem is solved by writing a function for the formation of the context, which takes into account everything that is imported and produces a copy of the object hierarchy.
Conclusion: The second security issue of a platform with the possibility of developing applets for it was considered. The first, I remind you, is the
collision of variable names in the global namespace . There is a third problem that is access to global browser properties (window, document, etc.), but this topic is for another article.