Ng-bind-html-güvensiz kaldırıldığında HTML'yi nasıl enjekte edebilirim?


265

Benim denetleyici bir DIV HTML enjekte izin $sanitizesağlayıcı ve ng-bind-htm-unsafeyönerge kullanmaya çalışıyorum .

Ancak, işe yarayamıyorum.

<div ng-bind-html-unsafe="{{preview_data.preview.embed.html}}"></div>

Bunun AngularJS'den kaldırıldığı için olduğunu keşfettim (teşekkürler).

Ama olmadan ng-bind-html-unsafe, bu hatayı alıyorum:

http://errors.angularjs.org/undefined/$sce/unsafe


1.2.23+ için basit bir çözüm var, gönderiye bakın
John Henckel

Yanıtlar:


123
  1. Sanitize.js'nin yüklü olduğundan emin olmanız gerekir. Örneğin, https://ajax.googleapis.com/ajax/libs/angularjs/[LAST_VERSION Buradan //angular-sanitize.min.js adresinden yükleyin.
  2. Eklemek gerekir ngSanitizesenin üzerine modülü app ör:var app = angular.module('myApp', ['ngSanitize']);
  3. sadece ng-bind-htmlorijinal htmliçeriğe bağlanmanız gerekir . Kumandanızda başka bir şey yapmanıza gerek yok. Ayrıştırma ve dönüştürme ngBindHtmlyönerge tarafından otomatik olarak yapılır . ( Şununla ilgili How does it workbölümü okuyun : $ sce ). Yani, sizin durumunuzda <div ng-bind-html="preview_data.preview.embed.html"></div>bu işi yapardı.

3
Bunu güvenli bir şekilde yapmak en temiz seçenektir. Daha fazla bağımlılık ile geldi ama güvenlik hakkında hiçbir tereddüt yok!
Pierre Maoui

Bunu ionic 1.0.0-beta.13 ile kullanma
jasonflaherty

3
Bu, giriş gibi bazı etiketlerle çalışmaz. Elbette bunun üstesinden gelmenin kolay bir yolu yok. Gerçekten sinir bozucu.
Casey

En yaygın ve güvenli yol. Farklı görünümlerde bind-html kullanmayı planlıyorsanız bunu tercih edin.
eduardobursa

350

Alex'in önerdiği gibi, kapsamınızdaki bir işlevi bildirmek yerine, basit bir filtreye dönüştürebilirsiniz:

angular.module('myApp')
    .filter('to_trusted', ['$sce', function($sce){
        return function(text) {
            return $sce.trustAsHtml(text);
        };
    }]);

O zaman bu şekilde kullanabilirsiniz:

<div ng-bind-html="preview_data.preview.embed.html | to_trusted"></div>

Ve işte çalışan bir örnek: http://jsfiddle.net/leeroy/6j4Lg/1/


3
Github üzerinde açısal için küçük bir yararlı araç koleksiyonum var, sakıncası yoksa bu filtreyi bu araçlara dahil edeceğim. Bu html'ye güvendiğinizde en iyi çözüm IMHO'dur.
Capaj

@Capaj Sorun değil, ancak bu cevaba bir bağlantı eklerseniz bu çok takdir edilecektir. :-) stackoverflow.com/a/21254635
Leeroy Brun

Çok hoş. bu iç içe tekrarlarda bir cazibe gibi çalışır!
Jelle Verzijden

Bu, her denetleyici için kodlamadan çok daha iyi bir çözüm gibi görünüyor. Sadece hızlı bir filtre ve bitti! Ben pasta satırları, yinelenen tablo satırları tekrar ile kullanılır .... <td ng-bind-html="representative.primary | to_trusted"></td>
Phil Nicholas

2
angular.module ('myApp'). filtre ('trustAsHtml', ['$ sce', işlev ($ sce) {return $ sce.trustAsHtml}]);
bradw2k

275

Belirtilen diğer yorumlardan biri olarak Açısal 1.2.0 ... 'ı kullandığınızı belirttiniz ng-bind-html-unsafe.

Bunun yerine, böyle bir şey yapmak isteyeceksiniz:

<div ng-bind-html="preview_data.preview.embed.htmlSafe"></div>

