Something odd I've noticed with iframe behavior in a simple widget

tateroth
Giga Contributor

I started working on a simple video playback widget for a service portal and ran into something strange.   When I put the following code in the HTML section of the widget I get the following results;

<div>

  <nav class="fit-content">

      <ul class="fit-content">

  <iframe ng-src="https://www.youtube.com/embed/STFlnEgx6nk" frameborder="0" allowfullscreen></iframe>

      </ul>

  </nav>

</div>

<p align="center">

  {{options.widget_text}}

  {{options.target_url}}

</p>

find_real_file.png

Where I have the following settings in the widget options;

find_real_file.png

The strange part is when I try to make the HTML dynamic based off of the Target URL field, I get the results below;

<div>

  <nav class="fit-content">

      <ul class="fit-content">

  <iframe ng-src="{{options.target_url}}" frameborder="0" allowfullscreen></iframe>

      </ul>

  </nav>

</div>

<p align="center">

  {{options.widget_text}}

  {{options.target_url}}

</p>

find_real_file.png

When I use inspect in Chrome I see this under Console;

amb.MessageClient [INFO] >>> connection exists, request satisfied

js_includes_sp.jsx:11973 Error: [$interpolate:interr] Can't interpolate: {{options.target_url}}

Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy.   URL: https://www.youtube.com/embed/STFlnEgx6nk

http://errors.angularjs.org/1.5.8/$sce/insecurl?p0=https%3A//www.youtube.com/embed/STFlnEgx6nk

http://errors.angularjs.org/1.5.8/$interpolate/interr?p0=%7B%7Boptions.targ…ecurl%3Fp0%3Dhttps%253A%...

      at js_includes_sp.jsx:6202

      at Function.$interpolateMinErr.interr (js_includes_sp.jsx:11258)

      at parseStringifyInterceptor (js_includes_sp.jsx:11402)

      at Array.regularInterceptedExpression (js_includes_sp.jsx:13768)

      at interpolationFn (js_includes_sp.jsx:11376)

      at Object.attrInterpolatePreLinkFn (js_includes_sp.jsx:10354)

      at js_includes_sp.jsx:6640

      at invokeLinkFn (js_includes_sp.jsx:10418)

      at nodeLinkFn (js_includes_sp.jsx:9988)

      at compositeLinkFn (js_includes_sp.jsx:9521)

What I don't understand is when the URL is pasted directly in, it works just fine but when I use the variable which has the same value I end up with this error.   I'm guessing I'm just missing something simple, but it seems really odd to me.   Any ideas or suggestions?

Note:   The video is just the first one I grabbed.  

1 ACCEPTED SOLUTION

ChrisBurks
Mega Sage

The reason it works when directly entered is that it's hardcoded. When it's a variable/dynamic, it could be compromised by malicious code. The $sceDelegate checks to see if the url is from the same origin (trusted) and if not it's considered not trusted.



For the src to be accepted when dynamic you'll need to bring in $sce into your client controller function. If your variable is being set in the server side, it will need to be passed to the client controller and set on scope there wrapped around $sce.trustAsResourceUrl method. Then everything should work.



Using your example:


HTML:


<iframe ng-src="{{ target_url }}" frameborder="0" allowfullscreen></iframe>




Client controller:


function($scope,$sce){


        var c = this;


        $scope.target_url = $sce.trustAsResourceUrl( c.options.target_url );


}


View solution in original post

5 REPLIES 5

chakravarthy
Kilo Explorer

Hi tateroth



Did you get this working? I'm facing similar issue with iframe.



Thanks,


Chakri


No I haven't, I going to try to fit some time in over the next couple of days to dig in a little more to see if I can figure it out.


ChrisBurks
Mega Sage

The reason it works when directly entered is that it's hardcoded. When it's a variable/dynamic, it could be compromised by malicious code. The $sceDelegate checks to see if the url is from the same origin (trusted) and if not it's considered not trusted.



For the src to be accepted when dynamic you'll need to bring in $sce into your client controller function. If your variable is being set in the server side, it will need to be passed to the client controller and set on scope there wrapped around $sce.trustAsResourceUrl method. Then everything should work.



Using your example:


HTML:


<iframe ng-src="{{ target_url }}" frameborder="0" allowfullscreen></iframe>




Client controller:


function($scope,$sce){


        var c = this;


        $scope.target_url = $sce.trustAsResourceUrl( c.options.target_url );


}


You were right on the money, thank you!   That's the path I was headed down, but I haven't gotten that far yet.