X-Internet Security - An Introduction

Date: 30-Jan-2002

Introduction

The REBOL programming language makes X-Internet a reality but there a a few risks to think about when planing for an X-Internet implementation.

This introductory article presents a few security issues related to executing content received remotely. It is especially relevent when providing service such as that enabled by Rugby or indeed any other web service software.

For this article I'll often refer to Rugby as an example. This does not mean Rugby is less secure than other software, just that it is convenient example when talking about REBOL.

The reality

Unfortunately some unscrupulous people will attempt to find and exploit any security weaknesses in your systems. For this reason you must learn how to avoid creating such weaknesses.

Security is a large and complex topic - too big to cover here. Here I just want to draw your attention to a some security issues and a couple of things you can do to manage the risks.

Opening a port

These days just opening a port on your machine visible on the internet is enough to have the baddies sniffing around your machine for a way in.

Opening a port occurs when for example you issue the SERVE command of Rugby. It also occurs when you run any type of "listening" service such as a web server or sometimes even a chat client.

Vulnerabilities will likely always exist in software. They might exist at the operating system level, a user program, or in application libraries. Software is complex, bugs can live in any layer of software. In the context of Rugby this means, there could be so far unknown security weaknesses in the programs you publish with Rugby, in Rugby itself, in the REBOL interpreter, etc.

Publishing a Rugby service or any other web service, means knowing that you are taking the risk of exposing such vulnerabilities to the world, and there's plenty of people in the world looking to exploit such vulnerabilties. Sobering is it not? For this reason publishing web services etc on a machine that either contains confidential information or has access to such information carries high risks. Yet this is the way the world is moving so be prepared to learn more than you every wanted to know about such vulnerabilities.

Also note that some internet service providers explicitly prohibit providing internet facing server ports. If you do open a port on an ISP with this policy in place, you might find yourself without an internet service in short order.

Untrusted code

Probably first off, unthinkingly using other peoples scripts is a recipe for problems. Exposing functions defined in these scripts as Rugby services or other types of web services is not a good idea at all.

I hope some of the following sections will show why this is so.

LOAD

It is just too easy to unwittingly leave open your system to attack. One likely cause for opening a security weakness is not understanding the behaviour of the code you are publishing well enough.

Here's one example:

LOAD

Many people did not realise that in earlier versions of REBOL, LOAD evaluates (to an extent) the value it is given. LOAD by default would evaluate any REBOL header it finds in the value you are loading. People normally only put simple values in the header of their REBOL scripts, but actually you could put any sort of function in there.

With newer versions of REBOL this security weakness has been removed and LOAD does not evaluate the header any longer.

DO and related

It might seem cool, to process arbitrary input as executable code but it is not. I hope it obvious, but serving up DO as an unprotected internet enabled web service is really a very bad idea.

What is not so obvious is that the logic of DO exists in many REBOL functions. Here are some examples:

Don't assume that is a complete list.

BIND and dialects

Dialecting is a good thing. It is part of REBOL's grand future. There are traps though in how dialects are implemented.

Imaging some script/data in the form of an unevaluated block, received as an request via Rugby or perhaps delivered as the body of an email. You have a program ready and willing to accept this input and your program expects that the script/data conforms to specific dialect.

How do you bind your program functions to the script/data - BIND? Oops, wait a moment.

BIND is powerful and could make some dialects as simple as evaluating a block that has been bound to a specific context. But what are the effects? How do you know that the input does not contain some malicious code or data?

This problem is really part of a general problem in how to deal with input. In the "x-internet" age input must always be considered in some way executable.

Validate your input

A more secure way to deal with the problem of input containing unexpected behaviour is to define exactly what you are expecting, and then to check that the input you receive conforms to the rules you defined. To do this use PARSE.

By using PARSE you can verify that the input is acceptable to process further and contains no un-expected/un-welcome executable code.

PARSE by itself is not a silver bullet though. You need to carefully check your parse rules to ensure that you do not accidently allow executable code. This can only meaningfully be done by considering how the input will be used in your function.

BTW, I have not seen any XML related information on this problem. Could be because my readings are too limited or (more likely?) perhaps the XML dialects don't have the problem because they are so limited. As XML dialects become more and more powerful I'd expect validating parsers to be mandatory for security in that arena too.

So before you unleash your wonderful new web service on the world ensure you have defined the grammar of your input. If the grammar is simple (only ever a string) simple testing in your web service should suffice. If the grammar is more sophisticated you should consider PARSE as your gatekeeper.

In a way your grammar becomes a contract - your function should only supply service if the input it is presented with conforms to the grammar.

Using SECURE

Another measure you can implement is to learn and apply the SECURE function. This function configures how the REBOL interpreter will handle access to network and disk resources. SECURE ensures that the REBOL interpreter becomes an active part of you security plan.

To use SECURE effectively, you should adopt the the old security policy from the era of mainframes and mini-computers - only grant those permissions actually required to achieve the task you want performed.

This requires analysing the functions you will be serving up for the minimum permission required for their successful completion. A good idea would be to then document these requirements for future reference.

Having performed this security analysis you are better equipped to set SECURE with confidence.

Other security measures and defaults

If you are making a web service using Rugby or some other software, you might find that the software contains extra security features.

For example, Rugby offers encrypted communications and the ability to restrict connections to specific ip addresses.

So check out the features that the software you use offers. It is important that you do it and pay particular attention to what the default settings are. Some software notably Microsoft's has been notorious in the past for having default security settings equivalent to "wide open".

Conclusion

There are lots of complicated security issues. The best defense is to learn as much as you can about what the problems are and then to devise and implement a plan that minimises your exposure to the risks.