Granular Code Security Underused
In my opinion, the idea of granular code security is one of the least-used features of modern runtime environment. By granular security control, I mean the ability of a runtime to give some access to a semi-trusted program, while at the same time denying access to other sensitive areas.Applet
Applet is probably the type of programs that uses granular code security the most, as of now. Some applets are not trusted at all, so they have no access to most of the Internet, the file system, and have to live with an ugly label under every window they create. Some applets are more trusted, and the browser will ask you for permission to let the applet do various things, such as accessing your document folder or connecting to another site.Semi-Trusted Local Application
A good example of semi-trusted program is Java Web Start applications. Inside the JNLP (Java Network Launch Protocol), there are provision to grant a software with a flexible set of permissions, such that, as an example, a word processor can access your document folders, but would not be allow to connect to another site (and potentially sending your sensitive document to that site). Another example would be a chat client that needs access to the network, but is not allowed to touch any of your files.Sadly, while there are provisions for granular security control, it is not currently implemented in Java Web Start. This is somewhat of a shame, as practically all Java programs can (and in my opinion, should) be packaged as Web Start programs.
Servlet
This is probably the most interesting use of granular security. I was attending a presentation on web application security a few months ago, and the presenter mentioned that one of the problem with insecure web application is that they are already configured with access to critical system resources, such as database or system files, so a compromised web application frontend can provide the attacker with direct access to sensitive data.The presentation got me thinking about applying granular code security to server side application. Currently, the J2EE web application deployment descriptor has options for specifying security contraints for who has access to servlet, but says nothing about what the servlet can access. What if, instead of giving a web application full access to the database, we can specify that a particular servlet only has access to certain database tables? For example, a ViewProductServlet may need access to the Product and Pricing tables, but it should not be accessing the CustomerCreditCard table. Similarly, a ProcessOrderServlet may need access to the ordering database, but it shouldn't be allowed to connect to the corporate LDAP directory.
(For those who think that servlet are uncompromisable because Java code are immute to buffer overflow, I have one word for you: SQL injection - OK, two words.)
As an example, inside the web.xml configuration, we can have the following,
{CODE()}
...
ViewOrderServlet
com.oaktop.webapp.ViewOrderServlet
...
jdbc:postgresql://catalogdatabase, readonly=true
ldap://corporate
file://etc/passwd
...
...
{CODE}
By addition a declaration of security contraints to the servlet (and other server side components), we create another onion layer for the security strategy of Defense in Depth. No longer would a compromise on your web application exposes your entire network - and attack can inject an SQL into a servlet successfully, but still won't have access to anything of value (besides finding out the prices for a few books).
This seems to me an interesting use of granular code security (and unusual, as I haven't seen this anywhere else).
P.S. My discussion of granular code security applies to .Net as well. Like Java, .Net also has granular security.
Visual Display of Application Trust Level
I was reading 'Trusted displays' suggested as online security boost, and that got me thinking about the issue of how to identify a trusted application on a user's desktop (The article actually is minimally related to my idea - I made the connection of "trusted" and "display" myself).For example, see enough pop-up windows, and you notice some that tries to minick the Windows XP window, with a "Warning: You computer may not be optimized" and a realistic window that is designed to look just like a regular Windows XP window. In the HTML, the designer of these deceptive web page tries to specify that new browser window should be borderless, so that it looks just like a regular window. From what I know, current browsers no longer allow completely borderless new window; they always draw the title bar "Page Title - Microsoft Internet Explorer," so that the user can now tell that this is a web page, instead of what appears to be a genuine window.
While this problem seems to be solved for malicious web pages, it doesn't address the emerging category of semi-trusted local application. As an example, let's look at Java applets. If an applet creates a new Window, the Java runtime automatically creates a status bar that says "Warning: applet window" ( example). Now, an applet is (mostly) either trusted or untrusted, so that is not too much of a concern. However, what about a Java Web Start application? The web start application launch file has provisions (though not currently implemented) for semi-trusted application. That is, the Web Start application can be somewhat trusted yet not fully trusted. This means that the program can be trusted on some aspects (e.g. access to the network), but not trusted on other aspects (e.g. writing to the system folder). As a full-fledge Java application, the programmer may not want to have restriction on what they can do with the display of their windows. A good example being full-screen games. However, if the programs are given full control on the 2D screen, then they can make the window look like anything they want, including trusted screens (e.g. bank account log in page).
(I should also note that the same category applies to .Net programs too. I believe that, using assembly trust settings, .Net programs can also be partially trusted. I use Java Web Start because that is what I had experience with.)
Of course, the trade-off here is visual display flexibility versus security. Either the program has the right to draw the windows anyway it wants, including imitating a password screen, or that all less-than-fully-trusted windows will have to be tagged with an ugly "Warning: Applet Window" label.
I can think of two ways to mitigate the trade-off:
- Since the 2D display space is occupied by the program, a 3D desktop, such as the one from Project Looking Glass, can use the addition dimension to display trust information. For example, imagine spinning a program around, and seeing either a green trusted stamp, a yellow icon for a partially trusted application, or a red, flashing, warning icon for an applet window.
- Another way that does not require a 3D desktop is to have a special "X-ray" view of all the applications. For example, imagine a special button on the Windows task bar, which, when you click on it, color the trusted programs green, partially trusted programs yellow, and a browser window with red (for potentially unsafed Internet content).
Either way will allow the GUI designer to draw their windows anyway they want (on the traditional 2D screens), while giving the users an easy way to assess how much to trust each program.
Of course, there are many other ways to display the trust information, but some are less user friendly than others (e.g. you can display "trusted" attribute in the Windows Task Manager, but that requires the user to hit control-alt-delete or its equivalent).
Is Agile Suitable for Platform Design?
The emergence of Agile as a software development practice is gaining momentum. I wonder though, is Agile applicable to all types of software development?From the examples that I have seen, Agile is being used very successfully in business-facing development, where the project must closely align itself with the business process, and thus must adapt quickly in any change in business requirements.
What about platform design, protocol design, and standard design? Does it make sense to adapt the Agile approach in those projects? I see the W3C standards go through working drafts, then candidate recommendation, before finally becoming a "recommendation." All of these iterations happen in a matter of years. What about other platform products like Microsoft SharePoint, or even more basic, like the Win32 API or the J2SE API?
I hope to explore this issue further, in finding the right methodology for platform design, and whether Agile may be a good fit.
(In My Opinion) Misuse of Java's NullPointerException
In looking over so many people's Java code, one feature that strikes me odd was the use of java.lang.NullPointerException in place of more sensible choices, such as java.lang.IllegalArgumentException.Before I go on, let me put my opinion in context: This is probably one of those statements that are more of a matter of taste - how different people do things differently. However, in spite of this, I still think that there is a misuse here.
Allow me to explain. Frequently, Java programmers use the following code (excuse the poor Wiki formatting):
class Person {
Person(Person mom, Pesron dad) {
if(null == mom || null == dad) {
throw new NullPointerException();
}
}
}
Interestingly, most programmers like to use NullPointerException here, to indicate that the arguments should not be null. But, why not IllegalArgumentException? Sementically, NullPointerException is thrown by the Java virtual machine when it tries to dereference a null reference. Other code can throw it too when dereferencing a null reference. However, in this case, the exception is not just that the "pointers" are null - it is that the arguments are invalid.
Looking at the JavaDoc documentation for NullPointerException, it says:
"Thrown when an application attempts to use null in a case where an object is required. These include:
- Calling the instance method of a null object.
- Accessing or modifying the field of a null object.
- Taking the length of null as if it were an array.
- Accessing or modifying the slots of null as if it were an array.
- Throwing null as if it were a Throwable value.
Applications should throw instances of this class to indicate other illegal uses of the null object."
The documentation seems to mention only cases where the reference is treated as a traditional C pointer. Whereas, if we look at the documentation for IllegalArgumentException,
"Thrown to indicate that a method has been passed an illegal or inappropriate argument."
It would seem that this is a better exception to use than NullPointerException.
On a side note, many people wonder why the Java architects called this exception NullPointerException, instead of NullReferenceException. My guess is that they wanted to signify the explicit use of the null reference as a "pointer" and not just a general exception for null references.
As I mentioned earlier, this is probably just a matter of taste. But taste has significance too. If I am debugging a complex program, and I see a NullPointerException, it tells me very little about what the problem is. Is there a bug in the program that tried to call a method on a null object? Or is it some user code throwing the NullPointerException, when it really indicate that there are illegal arguments passed? Using the right exception can help enhance the program's readability and diagnosibilty. In that sense, this is more just a matter of taste.
Survival of the Fittest, Mischaracterization of Natural Selection, and Genetic Algorithms
One of the catch phase from Charles Darwin's theory of evolution, says that Natural Selection is "survival of the fittest." Well, actually, it says "probable survival of the fit enough." There are 2 misleading points suggested by the phase "survival of the fittest."First of all, Natural Selection has never been interested in finding the "fittest;" whatever individual is fit enough at the moment is fit enough.
You see, Natural Selection operates on a statistically level, so that, in general, in a population where there is mutation and selection pressure, the best traits tend to emerge. However, the adjective "best," in the statistical sense, really only means "good enough." It makes no sense to apply the word "best" to the individuals. For example, if there is an individual tiger in a population that is the "fittest" (whatever that means, the strongest tiger, fastest tiger, etc.), and if that tiger, while resting under a cliff, happens to get smashed by a falling rock, that "best individual" is forever lost. Natural Selection doesn't guarantee survival of the "fittest," only survival of the "good enough." Only on a statisically level, can we meaningfully talk about: "Overall, if tigers are under selection pressure, the fast-running gene/individuals will probably emerge."
Secondly, I use the word "probably" intentionally, because not only does Natural Selection doesn't guarantee survival of the "fittest," it also doesn't really "guarantee" at all. Take the dinosaurus as an example - you don't see "highly-evolved" dinosaurus walking around today. The entire dinosaurus population was under such a great selection pressure that they could not mutate fast enough (or probably not enough of those mutations made it; see the first point). Sometimes, you can't mutate fast enough, because you are fundamentally obsolete. The dinosaurus, as a form factor for species, simply did not work, and so they died off. No amount of mutation will change that (we are not talking about mutation that allows dinosaurus parents giving birth to a tiger - that doesn't happen).
The reason why people refer to "survival of the fittest" is probably a misunderstanding of context in which Natural Selection operates. I had the realization of this mischaracterization when I was looking at Genetic Algorithms for IFM. The observation of the parallel between Genetic Algorithm and Natural Selection brings the following 2 points about genetic algorithms,
- Genetic algorithms will not bring you the "best solution," for the most part, just like Natural Selection doesn't bring you the "fittest."
- Genetic algorithms may not return any useful results at all, if mutation doesn't happen fast enough.
The first point in the comparison says that you shouldn't expect GA to bring you the best solution. In fact, you should expect to always receive "suboptimal" results. Only on a whole, if properly implemented, can GA brings "good enough" solutions. The second point concerns the modelling of the problem. For a good genetic algorithm implementation, it is very important to model your "genes" (selection attributes), or else you won't have any meaningful population after the selection. If you model your implementation like the dinosaurus, your will not find any "good enough" solution population after the algorithm finishes.
(To be continued, elaborated, and orgaznied).
Comments