Denetleyicinizde $scehizmeti enjekte edin ve HTML'yi "güvenilir" olarak işaretleyin:

myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
  // ...
  $scope.preview_data.preview.embed.htmlSafe = 
     $sce.trustAsHtml(preview_data.preview.embed.html);
}

1.2.0-rc3 veya daha yenisini kullanmak isteyeceğinizi unutmayın. ( Rc3'teki "gözlemcilerin" güvenilir HTML üzerinde düzgün çalışmasını engelleyen bir hatayı düzelttiler .)


2
Yukarıdaki kullanarak denedim ama kodumu kırıyor. İşlev tanımından önce '$ scope' başlığını eklemeniz gerekiyor gibi görünüyor - belki de bir anda "anlaşıldı", ancak artık değil. Aşağıdakiler işe myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
yaramalıdır

4
Sadece meraktan geçmek için $ sce hakkında daha fazla bilgiye buradan ulaşabilirsiniz ! ;)
genuinefafa

5
Bunun muhtemelen kodunuzda bir XSS güvenlik sorununa neden olacağını unutmayın. Alternatif ve daha güvenli bir düzeltme için ngSanitizeaşağıda önerilen cevaba bakınız ( stackoverflow.com/a/25679834/22227 ).
Martin Probst

Bu neden kötü bir fikir: docs.google.com/presentation/d/…
user857990

trustAsHtmlsöylediklerini yaparsa, Siteler Arası Komut Dosyası (XSS) saldırılarına neden olabilecek herhangi bir html koduna güvenir
Aleksey Solovey

112

Benim için en basit ve en esnek çözüm:

<div ng-bind-html="to_trusted(preview_data.preview.embed.html)"></div>

Ve kontrolörünüze fonksiyon ekleyin:

$scope.to_trusted = function(html_code) {
    return $sce.trustAsHtml(html_code);
}

Oyun $scekumandanızın başlatma işlemini eklemeyi unutmayın .


Denetleyicinin güvenilir html'yi $ kapsamında iade etmesi daha kolay görünüyor
meffect

1
Bu $ sce üzerine sonsuz döngü atabilir, şöyle bir şey yapabilir: $ scope.trusted = {}; $ scope.to_trusted = işlev (html_code) {return $ scope.trusted [html_code] || ($ scope.trusted [html_code] = $ sce.trustAsHtml (html_code)); };
AO_

1
HTML'yi güvenilir olarak kutsamayı içeren her çözüm bir XSS güvenlik açığı sunar. Daha güvenli bir düzeltme için lütfen aşağıda ngSanitize (stackoverflow.com/a/25679834/22227) öneren yanıta bakın.
Michele Spagnuolo

65

Bence bu en iyi çözüm şudur:

  1. Örneğin, uygulamanızda kullanılan common.module.js dosyasında olabilecek özel bir filtre oluşturun:

    var app = angular.module('common.module', []);
    
    // html filter (render text as html)
    app.filter('html', ['$sce', function ($sce) { 
        return function (text) {
            return $sce.trustAsHtml(text);
        };    
    }])
    
  2. Kullanımı:

    <span ng-bind-html="yourDataValue | html"></span>

Şimdi - yönergesi neden görmüyorum ng-bind-htmldeğil trustAsHtmlonun işlevinin bir parçası olarak - Ya etmezse o bana biraz aptal görünüyor

Her neyse - işte böyle yapıyorum - zamanın% 67'si, her zaman çalışıyor.


Bul ve değiştir için aşağıdaki regex'i kullanabilirsiniz: regex: ng-bind-html-unsafe = "((? :( ?!").) *) "Değiştirme: ng-bind-html =" ($ 1) | html "ile yukarıdaki filtre.
George Donev

2
HTML'yi güvenilir olarak kutsamayı içeren her çözüm bir XSS güvenlik açığı sunar. Daha güvenli bir düzeltme için lütfen aşağıda ngSanitize (stackoverflow.com/a/25679834/22227) öneren yanıta bakın.
Michele Spagnuolo

7

Kendi basit güvensiz html bağlantınızı oluşturabilirsiniz, elbette kullanıcı girdisini kullanırsanız bir güvenlik riski olabilir.

App.directive('simpleHtml', function() {
  return function(scope, element, attr) {
    scope.$watch(attr.simpleHtml, function (value) {
      element.html(scope.$eval(attr.simpleHtml));
    })
  };
})

