Expand Minimize

Don't use component properties without escaping

Component properties values should be escaped before using them

CheckId SPF020802
TypeName DontUseWebPartPropertiesWithoutEscaping
Severity CriticalError
Type JavaScriptFile

Before using values of web part properties you should always escape them first to prevent possible code injections.

By default SharePoint Framework passes values of web part properties into the code without escaping them. This makes the web part code vulnerable to script injections. Using the standard escape() method from the @microsoft/sp-core-library package, you should escape the value of the web part property before using it in your code.

Bad practice - not escaping web part properties before using them

import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './Weather.module.scss';
import * as strings from 'weatherStrings';
import { IWeatherWebPartProps } from './IWeatherWebPartProps';

import * as jQuery from 'jquery';
require('simpleWeather');

export default class WeatherWebPart extends BaseClientSideWebPart<IWeatherWebPartProps> {
  private container: JQuery;

  public render(): void {
    if (this.renderedOnce === false) {
      this.domElement.innerHTML = `<div class="${styles.weather}"></div>`;
    }

    this.container = jQuery(`.${styles.weather}`, this.domElement);

    const location: string = this.properties.location;

    if (!location || location.length === 0) {
      this.container.html('<p>Please specify a location</p>');
      return;
    }

    const webPart: WeatherWebPart = this;

    (jQuery as any).simpleWeather({
      location: location,
      woeid: '',
      unit: 'c',
      success: (weather: any): void => {
        const html: string =
          `<h2><i class="icon${weather.code}"></i> ${weather.temp}°${weather.units.temp}</h2>
           <ul><li>${weather.city} ${weather.region}</li></ul>`;
        webPart.container.html(html).removeAttr('style').css('background', `url('http://loremflickr.com/500/139/${location}')`);
      },
      error: (error: any): void => {
        webPart.container.html(`<p>${error.message}</p>`).removeAttr('style');
      }
    });
  }

  // ...
}


Good practice - escaping web part properties before using them
import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './Weather.module.scss';
import * as strings from 'weatherStrings';
import { IWeatherWebPartProps } from './IWeatherWebPartProps';

import * as jQuery from 'jquery';
require('simpleWeather');

export default class WeatherWebPart extends BaseClientSideWebPart<IWeatherWebPartProps> {
  private container: JQuery;

  public render(): void {
    if (this.renderedOnce === false) {
      this.domElement.innerHTML = `<div class="${styles.weather}"></div>`;
    }

    this.container = jQuery(`.${styles.weather}`, this.domElement);

    const location: string = escape(this.properties.location);

    if (!location || location.length === 0) {
      this.container.html('<p>Please specify a location</p>');
      return;
    }

    const webPart: WeatherWebPart = this;

    (jQuery as any).simpleWeather({
      location: location,
      woeid: '',
      unit: 'c',
      success: (weather: any): void => {
        const html: string =
          `<h2><i class="icon${weather.code}"></i> ${weather.temp}°${weather.units.temp}</h2>
           <ul><li>${weather.city} ${weather.region}</li></ul>`;
        webPart.container.html(html).removeAttr('style').css('background', `url('http://loremflickr.com/500/139/${location}')`);
      },
      error: (error: any): void => {
        webPart.container.html(`<p>${error.message}</p>`).removeAttr('style');
      }
    });
  }

  // ...
}

Disclaimer: The views and opinions expressed in this documentation and in SPCAF do not necessarily reflect the opinions and recommendations of Microsoft or any member of Microsoft. SPCAF and RENCORE are registered trademarks of Rencore. All other trademarks, service marks, collective marks, copyrights, registered names, and marks used or cited by this documentation are the property of their respective owners.