경고 : 안전하지 않은 스타일 값 URL 삭제


107

Angular 2 앱의 구성 요소 템플릿에서 DIV의 배경 이미지를 설정하고 싶습니다. 그러나 콘솔에 다음 경고가 계속 표시되고 원하는 효과를 얻지 못합니다 ... Angular2의 보안 제한으로 인해 동적 CSS 배경 이미지가 차단되는지 또는 HTML 템플릿이 손상되었는지 확실하지 않습니다.

이것은 내 콘솔에 표시되는 경고입니다 (img URL을 /img/path/is/correct.png다음과 같이 변경했습니다 .

경고 : 안전하지 않은 스타일 값 url 삭제 (SafeValue는 [property] = binding : /img/path/is/correct.png를 사용해야합니다 ( http://g.co/ng/security#xss 참조 )) ( http : // 참조 ) . g.co/ng/security#xss ).

문제는 DomSanitizationServiceAngular2를 사용하여 템플릿에 주입 된 내용을 삭제하는 것입니다 . 내 템플릿에있는 HTML은 다음과 같습니다.

<div>
    <div>
        <div class="header"
             *ngIf="image"
             [style.background-image]="'url(' + image + ')'">
        </div>

        <div class="zone">
            <div>
                <div>
                    <h1 [innerHTML]="header"></h1>
                </div>
                <div class="zone__content">
                    <p
                       *ngFor="let contentSegment of content"
                       [innerHTML]="contentSegment"></p>
                </div>
            </div>
        </div>
    </div>
</div>

다음은 구성 요소입니다 ...

Import {
    DomSanitizationService,
    SafeHtml,
    SafeUrl,
    SafeStyle
} from '@angular/platform-browser';

@Component({
               selector: 'example',
               templateUrl: 'src/content/example.component.html'
           })
export class CardComponent implements OnChanges {

    public header:SafeHtml;
    public content:SafeHtml[];
    public image:SafeStyle;
    public isActive:boolean;
    public isExtended:boolean;

    constructor(private sanitization:DomSanitizationService) {
    }

    ngOnChanges():void {
        map(this.element, this);

        function map(element:Card, instance:CardComponent):void {
            if (element) {
                instance.header = instance.sanitization.bypassSecurityTrustHtml(element.header);

                instance.content = _.map(instance.element.content, (input:string):SafeHtml => {
                    return instance.sanitization.bypassSecurityTrustHtml(input);
                });

                if (element.image) {
                    /* Here is the problem... I have also used bypassSecurityTrustUrl */ 
                    instance.image = instance.sanitization.bypassSecurityTrustStyle(element.image);
                } else {
                    instance.image = null;
                }

            }
        }
    }
}

예를 들어 [src] = "image"를 사용하여 템플릿에 바인딩 한 경우 다음과 같이하십시오.

<div *ngIf="image">
    <img [src]="image">
</div>

image사용하여 전달 된 bypassSecurityTrustUrl모든 것이 잘 작동하는 것 같았다 ... 깡통 사람이 내가 잘못을하고있는 중이 야 무엇을보고?


질문에 대한 해결책을 얻었습니까? 나는 똑같은 문제가 있으며 여전히 해결책을 찾으려고 노력하고 있습니다. 미리 감사드립니다!
SK.

답변:


112

전체 url문을 다음과 bypassSecurityTrustStyle같이 래핑해야 합니다 .

<div class="header" *ngIf="image" [style.background-image]="image"></div>

그리고

this.image = this.sanitization.bypassSecurityTrustStyle(`url(${element.image})`);

그렇지 않으면 유효한 스타일 속성으로 표시되지 않습니다.


1
PierreDuc, 배경 이미지가 위와 같이 우회되었을 때 지혜로운 말이 있지만 Angular2는 조용히 그것을 무시합니까? 새로운 질문을 게시 할 수 있지만 귀하의 답변과 상당히 밀접한 관련이 있다고 생각합니다.
David Pfeffer

@DavidPfeffer 코드를 보지 않고 어디에서 문제가 발생하는지 판단하는 것은 어렵습니다. :)이 코드를 최신 angular2에서 사용하고 있으며 여전히 작동합니다 ..
Poul Kruijt

1
나는 그것을 알아. 삭제를 우회 한 후 값이 유효하지 않으면 Angular2는 자동으로이를 무시합니다.
David Pfeffer

당신은 ngStyle을해야하고 그것은 살균을 방해하지 않고 작동 할 것입니다.
yglodt

Angular8에서 나를 위해 일했습니다. 살균이 가장 좋다고 생각합니다 ... 이유가 있습니다. @yglodt.
Sean Halls

67

이것을 사용하십시오 <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div> 문제가 해결되었습니다.


안전하고 간단합니다.
켄 모어

@Kenmore의 친절한 말에 감사드립니다. 도움이 될 수있어서 기쁩니다. 건배.
iRedia Ebikade

@ Sammy-RogersGeek 이미지 태그에 동일한 코드를 작성할 수 있습니까?
Arjun

당신은 내 하루를 구합니다!
VAdaihiep

Eloquent. 감사합니다.
Mindsect 팀

52

선형 그라데이션이있는 배경 이미지 ( *ngFor)

전망:

<div [style.background-image]="getBackground(trendingEntity.img)" class="trending-content">
</div>

수업:

import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';

constructor(private _sanitizer: DomSanitizer) {}

getBackground(image) {
    return this._sanitizer.bypassSecurityTrustStyle(`linear-gradient(rgba(29, 29, 29, 0), rgba(16, 16, 23, 0.5)), url(${image})`);
}

1
당신은 내 일 저장
Thamaraiselvam

1
완벽하게 작동합니다 :))
Abhijit 스리 바스타

