The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Disarming denial-of-service attacks in code sniplets

Hi,

As most of you know, Java applets suffer from a denial-of-service exploit. That is, Java's SecurityManager does not prevent one from consuming excessive resources (in the form of memory or CPU).

I have a strong interest in solving this problem because my own use-case suffers from the same exploit. The only approach that comes to mind is to use a bytecode analyzer (such as http://asm.objectweb.org/) to scan the code before attempting to execute it. Perhaps one could estimate cpu or memory consumption across a code block and if this surpasses a threshold fail the code with an error.

I would love to hear your ideas on the matter. Is there an easier/better approach?

Thank you :)
Gili Tzabari Send private email
Thursday, December 27, 2007
 
 
I found an interesting thesis on the matter of securing mobile code here: http://www.mcs.vuw.ac.nz/~ian/cgi-bin/wiki.pl?PhDthesis

The thesis focuses on injecting instrumentation code into the bytecode and throwing exceptions at runtime if a security violation occurs. They argue this is more flexible than static bytecode analysis.

Fair enough, but it isn't clear to me what code I could inject into the bytecode to measure cpu or memory usage in a non-intrusive manner. I could possibly measure memory usage by intercepting all "new" calls and estimating the heap allocated by the instrumented code but it's not clear to me what I could do for cpu time. I could always inject code that says "If the instrumented code has been executing longer than X ms then cause it to exit" but that doesn't seem to be the right metric to be measuring as it's dependent on runtime load and doesn't check for actual malicious behavior.
Gili Tzabari Send private email
Thursday, December 27, 2007
 
 
Ultimately, estimating the amount of storage required by any piece of code is equivalent to the halting problem, ie., it's impossible to determine generally via an algorithm.  However, instrumentation would allow you to monitor memory in use at any given point and throw an OutOfMemoryError if more memory is requested than should be allowed.

In fact, that's exactly what happens, at least with the Sun JVM for Java applets: memory allocation fails if the user-configured memory limit is hit and no memory can be freed via garbage collection.  For compute time, the problem is somewhat harder: how do you decide between an abusively CPU time sink and a compute-bound but useful algorithm?

(The limit is configured from the Java control panel, under Windows or OS X, as a set of parameters to pass to the JVM; have a look at 'java -X' for some idea of how to use them and what the defaults are.)
Angstrom Send private email
Thursday, December 27, 2007
 
 
Angstrom,

I am not so concerned with picking a good threshold so much as being able to measure CPU usage in the first place :) I agree that memory usage is (seemingly) trivial to compute but I wonder what one can do for CPU time...?
Gili Send private email
Friday, December 28, 2007
 
 
Unless you are worried about power consumption, I would prevent excessive CPU consumption by running the applet's thread at a lower priority.
DAH
Friday, December 28, 2007
 
 
Running a thread at lower priority does not prevent a DoS attack.

If there are no other eligible threads to be run (all happen to be blocked on I/O, etc), then the lower priority thread will get a full CPU time slice (aka 100% CPU)
xampl Send private email
Friday, December 28, 2007
 
 
I agree running at lower priority does not help. Aside from not preventing a DoS attack as xampl said it also forces me to run legitimate threads at lower priority.

Ideally I want to measure cpu usage dynamically (at runtime) but if that isn't possible I could always analyze the code statically at load-time and recursively assign a "weight" to each block of code (summing up the number of instructions that will get executed in the body) and apply a threshold to that.

One thing isn't clear to me: why does the author of the thesis paper seem to imply that runtime instrumentation is better than static (load-time) bytecode analysis? That is, why am I better off injecting bytecode that counts memory or cpu usage at runtime as opposed to trying to predict this value statically at load-time? Is the latter simply impossible?
Gili Send private email
Saturday, December 29, 2007
 
 
Static analysis of code for complex properties like "CPU time" and "performance" is very likely equivalent to the halting problem.  If it is, then any algorithm to exactly predict the property is not guaranteed to complete in finite time, never mind reasonable time -- which is the exact problem you're trying to avoid[0].  On the other hand, measuring time *actually used* is very easy and 100% reliable if done correctly.

[0] Using a heuristic approach is a fancy way of being wrong sometimes, but it can help.
Angstrom Send private email
Wednesday, January 02, 2008
 
 
If there are no other eligible threads to be run, then the lower priority thread isn't denying service to anyone, even if it takes up 100% of CPU time.

If there are architectural reasons why you can't run applets at a lower priority than your other code, then yes, that is a problem.
DAH
Wednesday, January 02, 2008
 
 
Angstrom,

How would you measure CPU usage in runtime? As far as I can tell only the OS can do that sort of thing. I'm not sure how one would do it in Java code.
Gili Send private email
Saturday, January 05, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz