Hot!Angular application with SSL VPN

Author
vashist
New Member
  • Total Posts : 1
  • Scores: 0
  • Reward points: 0
  • Joined: 2017/12/25 12:53:05
  • Status: offline
2017/12/25 13:17:32 (permalink)
0

Angular application with SSL VPN

Hello,
We have an Angular 5 application deployed at a client's network at http://10.x.y.z/my-app running fine when accessed directly (using hash in Url). Now the client wants to allow access to this application from external users. They configured SSL VPN in Fortigate (Web Mode) and added a bookmark to this internal app. The traffic from external users reaches the app. Resources such as images, css etc. are retrieved correctly. It's when the application itself starts up the problems begin.
 
Below is the console output. I'm clueless as I have no experience with Fortigate and have no access to the client infrastructure. Is this a Fortigate configuration issue or should I be looking at the application code? Any pointers?
 
Console output:
 
sslvpn.js:formatted:646 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
XMLHttpRequest.open @ sslvpn.js:formatted:646
(anonymous) @ polyfills.f49c53c5e5719087df48.bundle.js:formatted:2972
o.(anonymous function) @ polyfills.f49c53c5e5719087df48.bundle.js:formatted:1332
open_func @ sslvpn.js:formatted:502
(anonymous) @ main.1b6318b698ef209032cf.bundle.js:formatted:53868
...

window.webpackJsonp @ inline.f8b796da0c03c9b36b0b.bundle.js:formatted:25
(anonymous) @ main.1b6318b698ef209032cf.bundle.js:formatted:1

14:53:31.141 main.1b6318b698ef209032cf.bundle.js:formatted:54139 DOMException: Failed to set the 'responseType' property on 'XMLHttpRequest': The response type cannot be changed for synchronous requests made from a document.
    at l._subscribe (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2224057)
    at l._trySubscribe (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:146031)
    at l.subscribe (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:145860)
    at l.call (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2477489)
    at l.subscribe (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:145798)
    at l.call (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2476297)
    at l.subscribe (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:145798)
    at n.a (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2645998)
    at n._innerSub (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2665193)
    at n._tryNext (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:2665117)
 