@AbhijitSrivastava 나는 thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url ($ {thumbnail}) )[style.backgroundImage]="thumbnailMediumIcon". 어떤 Angular 버전을 사용하셨습니까? 나는 또한 배경 이미지를 시도했다. 여전히 작동합니까? 다른 접근 방식이 마음에 들지 않습니까?
MTZ

1
@AbhijitSrivastava 감사합니다! 내 실수 thumbnail로 URL 대신 blob ( )을 전달했습니다
MTZ

1
getBackgroundAngular는 bypassSecurityTrustStyle뷰가 새로 고쳐질 때마다 호출해야하므로 뷰 내부 를 호출하지 않는 것이 좋습니다 . 내부에 console.log를 추가하는 것을 테스트하기 위해 getBackground각 클릭 또는 사용자 스크롤 이벤트에서 함수가 호출되는 것을 볼 수 있습니다
Marcin

9

확인 Angular2 편리 파이프 : 사용법 :

  1. SafePipe코드 교체 DomSanitizationService와 함께DomSanitizer

  2. SafePipe당신 의 경우를 제공 하십시오NgModule

  3. <div [style.background-image]="'url(' + your_property + ')' | safe: 'style'"></div>


8

https://angular.io/api/platform-browser/DomSanitizer 의 문서에 따르면 이 작업을 수행하는 올바른 방법은 sanitize를 사용하는 것 같습니다. 적어도 Angular 7에서는 (이전과 변경되었는지 모르겠습니다). 이것은 나를 위해 일했습니다.

import { Component, OnInit, Input, SecurityContext } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

constructor(
    private sanitizer: DomSanitizer
) { }

this.sanitizer.sanitize(SecurityContext.STYLE, 'url(' + this.image + ')');

Re SecurityContext, https://angular.io/api/core/SecurityContext 참조 . 기본적으로 다음 열거 형입니다.

enum SecurityContext {
  NONE: 0
  HTML: 1
  STYLE: 2
  SCRIPT: 3
  URL: 4
  RESOURCE_URL: 5
}

1
이것은 가장 최신 답변입니다. 단축 될 수도 있습니다.this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema

@Zahema 나는 그것이 제공된 대답과 동일하다고 생각하지 않습니다. bypassSecurityTrustStyle보안을 sanitize(SecurityContext.STYLE, style)강화 하면서 보안을 무시합니다 . 내가 사용하는 것이 좋습니다 것이 sanitize적절한로 SecurityContext.
Oscar

@Zahema bypassSecurityTrustStyle는 .NET 에서 액세스 할 수없는 (적어도 할 수 없었던) 개체를 반환합니다 [ngStyle]. sanitize(SecurityContext.STYLE, style)대신 일반 문자열을 반환합니다.
Alexander Fink

@Oscar 동의하지만 어떤 이유로 모든 시나리오에서 항상 예상대로 작동하지는 않습니다. bypassSecurityTrustStyle기본적으로 무차별 적으로 강제하는 것입니다.
Zahema

6

Angular 7의 이미지 태그에 동적 URL을 추가하는 동안 동일한 문제가 발생했습니다. 많이 검색하여이 솔루션을 찾았습니다.

먼저 컴포넌트 파일에 아래 코드를 작성하십시오.