Bu direktif aynı zamanda $sce.trustAsHtml?
kontur

5

Ng-bind-html-güvensiz içinde {{}} kullanmanıza gerek yoktur:

<div ng-bind-html-unsafe="preview_data.preview.embed.html"></div>

İşte bir örnek: http://plnkr.co/edit/R7JmGIo4xcJoBc1v4iki?p=preview

{{}} Operatörü temel olarak ng-bind için bir kısayoldur, bu yüzden denediğiniz şey bir bağlamanın içindeki bir bağlamaya karşılık gelir ve bu işe yaramaz.


Ancak, çıkarırsam, hiçbir şey enjekte edilmez. Ve dokümanlar oldukça kafa karıştırıcı, tek bir} docs-angularjs-org-dev.appspot.com/api/…
metalaureate

Çok tuhaf. Emin olmak için test ettim ve benim için beklendiği gibi çalıştı. Tekli {} dokümanlarda biraz kafa karıştırıcı olduğunu kabul ediyorum, ancak dizede değişmez ifadeler olarak değil, bir ifadenin temsili anlamına geliyorlar. Cevabımı çalışan bir grupla güncelledim.
ksimons

Ayrıca, zaten 1.2.0 kullanıyorsanız, ng-bind-html-unsafe kaldırıldığı için buradaki yorumlara bakın: docs.angularjs.org/api/ng.directive:ngBindHtml
ksimons

2
1.2 kullanıyorum. Güvenli olmayan bir HTML nasıl enjekte edilebilir? Bu hatayı onsuz alabilirim: mistakes.angularjs.org/undefined/$sce/unsafe
metalaureate 16:13

{{}}Operatör ipucu için bağlayıcı başarısız sayesinde benim soruna neden oldu!
Campbeln

2

Benzer bir sorun yaşadım. Yine de github'da barındırılan markdown dosyalarımdan içerik alınamadı.

App.js'de $ sceDelegateProvider'a bir beyaz liste (github alanı eklenmiş olarak) ayarladıktan sonra bir cazibe gibi çalıştı.

Açıklama: Farklı bir URL'den içerik yüklerseniz güvenilir olarak kaydırmak yerine bir beyaz liste kullanma.

Dokümanlar: $ sceDelegateProvider ve ngInclude (harici HTML parçasını almak, derlemek ve dahil etmek için)


2

Sıkı Bağlamsal Kaçış tamamen devre dışı bırakılabilir, böylece html kullanarak enjekte edebilirsiniz ng-html-bind. Bu güvenli olmayan bir seçenektir, ancak test sırasında yardımcı olur.

AngularJS belgelerinden bir$sce örnek :

angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
  // Completely disable SCE.  For demonstration purposes only!
  // Do not use in new projects.
  $sceProvider.enabled(false);
});

Yukarıdaki yapılandırma bölümünü uygulamanıza eklemek, html'yi enjekte etmenize olanak tanır ng-html-bind, ancak dokümanın belirttiği gibi:

SCE, küçük kodlama yükü için size birçok güvenlik avantajı sağlar. SCE devre dışı bırakılmış bir uygulamayı almak ve kendi başınıza güvenli hale getirmek veya daha sonraki bir aşamada SCE'yi etkinleştirmek çok daha zor olacaktır. SCE'nin sunulmasından önce yazılmış çok sayıda mevcut kodunuz olduğu ve bunları bir kerede bir modülü taşıdığınız durumlarda SCE'yi devre dışı bırakmak mantıklı olabilir.


Bilmek güzel, ama kesinlikle dikkatle ele alınması gereken bir şey.
iconoclast

2

Filtreyi böyle kullanabilirsiniz

angular.module('app').filter('trustAs', ['$sce', 
    function($sce) {
        return function (input, type) {
            if (typeof input === "string") {
                return $sce.trustAs(type || 'html', input);
            }
            console.log("trustAs filter. Error. input isn't a string");
            return "";
        };
    }
]);

kullanım

<div ng-bind-html="myData | trustAs"></div>

diğer kaynak türleri için kullanılabilir, örneğin iframe'ler için kaynak bağlantısı ve burada bildirilen diğer türler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.