In my server log of my web server, I've noticed a hacker trying this:
https://[domain name]/index.action?action:${%23a%3d(new%20java.lang.processbuilder(new%20java.lang.string[]{'sh','-c','id'})).start(),%23b%3d%23a.getinputstream(),%23c%3dnew%20java.io.inputstreamreader(%23b),%23d%3dnew%20java.io.bufferedreader(%23c),%23e%3dnew%20char[50000],%23d.read(%23e),%23matt%3d%23context.get(%27com.opensymphony.xwork2.dispatcher.httpservletresponse%27),%23matt.getwriter().println(%23e),%23matt.getwriter().flush(),%23matt.getwriter().close()}
Which URL decodes to this:
https://[domain name]/index.action?action:${#a=(new java.lang.processbuilder(new java.lang.string[]{'sh','-c','id'})).start(),#b=#a.getinputstream(),#c=new java.io.inputstreamreader(#b),#d=new java.io.bufferedreader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.httpservletresponse'),#matt.getwriter().println(#e),#matt.getwriter().flush(),#matt.getwriter().close()}
My server doesn't use Java but I'm trying to understand what this hacker is trying to do here and why this could be a vulnerability. After all, I'm not just a developer but also need to know about how to protect a server, including servers not set up by me.
Code seems to start a new process and then tries to read data from the input stream. I'm assuming this is the input stream of the current web session.
As this attack is also tried over /login.action and various other URL's and different Java code, I am considering it to be potential dangerous. But I can't explain why this is dangerous.
The specific domain is under attack right now as the hacker tries to see if it's running WordPress or Magenta or other known systems and also tries several different attacks.
But what matters is this: the domain is currently under development and the owner still has to decide which development tools will be used. The choices are between Java and ASP-NET so is this attack dangerous if he chooses to pick Java?
It's trying to exploit a RCE vulnerability in Struts 2, I think this one. A bad one, Freemarker would execute any code inside ${} tags.
The Freemarker code starts a process to execute id to see if the server is running as root, giving full access to the box. Even a vulnerable Struts version might not be too bad here, since the attacker might not be interested unless you were root.
The attacker's program has a lot of these old vulnerabilities that would work on very unsafe servers, but even simple admin protocol will protect against these amateur attacks. You would only be vulnerable when running as root, using an old version of a software, opening up your db server to the internet with a weak or default password, etc.
Regardless of the technology you choose, there will be security issues and you need to follow the CVEs. For example a modern Java framework like Spring has a few, but remote code execution is quite rare, and that's what those attack programs look for.
Related
For various reasons, I have a Java application that needs to be able to detect which user is running it. I've seen a few suggestions that address the issue, but none are fully satisfactory.
Some suggest using the system property user.name, but this is not reliable as it can be spoofed in at least 2 ways (changing the value of the environment variable that the system looks to, or starting the program with an override value via a -Duser.name option).
Another option is to use the classes in the com.sun.security.auth.module package, but the Java Ruling Class is very clear on why this is not a good idea (see for example this web page).
This seems like it's a sufficiently valuable capability that there should be a way to do this in Java that is supported, but I haven't been able to find it. Any suggestions?
For various reasons, I have a Java application that needs to be able to detect which user is running it.
Bad luck, on modern, but especially on unix/posix systems, it's up to the user to define which libraries get loaded when your java gets loaded. This can include a library that intercepts call to the C runtime (libc) that checks user names.
Not to mention that user namespaces are a common feature on multiple OSes, which allow any unprivileged user to set arbitrary user names. This is by design.
In short: the system is the user's. You can't use whatever that system says to authenticate against any other system. This is a truth as old as authentication systems: you need an anchor of trust, and on a system that you don't control, such an anchor is not yours to get – unless you have things like TPM or FIDO/cryptographic smartcard readers.
You will have to find a fundamentally different security mechanism. You can never trust a user's system if you've got anything to hide from them. Think about this: your user might very well boot a virtual machine in which they control everything; they very much copy the original machine's hard drive byte for byte, but they change their user name in that VM to that of someone else. Game over for your system.
I feel like I need to repeat that: You cannot trust a user's system. If your security depends on your software doing actually what is expected of it (e.g. validating a password, or checking anything else, and if successful, sending a packet somewhere), then a simple debugger can just jump over any security measure and execute the code you didn't mean to be executed in a case of non-authentication. You, as a developer, know how to use a debugger. Any user could use a debugger, too.
Read an interesting article about securing XP,http://www.expertreviews.co.uk/software/1304965/when-windows-xp-support-ends-this-is-how-you-secure-your-pc-and-save-all-updates.
With these suggestions is building apps for the marketplace ok with this setup to get by w/o headaches.
Here are my noob thoughts and question:
Just learning to code. Do you think I could run a limited setup to learn languages Java and C# while still being able to use my desktop for deployment of apps? A limited login as described only allows certain actions which I believe is different than a typical guest account. I wonder if my comp could still act as a server to retrieve data requested by users away from my machine. I figure I would need to be logged in as an admin to make some changes but, would hope that tasking processes or jobs could still be done.
I guess my question is, do users of a program you made need access to a local machine for some functions and would that work in limited?
I would like to get something portable and keep my desktop for business to be economical and not run the risk of logging on to an unsecure Wi-Fi with a portable that has business use. Ideally, I'd pony up for newer, better. I'm just learning though.
Do users of a program you made need access to a local machine for some functions and would that work in limited.
No. If you need some sort of server backend for your app a personal computer would be a bad choice for several reasons:
It would need to be available at all times: you can't frequently turn it off or restart.
It would require the same ip address.
It could consume a good amount of you're computer's resources, making it difficult to use for personal use
Instead you should probably be using a dedicated server or a cloud based solution, of which several offer free usage tiers.
I have an (unsigned) applet that let you draw a logic circuit and test it on-screen (a bit like Electronics Workbench), and it then serializes the circuit (the internal form, not the visual representations) and sends it to the server where a bunch of automated tests are run and a performance report is produced. This is a small but crucial part of a much larger web app.
However, the latest Java plug-in now says this:
Running unsigned applications like this will be blocked in a future release because it is potentially unsafe and a security risk.
Now, self-signing it will still apparently work (for now), but then the code runs OUTSIDE the sandbox, which strikes me as a stupid way to do things, even though my code is of course completely bug-free! (Can I interest you in buying a bridge?) Reading further on the Oracle website I see this:
The platform will not deny the execution of Java applications... Future update releases may include additional changes to restrict unsafe behaviors like unsigned and self-signed applications."
(Which sounds like it means "Future updates will deny the execution of Java applications" -- unless you pay money to Thwaite or Verisign on a regular basis AND expose users to code running outside a sandbox.)
They also say
"Even the smallest changes in user experience are sometimes troublesome".
(No kidding.)
"We have considered how changes affect user experience. Given the current climate around Java security in the browser, code signing is a valuable security control for protecting Java users."
Well, I don't see how I can continue using Java under these circumstances. The goalposts have been moved (again), and now I'm looking for a different football team... or more precisely, I'm looking for an alternative technology that will let me continue to do what I do now: drag & drop circuit elements, create connections by dragging between input and outputs or other connections, and finally take the internal form of the diagram and squirt it to the server in a form which can be decoded and exercised, preferably by exactly the same code that created the diagram to avoid versioning headaches. And something which is safe, which can't trash the local filesystem or whatever just because I've signed it.
Can anyone suggest where I should be looking next, now that Oracle has made my life a nightmare?
(Which sounds like it means "Future updates will deny the execution of Java applications" -- unless you pay money to Thwaite or Verisign on a regular basis AND expose users to code running outside a sandbox.)
A signed applet launched using JNLP can still be sand-boxed.
But if you really wish to avoid it..
I think what you described can be provided using JavaScript for the logic and and an HTML 5 canvas for the rendering.
I would avoid Flash, since it is also susceptible to security bugs. It would be like digging yourself a brand new hole to get trapped in.
I can't comment on what you found about applets, since I never wrote one.
If you want to move away from them, maybe your only option (while staying with Java) is go for web applcations, where the code is most on server-side and you interact with your software directly in your browser. On the client-side javascript (and js-related libraries like JQuery) is used, though I can't elaborate about it more since I'm don't know the Java EE stack very well yet.
I'm not sure if you can get 100% the same user experience as you currently have in your applet, above all for an electronics application. But it may offer the highest code-reuse of most of your Java classes.
I've used Vaadin, it's a framework that moves almost all your coding to the server-side (you only need to code the client side if you want to create addons). I've heard about Zk too, but I've never used it, so I can't say anything about it.
You can still run unsigned java applets in your web pages if you block your Java plugin in the browser to the version SE 7 U11 (jre-7u11-windows-i586.exe) Of course you will have to block automatic Java update with "C:\Program Files (x86)\Java\jre7\bin\javacpl.exe"
I hop you can survive for a while this way, before you find an alternative to JAva applet.
In HTML5 the tag to call an apllet is now object and the syntax is a bit different:
<object codetype="application/java"
classid="yourApplet.class"
codebase="http://www.yourserver ..."
archive="YourJarFile.jar"
width="x" height="y">
<param name="paramName1" value="paramValue1"/>
<param name="paramNamei" value="paramValuei"/>
</object>
I am writing a small webserver for my house to play around with a few java API's I want to know better. This web server will eventually hold personal files and pictures.
I did not feel like setting up an LDAP server for authentication and was wondering how bad would it be if i just had the java code check it directly?
As long as you take proper precautions not to distribute or publish your source code, having a hardcoded password is most certainly safer than having a network service validate it. There are two problems, however:
Keeping your source code secret may not be too hard, but you can easily forget that you hardcoded the password in the future an become careless about the source. You may want to copy it to a friend, or publish it on github.
Having the password hardcoded means that someone that compromises your code may easily learn the password. A tried-and-true network authentication solution will not be ridden with vulnerabilities - your code almost certainly will.
A potential alternative you should consider is to keep a plain text file with the password, and read it as necessary. It mitigates (but doesn't eliminate) these two issues, and will also allow for a bit more security if your OS supports the proper file permissions and user privilege separation.
As always, avoid using a password repeatedly for different services. Since you'll have untested code facing the internet, remember to implement proper OS-level counter-measures.
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.