14:53:31.156 main.1b6318b698ef209032cf.bundle.js:formatted:49196 ERROR DOMException: Failed to execute 'setAttribute' on 'Element': '' is not a valid attribute name.
    at Object.set_attr (https://some-domain.com:10443/sslvpn/js/sslvpn.js:1:20146)
    at l.setAttribute (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:405810)
    at Object.set_attr (https://some-domain.com:10443/sslvpn/js/sslvpn.js:1:20329)
    at l.setAttribute (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:332056)
    at Object.set_attr (https://some-domain.com:10443/sslvpn/js/sslvpn.js:1:20329)
    at pn (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:232325)
    at me (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:248003)
    at Se (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:255747)
    at Me (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:254954)
    at me (https://some-domain.com:10443/proxy/1d335b11/http/10.x.y.z/my-app/main.1b6318b698ef209032cf.bundle.js:1:248677)

 
14:53:31.159 main.1b6318b698ef209032cf.bundle.js:formatted:12375 ERROR Error: Uncaught (in promise): InvalidCharacterError: Failed to execute 'setAttribute' on 'Element': '' is not a valid attribute name.
Error: Failed to execute 'setAttribute' on 'Element': '' is not a valid attribute name.
    at Object.set_attr (sslvpn.js:formatted:558)
    at l.setAttribute (main.1b6318b698ef209032cf.bundle.js:formatted:18265)
    at Object.set_attr (sslvpn.js:formatted:563)
    at l.setAttribute (main.1b6318b698ef209032cf.bundle.js:formatted:15297)
    at Object.set_attr (sslvpn.js:formatted:563)
    at pn (main.1b6318b698ef209032cf.bundle.js:formatted:9892)

 
 
===============
in sslvpn.js:
===============
set_attr: function() {
        var s, i, v;
        if ("object" == typeof arguments[0]) {
            if (3 == arguments.length)
                s = this.is_url_attributes(arguments[1]) ? this.url_rewrite(arguments[2]) : arguments[2],
                arguments[0].setAttribute(arguments[1], s); // <<< ERROR HERE
            else
                for (i = 2; i < arguments.length; i += 2)
                    v = i + 1 < arguments.length ? arguments[i + 1] : null,
                    s = this.is_url_attributes(arguments[i]) ? this.url_rewrite(v) : v,
                    arguments[0].setAttribute(arguments[1], arguments[i], s);
            return arguments[0]
        }
        "function" == typeof arguments[0] && 3 == arguments.length && (s = this.is_url_attributes(arguments[1]) ? this.url_rewrite(arguments[2]) : arguments[2],
        arguments[0].setAttribute(arguments[1], s))
    },

#1

13 Replies Related Threads

    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/02/27 05:44:14 (permalink)
    0
    Hi vashist,
     
    I have the same problem.
    With Angular 1, the URL Rewrites of sslvpn.js broke the angular router, there is the patch:
    https://github.com/d-trattner/Fortinet-Angular
     
    Now I have problems again with angular 5 and I tried to come up with a solution.
    I tried to replace the functions again (mainly set_attr), but there is always a Stack Exceed Error.
    I may try other solutions later...
     
    What I tried a few minutes ago, is to obfuscate the function calls, so they do not get replaced by Forti.
    You would need the following inside the angular 5 project (as a script):
    var a5p = {
        set_attr: function() {
            return "etubirttAtes".split('').reverse().join('');
        }
    }

     
    Finally, after building (dist), open up vendor, polyfills and any other file that contains the "setAttribute" call.
    Replace the string ".setAttribute(" with "[a5p.set_attr()]("

    Sure, you could just replace ".setAttribute(" with "["etubirttAtes".split('').reverse().join('')](",
    but I tried to save some chars.
     
    I just got my sample application running using this approach.
    But in reality, I do not want to modify the dist, so I try to come up with another solution... digging goes on...
     
    BR, Daniel
     
    Edit:
    Have not found a better solution by now.
    To speed up the replace solution, one could put a powershell script inside the project dir (if on Win):
    #fortipatch.ps1
    $files = Get-ChildItem -Path "C:\path_to_angular_app\dist\*" -Include *.js

    foreach ($file in $files){
        $find = ".setAttribute("
        $replace = "[a5p.set_attr()]("
        $content = Get-Content $($file.FullName) -Raw
        $content.Replace($find, $replace) | Out-File $($file.FullName) -encoding utf8
    }

     
    the packacke.json could have the following script added:
    "fortipatch": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./fortipatch.ps1"

     
    The PS Script adds a BOM to the files, but my application worked, should not have any impact...
     
    After building the app, developer would run...
    npm run fortipatch

     
    But, I'm not giving up the search for another solution...
    post edited by dant - 2018/02/27 08:15:51
    #2
    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/02/27 08:54:43 (permalink)
    0
    Now I may have found a working solution without having to replace anything:
    https://www.npmjs.com/package/javascript-obfuscator
    Tested and worked, I just obfuscated vendor and polyfills files.
     
    Here is an example:
    https://ourcodeworld.com/articles/read/607/how-to-obfuscate-javascript-code-with-node-js
     
    BR, Daniel
    #3
    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/03/20 06:27:38 (permalink)
    0
    After finalising our A5 application, I want to give you a final conclusion, on what happened here and what worked for me:
     
    First, the obfuscation eliminates most issues.
    I do not have the time to fix the problems, that arise on Fortis side.
    Here are the scripts I use for the obfuscation:
    obfuscate-dev.js:

    var fs = require("fs");
    var JavaScriptObfuscator = require('javascript-obfuscator');
    var files = [
        './dist/vendor.bundle.js',
        './dist/polyfills.bundle.js'
    ]
    files.forEach(function(file) {
        var backup = file + ".bak";
        fs.renameSync(file,backup);
        fs.readFile(backup, "UTF-8", function(err, data) {
            if (err) { throw err; }
            // Obfuscate content of the JS file
            var obfuscationResult = JavaScriptObfuscator.obfuscate(data);
            // Write the obfuscated code into a new file
            fs.writeFile(file, obfuscationResult.getObfuscatedCode() , function(err) {
                if(err) { return console.log(err); }
                console.log(file + " obfuscated!");
            });
        });
    });

    obfuscate-prod.js:
    var fs = require("fs");
    var path = require("path");
    var JavaScriptObfuscator = require('javascript-obfuscator');
    var dir = './dist/';
    fs.readdir(dir, function(err, list) {
        if (err) { throw err; }
        list.forEach(function(file) {
            if(file.slice(-2) === 'js' && (file.substr(0,5) === 'main.' || file.substr(0,10) === 'polyfills.')) {
                var filepath = path.resolve(dir, file);
                var backup = filepath + ".bak";
                fs.renameSync(filepath,backup);
                fs.readFile(backup, "UTF-8", function(err, data) {
                    if (err) { throw err; }
                    // Obfuscate content of the JS file
                    var obfuscationResult = JavaScriptObfuscator.obfuscate(data);
                    // Write the obfuscated code into a new file
                    fs.writeFile(filepath, obfuscationResult.getObfuscatedCode() , function(err) {
                        if(err) { return console.log(err); }
                        console.log(filepath + " obfuscated!");
                    });
                });
            }
        });
    });

    Now in the package.json scripts section:
    "dev": "ng build --dev --base-href [your basehref] && node obfuscate-dev",
    "prod": "ng build --prod --base-href [your basehref] && node obfuscate-prod",

     
    Second, the XMLHttpRequest Error:
    By the time of working on the application, I had no server-calls, so I just recently stumbled across the other error you mentioned:
    Failed to set the 'responseType' property on 'XMLHttpRequest'

    This error arises here:
    sslvpn.js (injected forti JS), scrolling down to the bottom
    try {
            !function(open) {
                XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
                    open.call(this, method, fgt_sslvpn.url_rewrite(url), async, user, pass)
                }
            }(XMLHttpRequest.prototype.open)
    ...
    ...

    Because the prototype function gets overwritten, obfuscation cannot do anything.
    So I used the fortipatch approach to re-re-write the "XMLHttpRequest.prototype.open" method like that:
    if(typeof fgt_sslvpn !== "undefined"){
        try {
            !function(open) {
                XMLHttpRequest.prototype.open = function(method, url, async=true, user, pass) {
                    open.call(this, method, fgt_sslvpn.url_rewrite(url), async, user, pass)
                }
            }(XMLHttpRequest.prototype.open)
            console.log("Fortis XMLHttpRequest.prototype.open overwritten with async default value = true");
        } catch (e) {}
    }

     
    The problem lies in the async property, I defaulted that to "true".
     
    Hope that helps, maybe Forti will update the sslvpn.js anytime soon (hopefully).
     
    Edit:
    If users are using IE11, default parameters (ES6) are not supported, so use it like that:
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
                    if(!async) async = true;
                    open.call(this, method, fgt_sslvpn.url_rewrite(url), async, user, pass);
                }

    post edited by dant - 2018/03/23 05:36:13
    #4
    jblanco
    New Member
    • Total Posts : 5
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/05/03 07:08:56
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 07:29:17 (permalink)
    0
    Hello dant,
     
    I am trying to access an Angular 1 app behind this FortiGate SSL VPN. Basically, the same issue that you and vashist were having. However, I have not faced any routing issues because when the app loads, it loads with errors (see picture) which does not allow me to do or test anything else on the app.
     
    I went over your solution of obfuscation but I don't know if it will apply to my issue. After doing some testing on my own it seems the issue happens with angular code in the html. When I put an expression, , or a ng-click, or ng-model, then the app shows the error on the picture. But when the html is clean of angular code, except for ng-app and ng-controller, the app works fine, and by that I mean that the angular scripts/controllers are loaded and executed correctly. 
     
    Any ideas or suggestions? Let me know if you need more info. Thanks. 
    post edited by jblanco - 2018/05/03 09:07:19
    #5
    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 07:59:29 (permalink)
    0
    * sry, the forum reply was misleading
    post edited by dant - 2018/05/03 08:01:44
    #6
    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 08:02:09 (permalink)
    0
    Hi jblanco,
    The picture/screenshot is missing. 
    As this solution was tested for A5, please try the following: https://github.com/d-trattner/Fortinet-Angular
     
    BR, Dan
    #7
    kurtli_FTNT
    Bronze Member
    • Total Posts : 48
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/03/29 15:07:50
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 09:10:22 (permalink)
    0
    Hi Dant,
        Thanks for your work. May I know what build version you guys are using and do you guys already opened a ticket for that?
     
     
    Regards.
    #8
    jblanco
    New Member
    • Total Posts : 5
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/05/03 07:08:56
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 09:13:19 (permalink)
    0
    I am trying to post the image but is not uploading it. I will try to use a link instead. https://drive.google.com/...BCxOVofw08CBfSGNxr0vle
    #9
    jblanco
    New Member
    • Total Posts : 5
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/05/03 07:08:56
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 09:40:14 (permalink)
    0
    Hello kurtli,
     
    Build version of what? Angular? And I have not opened a ticket. If I need to open one, how would I go about it?
     
    Thanks.
    #10
    kurtli_FTNT
    Bronze Member
    • Total Posts : 48
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/03/29 15:07:50
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 09:49:33 (permalink)
    0
    Hi Jblanco,
       What is the version of FOS? 6.0, 5.6, or 5.4? As I saw a similar bug and it will be fixed in 5.6.5 and 6.0.1.
     
     
    Thanks
    #11
    jblanco
    New Member
    • Total Posts : 5
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/05/03 07:08:56
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 11:50:20 (permalink)
    0
    The version is 5.4.6. The latest version out is 6.0.1? And do you think this bug with angularjs is fix in this latest version?
    #12
    kurtli_FTNT
    Bronze Member
    • Total Posts : 48
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/03/29 15:07:50
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/03 13:56:37 (permalink)
    0
    v6.0.1 is next coming version but not released yet. I found an existing bug with similar symptom and it will be fixed in 6.0.1. We are working to make sure if they share the same cause, if not, then probably will open another bug to track.
    BTW what is the model/platform with 5.4.6? I am trying to reproduce in lab, so better with the same model. Thanks.
    #13
    dant
    New Member
    • Total Posts : 7
    • Scores: 0
    • Reward points: 0
    • Joined: 2018/02/27 05:27:49
    • Status: offline
    Re: Angular application with SSL VPN 2018/05/04 00:24:24 (permalink)
    0
    I try to give as much information as I can to reproduce the issues...
     
    FortiGate 5.4.x
    I think that was the version, where I got the issues with Angular 1.3.18.
    The solution was my patch: https://github.com/d-trat.../forti_sslvpn_patch.js
     
    FortiGate 5.6.2
    This is the current version and I solved the issues in Angular 5.x (as seen in the previous posts).
    BUT, my patch for Angular 1.3.18 did not work anymore.
    I then obfuscated the Angular 1.3.18 core file, what seems to work here too.
     
    For A1 to reproduce, you would need a simple app with a route (using $location).
    For A5 to reproduce, you would need an app with a server call, can be a fake server call (http-interceptor).
     
    BR, Dan
    #14
    Jump to:
    © 2018 APG vNext Commercial Version 5.5