constructor(private sanitizer: DomSanitizer) {}
public getSantizeUrl(url : string) {
    return this.sanitizer.bypassSecurityTrustUrl(url);
}

이제 html 이미지 태그에 다음과 같이 작성할 수 있습니다.

<img class="image-holder" [src]=getSantizeUrl(item.imageUrl) />

item.imageUrl 대신 요구 사항에 따라 작성할 수 있습니다.

이 사이트에서 참조를 얻었습니다. 동적 URL . 이 솔루션이 도움이되기를 바랍니다. :)


이 이미지 작동하지만, 질문이 대답은 관련이 배경 이미지로 사용, 스타일 URL에 대해이었다
Amirreza

3

실제로 삭제 된 것이있는 경우에만이 경고를 인쇄하는 공개 된 문제가 있습니다. https://github.com/angular/angular/pull/10272

아무것도 삭제되지 않았을 때이 경고가 인쇄 될 때 자세히 읽지 않았습니다.


3
여기에 올 수있는 사람들을 위해 : 그 문제는 해결되었습니다. 항상이 아니라 HTML을 삭제 한 경우에만 경고를 인쇄합니다.
flamusdiu

그렇게하는 것이 잘못된 관행인지 알고 싶었습니다. 이 경고를받지 않으려 고해야합니까?
Amrit

사용자가 제공 한 콘텐츠 (입력 필드의 텍스트, 데이터베이스 또는 제어하지 않는 다른 소스에서로드 된 사용자 콘텐츠 등)에이를 적용 할 때는 매우 주의 해야합니다 . 이렇게하면 Angular에 본질적으로 안전하지 않은 콘텐츠는 신뢰할 수 있습니다. 상수, 빌드시 전달되는 환경 변수, 이러한 안전한 값에서만 계산 된 값과 같이 제어하는 ​​정적 콘텐츠에 사용하는 것은 괜찮습니다.
Günter Zöchbauer

1

경고에서 제안하는 작업을 이미 수행하고있는 사람을 위해 Angular 5로 업그레이드 SafeStyle하기 string전에 템플릿에서 사용 하기 전에 유형을 매핑 해야했습니다. Angular 5 이후에는 더 이상 그렇지 않습니다. 나는이 내 모델을 변경했다 image: SafeStyle대신을 image: string. 이미 [style.background-image]속성 바인딩을 사용 하고 전체 URL에서 보안을 우회했습니다.

이것이 누군가를 돕기를 바랍니다.


0

Angular는 전용 살균 라이브러리가 아니기 때문에 위험을 감수하지 않는 의심스러운 콘텐츠에 지나치게 열광합니다. 예를 들어 DOMPurify와 같은 전용 라이브러리에 삭제를 위임 할 수 있습니다. 다음은 Angular와 함께 DOMPurify를 쉽게 사용하기 위해 만든 래퍼 라이브러리입니다.

https://github.com/TinkoffCreditSystems/ng-dompurify

HTML을 선언적으로 삭제하는 파이프가 있습니다.

<div [innerHtml]="value | dompurify"></div>

한 가지 명심해야 할 점은 DOMPurify가 HTML / SVG를 삭제하는 데 적합하지만 CSS가 아니라는 것입니다. 따라서 Angular의 CSS 새니 타이 저를 제공하여 CSS를 처리 할 수 ​​있습니다.

import {NgModule, ɵ_sanitizeStyle} from '@angular/core';
import {SANITIZE_STYLE} from '@tinkoff/ng-dompurify';

@NgModule({
    // ...
    providers: [
        {
            provide: SANITIZE_STYLE,
            useValue: ɵ_sanitizeStyle,
        },
    ],
    // ...
})
export class AppModule {}

내부적 인-hense ɵ접두사이지만 Angular 팀은 어쨌든 자신의 패키지에서 그것을 사용하는 방법입니다.


-1

제 경우에는 디스플레이 구성 요소에 도달하기 전에 이미지 URL을 가져와 배경 이미지로 사용하고 싶으므로 해당 URL을 사용하려면 Angular에 안전하고 사용할 수 있다고 알려야합니다.

.ts 파일에서

userImage: SafeStyle;
ngOnInit(){
    this.userImage = this.sanitizer.bypassSecurityTrustStyle('url(' + sessionStorage.getItem("IMAGE") + ')');
}

.html 파일

<div mat-card-avatar class="nav-header-image" [style.background-image]="userImage"></div>

답변을 수정하여 설명하고 기존 답변보다 더 나은 답변 인 이유를 적어주세요.
Dragonthoughts
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.