NetIQ Access Manager – Javascript Injection Policies



By: jrivard

August 14, 2013 10:05 am

Reads: 817

Comments:0

Rating:5.0

NetIQ Access Manager (NAM) v3.2 SP2 introduces a new powerful feature for protected web applications. The Access Manager Access Gateway (the AG), now has the ability to inject arbitrary javascript into nearly any HTML page passing through the access gateway.

This feature was added to give the administrator more flexibility in integrating off the shelf apps into Access Manager, as well as modifying application behavior. In most cases you shouldn’t need this feature. But if you do, you will be glad its there.

The Javascript Injection feature is actually part of the form fill engine of the Access Gateway. This is because the same technology is used for both functionality. The primary difference in a Javascript Injection Policy is that there does not need to be a <form> tag on the page in order for the injection to occur.

To create a new Javascript Injection Policy, login to the NAM Administration Console, then select Policies menu and the Policy submenu. Next, create a new policy and set the type to Access Gateway: Form Fill, when the new policy page is loaded, select the New menu, and choose Inject JavaScript. At that point your screen should look similar to the following.

29436-1

The JavaScript injector will allow injection at three different places on the page, depending on your needs. You can inject your JavaScript into the Head block, just after the opening <body> tag, or just before the close of the ending </body> tag. In most cases it won’t matter which position you use, but the flexibility is there in case pre-existing application scripts may otherwise interfere with your script location.

You can also select CGI or Page matching criteria, this work exactly the same as on the standard form fill policy configurations. Also keep in mind that this policy will have to be deployed as part of a protected resource. You should try to use the matching criteria and protected resource path definitions both to limit the scope of your injection policy as much as possible. The more narrow the scope of the policy, the less overhead the form fill engine will need to consume to detect and inject on the pages in scope.

It’s also worth noting that a standard form fill policy and a javascript injection policy cannot both be invoked on the same page. That should not be a problem because you can use the form fill policies’ Statements to Execute on Submit to inject any necessary javascript into a form fill.

Javascript Injection Policy Examples

Hello World Examples

The first example simply pops up an alert to prove the javascript injection is working. If you get a browser dialog box that says “the alert is working!” then you know the injection policy has been triggered on the page.

