FOBs, those pesky little files that we all take for granted, import into our databases, and live happily ever after. After you read this post, you’ll handle FOB files very, very carefully.
Why is that? Well, if you haven’t already, then read this post first: From C/AL to executable: how NAV runs your C/AL code
Good, now that we are on the same page, let me explain why you must never, ever, ever trust a FOB file.
If you are simply curious, then download this FOB here: HelloWorld.fob.
Good, now go to your development environment, import it, and then find codeunit 87654 Hello, World!
Good, now design this codeunit and take a look at what it contains:
Not much, eh?
Now, close the designer, make sure not to save the object, simply close and cancel saving. It is crucial at this stage not to save or compile this object.
Good, now run this object.
Starts off well, but then quickly develops into quite a dialog between you and some ghosts that come from who knows where.
See? That’s why you must never, ever trust FOB.
Now, compile that codeunit.
Good, now run it again. And it shows only a single message, as expected.
What’s going on here? It’s simple. I have created a codeunit which has more C/AL code than you see in your C/AL editor. Then, I have exported the content of the User Code field from Object Metadata table into a C# file. Then, I have produced the codeunit with only a single MESSAGE that shows “Hello, World!”. Then, I have imported the C# file I exported earlier into the same record of the Object Metadata table.
What I have at this point is an object with a mismatch between C# and C/AL. And as I said, once the object is marked as compiled, C/AL is ignored by everything, and it’s C# that matters. If I export the FOB now, and you import that FOB, you get exactly the same situation: C/AL code contains something, which is completely irrelevant, while C# code contains anything that the FOB author cared about injecting in your object. And know what? If you don’t compile the imported objects, NAV will simply use the C# that it finds in the User Code field. And that’s where all those messages and confirmation dialogs in this FOB you downloaded come from.
Now, I am not saying this to give you an idea how to inject your stuff into FOB files that you ship around. I am writing this to warn you about dangers that FOB files bring with themselves and that you adopt a practice of not using FOB files for transferring the data around.
Instead, you should use text files. A text file contains only C/AL code, and after importing you must compile the imported objects first to generate the C# code.
However, a better approach is to simply ship delta files. You can use PowerShell to create them, and to import them, and then to remove the customizations if you don’t need them. Just like Waldo explains in his fantastic blog post: Apply-NAVDelta to add and remove customizations.
FOB, not good. TXT, good. DELTA, the best.
This Post Has 17 Comments
Pingback: C# Injection: Don’t trust FOB - Vjeko.com - Dynamics NAV Users - DUG
Pingback: C# Injection: Don’t trust FOB - Microsoft Dynamics NAV Community
Hi Vjeko, when I try to import the modified c# text file I get an error message. The blob is compressed so import through sql is not straightforward. How did you import the c# file on object Metadata?
You do it through C/AL. Just import BLOB through an OutStream.
That’s what I am doing but I get a permission error
Hm, might be a license thing. My license apparently allows me to do that, and I am pretty sure there are other licenses out there permitting it.
What will be the effect on recompile importerted fobs? Will this prevent code injection?
Yes, of course. The article even says as much.
Hi Vjeko, I think I figured it out myself, if you write in c/al with real code, compile and then import a simplified version of c/Al code in object Metadata you get what you created but you can’t inject directly in c# unless you do it though sql I guess
Well, you can export C#, modify it outside, then import it. Whichever way yo do it, it’s extremely unsafe to handle FOBs.
Using .txt files implies losing the control on the objects that are going to be imported (no possibility to skip), therefore requires a preliminary check in the target database.
A bit risky, you don’t think?
No, I don’t quite agree. It all has to do with how you manage your environments. I think that the days in which we are simply importing objects long gone. We should all start applying source control and application lifecycle management principles in NAV, and then we would not have to worry about things like preliminary checks or similar. If we only have one development environment and are moving from there to production, then of course we will have problems no matter which approach we use.
Pingback: Weekly Digest - Start Week with some Great Discussion about NAV. - Microsoft Dynamics NAV Community
Pingback: ArcherPoint Dynamics Developer Digest - vol 116 - Microsoft Dynamics NAV Community
some years ago tools for doing this were made for “protecting the C/AL source-code”, so what is the news here? this behavior is exactly the same since… ever, except that you do not need any binary tool anymore.
There is no news here. Not all blog posts need to be news 🙂 I’ve posted this because many people are not aware of this, and to educate people of how FOB works, and also how Object and Object Metadata tables work. That’s the point.