You've made it to the last day! It's appropriate to end by tackling one of the most far-reaching issues-security. The reason security concerns exist at all in the context of VBScript and the World Wide Web is that pages bearing VBScript are foreign visitors arriving at a client computer from a server. A common fear is that maliciously or incompetently designed pages that a user unwittingly encounters could wreak havoc on the local computer. Today's lesson addresses these concerns and discusses the features of the VBScript and server-supplied component model that reduce these risks.
At the end of today, which marks the completion of three full weeks of VBScript material, you will have full knowledge of how to create and deploy effective VBScript scripts. You'll have a good understanding of the many issues such as security that might shape some of your scripting and component integration strategies. Once you complete today's lesson, creativity and ingenuity will be your guides to script creation from this point forward in your VBScript experience. Unleashing experience, ingenuity, and creativity to produce better, active documents is what VBScript is all about.
When you download a page from the Web, you download all the code along with it. As you interact with that page, code could be executed at any time while you're barely aware of the fact. Think of the material covered so far in the first 20 days of study to imagine some of the ways this could happen. You click an anchored image, and code that was written to respond to image clicks is launched. A timer is started as soon as the page loads, and after you stare at the page for 10 seconds, the timer expires. Unbeknownst to you, the timer event code starts to execute in the background.
There's no getting around the fact that unless you personally inspect the source of each and every page you ever load across the Internet, you're really taking it on blind faith that a page is valid. You have some good reasons to have such faith, but it helps to understand them to think about some of the potential security risks. Such risks include the possibility of catastrophic script errors, script viruses, or erroneous or malicious ActiveX controls. I consider each of these areas in turn with an explanation of why you don't have to lose too much sleep over such risks.
Note |
The material that follows should put your mind considerably at ease about the security of Web pages. However, the security arena today has a lot of gray areas. It will probably be some time before the Internet has a unified security front. In the meantime, keep in mind that there is always, in theory, a remote potential for disaster to strike because trouble is, by definition, surprises that you don't foresee. |
One risk of loading a Web page across the network is that the code contained in it might cause some terrible error when it runs on your system. Consider a hypothetical worst-case situation that highlights some of the risk involved. Suppose you put your new Web pages on the company's brand new Web server. One of the pages includes a script that you wrote to calculate travel expenses. As luck would have it, the script has a bug. When you click the command button to request the sum of all the daily expenditures on an expense report page, the script attempts to calculate the total price by looping through each day. Because of a bug in the While conditional, this loop loops forever rather than terminate after the specified number of days.
Suppose that you rather hastily placed this page on your company's Web server without testing it thoroughly. Meanwhile, your company's CEO takes advantage of a quick break in his overseas meeting to update his travel expense account information from his laptop. He connects his laptop to the phone system, makes a few clicks, and finds your Web page in front of him. His presentation package software is also cached in his browser, full of pages for the presentation he is about to give. As the CEO nervously waits out the break, he enters the last few days of meal information into your page. Then, he clicks a calculate button, launching the calculation code. He waits and waits and waits. He starts to think of alternate career paths for the programmer who provided this page if he has to reboot his system. Just in the nick of time, a message box pops up. It knowingly proclaims, "This page contains a script that is taking an unusually long time to finish. To end this script now, click Cancel." Although the CEO is still a bit miffed at not completing his expense report, he is relieved at the graceful recovery. In fact, he reminds himself as he turns his attention to his presentation that he'll have to commend his programming staff for their foresight in checking for such circumstances and avoiding catastrophe.
The credit really should go to the browser, however. The message is generated by the Internet Explorer browser when it detects a long period of inactivity in the script. This is a natural safeguard that's built in to the browser's support of the script language. Its purpose is to keep any page's script from locking up the browser with infinite processing.
Listing 21.1 shows an example of code that causes this type of infinite loop. This code is intended to add up the value of every third number from 1 to 1000 when a calculate button is selected. However, the script has an error. The intCount counter variable is incorrectly incremented at the bottom of the loop. Therefore, the script will never reach the loop's exit condition of intCount >= 1000. The program keeps right on looping endlessly unless something comes along to make it stop.
Listing 21.1. Code with an endless loop.
<SCRIPT language="VBScript">
<!--
' Total count from calculation
sub cmdStart_OnClick
' Adds up value of every number evenly divisible by 3; from 1 to 1000.
Dim intCount ' Current number to analyze
Dim intTotalCount ' Cumulative total
' Act on every third number, adding to total if divisible by 3
do while intCount <= 1000
' Add to the total count if the number is divisible by 3
if (intCount mod 3) = 0 then
intTotalCount = intTotalCount + intCount
end if
intCount = count + 1
loop
lblStatus.Caption = "Grand total is " & intTotalCount
end sub
-->
</script>
Note |
The page with this program, infinite.asp, is available on the CD-ROM that comes with this guide. |
When this code is executed, the loop keeps repeating continuously because the wrong name is used to increment the loop counter. The browser, however, notices that the script is executing for an unusually long time. After about 25 seconds, the browser presents a message box notifying the user of this fact and giving him the option to cancel the script altogether. Figure 21.1 shows the message box that results from running the script in Listing 21.1.
Figure 21.1: A message box indicating that the program has been running for a long period of time.
Note |
Listing 21.1 purposely showed incorrect code with an infinite loop to illustrate the browser recovery that takes place. For the algorithm in Listing 21.1 to function correctly, you'd need to replace the line intCount = count + 1 |
As the infinite loop example shows, you can hang an individual script on a page, but you can't easily hang the browser itself. Even more importantly, you can't write a script that hangs the computer. The language is designed to be robust. VBScript cannot get into situations where it could inadvertently harm the systems it is running on. The programming constructs responsible for some of the more serious errors in many languages that could interfere with other programs are simply not present in VBScript. There are no pointers to memory to misuse. There is no memory management to mishandle. There is no capability to interact with system messages or for that matter, even to call system routines. In the Windows environment, this means that you cannot make dynamic link library calls, including Windows Application Programming Interface (API) calls, from VBScript. A lot of the more complex operations that a normal Windows program can perform simply can't be done in VBScript. VBScript is all the safer for it.
Even when a script does go bad, such as in the infinite loop example, the browser and the operating system provide an added layer of protection. Simply put, any ill effects of poor VBScript programming will almost always affect only the page itself and not anything else. This is by design. Few users would want to download Web pages laden with VBScript if they risked hanging their browsers or their systems with every such page. With the robustness of VBScript, users can download pages that use it with no such concerns.
The VBScript language is designed to be error proof, as the last section discusses. It's also designed to be vandal proof. Just as no user wants to download potentially mistake-prone pages, no user wants to download pages that pose a risk of bringing viruses onto the local system.
Suppose VBScript had a command such as FormatHardDrive. (It doesn't, but just suppose it did!) A mischief-minded hacker could put a page on the Web and advertise it as "Free Tips on VBScript." If the function existed, he could provide a page that looked normal but made use of code like that in Listing 21.2.
Listing 21.2. A script function that does not exist but would be dangerous if it did!
<Script Language="VBScript">
' Startup code
FormatHardDrive
msgbox "You've been vicitimized"
</script>
If you could write this code, Web users would be pretty helpless. Any page could potentially contain such a hidden surprise. The only way to find it would be to inspect all the code before the page was ever loaded.
VBScript provides a limited, safe function set for exactly this reason. Web page users can take comfort in the knowledge that VBScript does not support any dangerous function calls. As a matter of fact, even many capabilities that you might not regard as dangerous are not present. There is no standard file support. You cannot use the clipboard from VBScript. Direct dynamic link library declarations that give access to other libraries and Windows Application Program Interface calls to carry out operating system-level functions are not allowed.
It all adds up to a language that you cannot easily manipulate for malicious purposes. One cannot say "never" with absolute certainty about anything, but most experts agree that VBScript offers little in the way of capabilities to interfere with the whole system. The biggest security threat with VBScript comes with the components that it can integrate. Integrated components such as OLE automation objects and ActiveX controls are separate pieces of code not written in VBScript. These components could, in theory, pose risks, depending on how they were written; they can use DLL calls and Windows API calls and delete files. However, you have a good model for dealing with these components, which is addressed in the next section.
The real security risk in downloading a script-based Web page is the components it uses. Like the famed Trojan Horse of old, the components can come along for the ride with the page and then perform malicious deeds when a script calls them. After all, VBScript is restricted by the domain of its language from getting into trouble. You can write a component in other languages, such as C++, that have no such restrictions. Whenever a script calls such a component, that code gets a chance to execute. This would seem to be a security hole in the script-based Web page model, but these concerns have an answer.
When you download a page that brings components with it, you are informed by the browser what those controls are. You can choose whether to accept them onto your local system. How can you ever trust a component that you didn't write? An entire system is in place to certify components by providing a trail of ownership. A component provider is not likely to intentionally package a virus-laden component and distribute it when the company name is clearly identified with a product; you can expect that the same assurance will apply when an Internet component has a trail. A business that produces a component must submit it to an authorized lab for certification, which grants a unique digital signature to be embedded in that component. This does not necessarily mean that you will never find bugs in a component. It does mean that you can track the code back to the original development company. It also means that if any changes occur in the component after it leaves the original developer, the browser will warn you before downloading it.
Certified code is called signed code, meaning it has a unique digital signature that the certification lab granted. The certification lab, called a certificate authority, documents the code submittal and the company producing it and then grants a digital certificate. This identification number is used to help identify the component in the future. The software provider then takes the digital certificate and encrypts it into the software product using an encryption password, or key.
Now the software can be distributed. Whenever a user downloads the code, the browser can use a different public key supplemented by a Windows 32 API function call in the Windows environment to verify that the component has a valid certificate. This can also detect if any changes have occurred in the component since it was released from the vendor. If no signature is present on a component, a user can still choose to download it. They can also download a component with an invalid signature, although it would probably be foolhardy to do so because this could indicate component tampering or viruses. Although the first implementation of this approach is currently available on Windows 32-bit platforms, it is intended as a cross-platform approach in the long run.
Only that specific component will carry that digital signature.
As a result, you know what you're getting when you download the
component. A component that is backed by a certified digital signature
is one that is traceable and recognizable. How will this affect
your VBScript code? When you consider which controls to integrate
to make your active pages, it is probably a wise strategy to choose
certified components. Today, this procedure is in its early stages,
and most Web page users don't give it a lot of thought. Eventually,
viewing a page that warns of noncertified components might be
regarded as a risky move that only the most daring users care
to take!
Note |
You can find information about certification process and implementation techniques by searching http://www.microsoft.com/intdev and reviewing information in the ActiveX Software Development Kit (SDK) available for download there. If you have questions on the state of certification of a commercial ActiveX component, it is recommended that you check with the vendor. |
The Internet Explorer browser will alert you to the potential download of any component. Then you make the decision of whether to assume the risk of download based on your familiarity with the control. Most people are much more likely to risk trying a certified component traceable back to the vendor than to take a chance on a page laden with controls of questionable origin. The browser pops up a dialog box that asks you whether you want to download the control. You can turn this feature off in the browser.
If you select View | Options from the menu, choose the Security tab, and then select the Programs button, you see a dialog box that lets you specify whether you want Expert security, Normal, or None. If you choose Expert, you'll get warnings about any page that has a control. Normal will just automatically prevent the controls from doing damage by not utilizing them on the page. If you choose None for open Internet cruising, you're doing the equivalent of driving without a seat belt. You may get along just fine taking your chances, and the odds may be highly in your favor, but there's always a chance you could be hit head-on by a rogue control. The potential damage that could be done in these unlikely circumstances is certainly enough to cause an Internet fatality and a good conversation piece among your Internet-savvy co-workers. The None setting is by far the most convenient to the Web page user. You must weigh the familiarity and trust you have in the pages you'll be viewing against this convenience. What's this all mean to you as the VBScript developer? Your users will face the same decision, and the degree of safety of controls and components you incorporate into your script solutions may determine whether those pages are utilized. Building your pages on known, certified controls is the answer.
Now that I've addressed issues of security, you can feel more at ease making use of the pages and components that come to you from the server. You know that you can't cause too many problems accidentally with your code and that other programmers can't cause you too many problems accidentally or intentionally. How about protection for the source code of your scripts? Perhaps you're a consulting firm, and you have a page that provides feedback to users on adjusting sensitive electronic equipment. Customers come to you just because you offer this service. The code in your page uses some algorithms based on constant values that took you many months to research and perfect. Those algorithms are also proprietary to your company, for if other consultants had access to the logic, they would offer the same services. Listing 21.3 shows such a hypothetical page and its script.
Listing 21.3. A page with proprietary code.
<HTML>
<HEAD>
<TITLE>Ken and Jasper's WiseOne Engineering</TITLE>
<H1>
<A HREF="http://w3.softlookup.com"><IMG ALIGN=BOTTOM SRC="wiseone.jpg" BORDER=2></A>
<EM>Ken and Jasper's WiseOne Engineering</EM>
</h1>
<HR>
</HEAD>
<EM>Enter the reading on Gadget 1 and we'll give you the adjustment factor</EM>
<SCRIPT language="VBScript">
<!--
sub cmdAdjustment_OnClick
' Calculate the adjustment factor based on Gadget 1 reading
dim dblTemp1 ' Hold intermediate result
' Use our secret constants to get the adjustment factor
dblTemp1 = Cdbl(txtGadget.value) * 23.015
' Then apply some more of our secret constants to do the Tim adjustment
if dblTemp1 > 20 then
dblTemp1 = dblTemp1 / 31.3
else
dblTemp1 = dblTemp1 / 15.7
end if
lblStatus.Caption = "The adjustment factor is " & str(dblTemp1)
end sub
-->
</script>
<center>
Enter gadget 1 value here:<input name="txtGadget1">
<h3>Click here to do the adjustment</h3>
<input type="button" name="cmdAdjustment" value="Adjustment">
</center>
<BR><BR><BR>
<!-- -------- Label Control to Display Status ---------------------->
<OBJECT
classid="clsid:99B42120-6EC7-11CF-A6C7-00AA00A47DD2"
id=lblStatus
width=750
height=16
align=middle
hspace=5
vspace=0
border=0
>
<param name="angle" value="0" >
<param name="alignment" value="3" >
<param name="BackStyle" value="0" >
<param name="caption" value="">
<param name="FontName" value="Arial">
<param name="FontSize" value="16">
<param name="FontBold" value="1">
</OBJECT>
<HR>
<center>
<address>
1996
By Ken and Jasper's Wiseone Engineering and Tim Associates<br>
3100 Ginnyemmaben Lane
Lisakaylaryanville, Mi 11111
</address>
</center>
</BODY>
</HTML>
The code is not secure in this case. Notice how easy it is to spot the top-secret constants in this code (even if a comment didn't call attention to them). The company's proprietary knowledge is there for everyone-including competitors-to view. Anyone who looks at your page can view your script by selecting the View Source option of her browser. This is quite different from the programs generated by most sophisticated languages. Usually, traditional programs are distributed as files of bytes to be executed or interpreted, and you cannot read them easily, if at all. The ease of viewing a Web page source is generally a nice feature because it helps developers quickly pick up new techniques and learn from one another's pages. However, this stops feeling like a nice feature as soon as you complete your first Web page that you want to share with the world without sharing the script source code behind it.
How can you protect this code? Your options are rather limited
today but are rapidly expanding. As long as your Web page has
standard VBScript code, it's there for the viewing and the taking.
Legal or ethical considerations might discourage people from taking
a competitor's code, but from a strictly technical aspect, anyone
who can view your page in the browser also has the capability
to view and lift the code in your page. The still-evolving network
etiquette and attitudes of users are oriented toward very open
sharing. Because the Internet and World Wide Web began and prospered
on the concept of openness, a widespread attitude is that the
source code of any page is fair game to view, investigate, and
even incorporate.
Note |
The software development industry and one's personal satisfaction in being a part of it will remain strongest if all programmers seek to maintain the highest ethical standards in crafting their programs. Be sure to pay careful attention to issues and seek permission from other page owners before incorporating any pieces of programming from another Web page into your own. (This guideline should be coupled with common sense. It does not apply to intentional sample code, of course. Help yourself freely to any of the code you find in these sample pages-you don't have to e-mail us to ask if you can use it in your solutions!) |
Better solutions for protecting VBScript do exist. One alternative is to move your code to an ActiveX control or a Java applet object and distribute that with your page. The objects are distributed as files of bytes to the client computer rather than as easily read text. Of course, this is not always a very attractive option because it can involve a fair amount of work. However, it is expected that the next version of the regular Visual Basic product will allow generation of ActiveX controls, so at least it will be easier to make this migration. Listing 21.4 shows a modified page after the proprietary code of Listing 21.3 was replaced by a customized ActiveX control.
Listing 21.4. A page where the proprietary code has been moved to an ActiveX control.
<HTML>
<HEAD>
<TITLE>Ken and Jasper's WiseOne Engineering</TITLE>
<H1>
<A HREF="http://w3.softlookup.com"><IMG ALIGN=BOTTOM SRC="wiseone.jpg" BORDER=2></A>
<EM>Ken and Jasper's WiseOne Engineering</EM>
</h1>
<HR>
</HEAD>
<EM>Enter the reading on Gadget 1 and we'll give you the adjustment factor</EM>
<SCRIPT language="VBS">
<!--
sub cmdAdjustment_OnClick
' Calculate the adjustment factor based on Gadget 1 reading
dim dblTemp1 ' Hold intermediate result
' Use our custom-made ActiveX control to get the adjustment factor
ctlOurControl.GadgetReading = txtGadget.value
dblTemp1 = ctlOurControl.GetAdjustment
lblStatus.Caption = "The adjustment factor is " & str(dblTemp1)
end sub
-->
</script>
<center>
Enter gadget 1 value here:<input name="txtGadget1">
<h3>Click here to do the adjustment</h3>
<input type="button" name="cmdAdjustment" value="Adjustment">
</center>
<BR><BR><BR>
<!-- ------------ Label Control to Display Status ---------------------->
<OBJECT
classid="clsid:99B42120-6EC7-11CF-A6C7-00AA00A47DD2"
id=lblStatus
width=750
height=16
align=middle
hspace=5
vspace=0
border=0
>
<param name="angle" value="0" >
<param name="alignment" value="3" >
<param name="BackStyle" value="0" >
<param name="caption" value="">
<param name="FontName" value="Arial">
<param name="FontSize" value="16">
<param name="FontBold" value="1">
</OBJECT>
<!-- -------- Custom Control to Calculate Adjustment ------------------------>
<OBJECT
classid="clsid:99B42120-6EC7-11CF-A6C7-00AA00A47DD2"
id=ctlOurControl
width=750
height=16
align=middle
hspace=5
vspace=0
border=0
>
<param name="Gadget1" value="20" >
</OBJECT>
<HR>
<center>
<address>
1996
By Ken and Jasper's Wiseone Engineering and Tim Associates<br>
3100 Ginnyemmaben Lane
Lisakaylaryanville, Mi 11111
</address>
</center>
</BODY>
</HTML>
If you compare Listing 21.3 and Listing 21.4, the risk of including proprietary code is clear. When it's in the script, it's there for all to see. When it's moved to an ActiveX control, others might be able to use the control to get the same results from your page, but they cannot view the source code itself. Moving key code to a control also facilitates reusability. If you've used the control in 20 pages and you have to change a constant, you can just update one control. If you used direct VBScript code without a control, you'd need to make a change in 20 places. For key issues such as security and maintainability, you might sometimes decide to move part of your script solutions to controls. Generally speaking, though, the flexibility and quick development of coding in VBScript probably justify keeping as much code as possible at the script level.
You can also use the Layout control described on Day 18, "Advanced User Interface and Browser Object Techniques," but then your code will not be as easily viewable. When the user selects View | Source from the browser, he will see the page that includes the Layout control, not the code defined within the Layout Editor. Because this technology is still in early beta, this may be handled differently on subsequent releases. There is a long-term solution that is likely to be even better: An evolving standard would place a tag at the top of the page that indicates, among other things, whether the source of a page can be viewed. If it is designated as private, the browser would not display the source code behind it even when the user selects View | Source. There are always ways to defeat security, however. These technologies are perhaps more prone to interception than having code in a control, and you might not want to have your company fortune depend on them.
Fortunately, the vast majority of VBScript writers are probably not too concerned with these source code privacy issues. Most code makes pages active and glues together the operation of components, but the code doesn't often have corporate knowledge embedded within the script. However, VBScript is so quick and easy to use that you might find a greater cumulative body of knowledge reflected in the collective scripts of all your Web pages. Be aware that wherever your script visits, its source code visits as well!
Today's lesson addresses the robustness and safety of HTML-related scripts written in VBScript. The browser will detect any long-running scripts that might be stuck in a loop, notify the user, and halt the script. The language itself provides few means to get into trouble. VBScript has no file I/O, no clipboard control, no memory management, and no memory pointers for this reason. This makes it a safer language that is highly unlikely to introduce errors affecting other programs. Viruses pose another risk to the integrity of the user's browser environment. The same language restrictions that apply to VBScript to reduce the likelihood of accidental errors also reduce the possibility of viruses.
The only potential for serious problems with a script is through the components it integrates. You can download components along with a page and the script that uses them from a Web server. Because components are written in languages other than VBScript, all safety bets are off. However, components can also be certified. A certification means that the control has been provided with a digital signature that uniquely identifies it across the industry. You can use certified controls with a high degree of confidence that you are safe from risk.
Q | What happens when VBScript gets into an endless loop? Will the script keep running until the browser runs out of memory? |
A | No. The browser will detect that the script has been running for an inordinate period of time and present you with a message box to cancel the script. |
Q | If you need to communicate with another task in the Windows environment from VBScript, is it better to use a dynamic link library call, share information through the clipboard, perform simple file I/O, or redesign your script? |
A | The first three approaches will not work because none of the technologies mentioned are supported under VBScript. The best bet is to rethink the design of the script. Perhaps you can merge the tasks that must communicate into one page. Maybe server-side communication through submitting data to a server program you write is a better approach. In any case, VBScript will not support these communication activities directly. |
Write your own endless loop program for experimental purposes as described earlier today. Because this is a script where you have intentionally introduced a problem, make sure not to distribute it on your server. Even though you don't expect any other side effects, practice safe computing. Make sure all other programs of importance are closed before you do these tests.
Load the page with this script into the browser. Start the loop and observe how long it takes the browser to detect the long-running script, notify you, and halt it. Do you think this behavior could interrupt any correctly functioning scripts? Write a large calculation loop (that is not endless) and time it. Observe whether it comes in under the browser "endless activity" detection time. Most practical applications should complete their work well under this time line.
Try to use other programs at the same time the code is running. See if you observe any noticeable effect on the performance of those other applications. Generally, you won't see much impact, but certain operations can cause a ripple. For example, a script that heavily stresses memory could make a noticeable impact. Extensive allocation of very large strings through repeated string assignments to grow the string longer and longer is one such case.
Note |
Refer to Appendix C, "Answers to Quiz Questions," for the answers to these questions. |