<script type="text/javascript">
   alert(‘the alert is working!');
</script>

This second example will change the background of a page. Note that depending on the layout of the HTML page and other CSS/Javascript that is invoked on this page, it is possible for this to have little to no effect. It is best to experiment with simple HTML pages first.

<script type="text/javascript">
   document.body.style.backgroundColor="yellow";
</script>

Idle Timeout Handler Examples

A common request from security auditors is to automatically logout a user when an idle timeout period is reached. NAM has built in idle timeout handling, but it simply destroys the user’s HTTP session. The potentially sensitive contents of the application screen are left in a users browser for other people to see. And worst yet,l the user may return to the page to continue editing a form or other data, only to lose that data when they proceed to the next page and are redirected to a login screen.

Handling these issues is typically the domain of the application developer, not the access management solution. However with NAM’s Javascript Injection, we can add script to the application to handle these scenarios, and the application will behave as if that script was part of the application.

This first example shows a very basic handler that will redirect the user to NAM’s logout page after an idle period. The script isn’t capable of reading the actual NAM idle timeout setting value, so you will need to specify the desired timeout (in milliseconds) in the script.

<script type="text/javascript">
var inactivityTime = function () {
    var t;
    if (window.onload != null) {  
      var oldOnload = window.onload;
      window.onload = function() { inactivityTime(); oldOnload(); }
    } else {
      window.onload = resetTimer;
    }
    document.onmousemove = resetTimer;
    document.onkeypress = resetTimer;

    function logout() {
        location.href = '/AGLogout'
    }

    function resetTimer() {
        clearTimeout(t);
        t = setTimeout(logout, 15000); //milliseconds
    }
};
inactivityTime();
</script>

It would be more polite to give the user a warning first; but that will require a more sophisticated script. The following script will add a lightbox with a warning before the redirect occurs. It also demonstrates that the Javascript Injector can inject more than javascript! In this example, a <style> block is added to add styling for the injected lightbox html.

<script type="text/javascript">
var NamInjectedIdleTimeoutHandler = {};

NamInjectedIdleTimeoutHandler.SETTING_LOGOUT_URL = '/AGLogout';
NamInjectedIdleTimeoutHandler.SETTING_IDLE_MS = 10000; //30 seconds
NamInjectedIdleTimeoutHandler.SETTING_WARNING_TEXT = 'Your session is about to time out.<br/>Please click anywhere to continue'
NamInjectedIdleTimeoutHandler.SETTING_WARNINGS_MS = 10000; //10 seconds

NamInjectedIdleTimeoutHandler.TIMER = null; // do not modify

NamInjectedIdleTimeoutHandler.displayLightBox = function() {
	var divOverlay = document.createElement("div");
	divOverlay.class = 'nam-injected-lightbox';
	divOverlay.id = 'nam-injected-lightbox';
	divOverlay.setAttribute("onclick", "NamInjectedIdleTimeoutHandler.resetTimer()");
	divOverlay.innerHTML = '<div id="nam-injected-notice" class="nam-injected-notice">' + NamInjectedIdleTimeoutHandler.SETTING_WARNING_TEXT + '</div>';
	var bodyTag = document.getElementsByTagName("body")[0];
	bodyTag.appendChild(divOverlay);
}

NamInjectedIdleTimeoutHandler.clearLightBox = function() {
	var element = document.getElementById("nam-injected-lightbox");
	if (element != null) {
		element.parentNode.removeChild(element);
	}
}

NamInjectedIdleTimeoutHandler.resetTimer = function() {
    clearTimeout(NamInjectedIdleTimeoutHandler.TIMER);
	NamInjectedIdleTimeoutHandler.clearLightBox();
    NamInjectedIdleTimeoutHandler.TIMER = setTimeout(NamInjectedIdleTimeoutHandler.showWarning, NamInjectedIdleTimeoutHandler.SETTING_IDLE_MS);
}

NamInjectedIdleTimeoutHandler.logout = function() {
	location.href = NamInjectedIdleTimeoutHandler.SETTING_LOGOUT_URL;
}

NamInjectedIdleTimeoutHandler.showWarning = function() {
    NamInjectedIdleTimeoutHandler.displayLightBox();
	clearTimeout(NamInjectedIdleTimeoutHandler.TIMER);
    NamInjectedIdleTimeoutHandler.TIMER = setTimeout(NamInjectedIdleTimeoutHandler.logout, NamInjectedIdleTimeoutHandler.SETTING_WARNINGS_MS);
}

NamInjectedIdleTimeoutHandler.startIdleDetector = function() {
    document.onmousemove = NamInjectedIdleTimeoutHandler.resetTimer;
    document.onkeypress = NamInjectedIdleTimeoutHandler.resetTimer;
    NamInjectedIdleTimeoutHandler.TIMER = setTimeout(NamInjectedIdleTimeoutHandler.showWarning, NamInjectedIdleTimeoutHandler.SETTING_IDLE_MS);
}
NamInjectedIdleTimeoutHandler.startIdleDetector();
</script>
<style>
#nam-injected-lightbox {
   background-color: #000;
   opacity: .7;
   filter: alpha(opacity=70);
   position: absolute; top: 0; left: 0;
   width: 100%; height: 100%;
   z-index: 10;
}
#nam-injected-notice {
   background-color: white;
   color: black;
   opacity: 1
   filter: alpha(opacity=100);
   position: absolute;
   top: 50%;
   left: 50%;
   margin-left:-70px;
   margin-top:-50px;   
   padding: 10px;
   z-index: 11;
}
</style>

Analytics Injection Examples

A simpler case involves injecting a script to allow analytics. A common example is using Google Analytics to track application usage. The example value UA-11111111-1 would need to be replaced with the appropriate Google Analytics site identifier.

var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-11111111-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

Other Uses

These examples are just some of the possibilities with the NAM Javascript Injection Policy. More practical examples are to adjust behavior of your specific applications.

There are a few things to keep in mind when using these scripts.

  1. Since you can define your own <script> tag, you can reference external scripts as well as inject your own script blocks by including a src attribute.
  2. It is possible to use standard Javascript libraries such as jQuery, Dojo or YUI, but you must use caution to avoid referencing a second copy of a library your application is already using.
  3. You can inject <style>, <link> and other tags besides just <script> tags.
VN:D [1.9.22_1171]
Rating: 5.0/5 (2 votes cast)
NetIQ Access Manager - Javascript Injection Policies, 5.0 out of 5 based on 2 ratings

Tags: ,
Categories: Access Manager, Technical Solutions

Disclaimer: As with everything else at NetIQ Cool Solutions, this content is definitely not supported by NetIQ, so Customer Support will not be able to help you if it has any adverse effect on your environment.  It just worked for at least one person, and perhaps it will be useful for you too.  Be sure to test in a non-production environment.

Comment