D365 Audit
Blog · 2026-10-01 · 5 min read

Risks of JavaScript in Dynamics 365

Form scripts are the part of a solution that ages fastest and is documented least. The typical problem patterns at a glance.

JavaScript is where legacy builds up fastest in Dynamics 365. A form script runs unnoticed for years, even after the API it uses has long been replaced. Only a platform update or a migration turns it into a problem.

The replaced programming interface

The most common pattern is access through "Xrm.Page". For years this object was the standard way to reach fields on a form. Since version 9 it counts as deprecated. The intended way is the execution context and "formContext".

"Xrm.Page" still works, and that is exactly the trap. There is currently no date on which the rewrite is forced, so it does not happen. If you still have scripts with this access today, you are postponing a task that will eventually have to be done under time pressure.

The same applies to the old object model from the 2011 era and to the endpoints for data access from that time. Both show up regularly in grown solutions.

Security-relevant patterns

Some constructs are problematic regardless of age.

  • "eval" and functional equivalents run arbitrary code. In a form script there is practically never a good reason for it.
  • Direct assignments to "innerHTML" write into the document without sanitizing. If data from records ends up there, that is an entry point for attacks.
  • Unencrypted calls to "http://" instead of "https://" transmit content in plain text.
  • Absolute URLs to your own environment break as soon as the solution moves to another environment. Relative paths are the right choice here.

The quieter problems

Some things are not a security topic, but they cost time.

Forgotten "console.log" or "debugger" statements show that a script was shipped in a debugging state. Some solutions include third-party libraries in old versions, for example an aging jQuery version. These come with known vulnerabilities. A large number of uncompressed scripts slows down the loading of forms.

Then there are the scripts nobody can attribute anymore: web resources that no form and no ribbon references. Either they are dead and can go, or another solution that you cannot see here uses them. The export alone cannot tell the two apart. So nothing gets deleted to be safe, and the stock keeps growing.

The connection you rarely see

A script is bound to a form through an event: on load, on save, when a field changes, when a tab expands, and so on. This binding lives in the form definition, not in the script file.

If you only look at the files, you do not see which function is called where. For a handover, that is the one piece of information that counts: which form calls which function on load?

A practical approach

Work through such stock in the same order every time: security-relevant patterns first, then replaced interfaces, and cleanup topics last.

Do not tackle the replaced interfaces all at once. It makes more sense to take them along when the form in question is rebuilt anyway. What matters is to know the stock, so that the decision is made consciously.

How does your own solution stack up?

Upload your solution export and get an assessment within minutes: security risks, technical debt, documentation coverage, and migration risk. No access to your environment required, first metrics free of charge.

Analyze your solution View sample report