Repository: angular/angular
File: packages/core/src/sanitization/sanitization.ts (TypeScript)

Code before:
  }
}

export function validateAgainstEventAttributes(name: string) {
  if (name.toLowerCase().startsWith('on')) {
    const errorMessage =
      `Binding to event attribute '${name}' is disallowed for security reasons, ` +
      `please use (${name.slice(2)})=...`;
    throw new RuntimeError(RuntimeErrorCode.INVALID_EVENT_BINDING, errorMessage);
  }
}

function getSanitizer(): Sanitizer | null {
  const lView = getLView();
  return lView && lView[ENVIRONMENT].sanitizer;
}

const attributeName: ReadonlyArray<string> = ['attributename'];

/**
 * @remarks Keep this in sync with DOM Security Schema.
 * @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
 */
const SECURITY_SENSITIVE_ELEMENTS: Readonly<Record<string, ReadonlyArray<string>>> = {
  'iframe': ['sandbox', 'allow', 'allowfullscreen', 'referrerpolicy', 'csp', 'fetchpriority'],
  'animate': attributeName,
  'set': attributeName,
  'animatemotion': attributeName,
  'animatetransform': attributeName,
};

/**
 * Validates that the attribute binding is safe to use.
 *
 * @param value The value of the attribute.
 * @param tagName The name of the tag.
 * @param attributeName The name of the attribute.
 */
export function ɵɵValidateAttribute(value: any, tagName: string, attributeName: string) {
  const lowerCaseTagName = tagName.toLowerCase();
  const lowerCaseAttrName = attributeName.toLowerCase();
  if (!SECURITY_SENSITIVE_ELEMENTS[lowerCaseTagName]?.includes(lowerCaseAttrName)) {
    return value;
  }

  // Restrict any dynamic bindings of security-sensitive attributes/properties
  // on an <iframe> for security reasons.
  if (lowerCaseTagName === 'iframe') {
    return validateIframeAttribute(value, tagName, attributeName);
  }


Review comment (security):
nit: we can add a similar note to the `dom_security_schema.ts` too.

Code after:
      `please use (${name.slice(2)})=...` +
      `\nIf '${name}' is a directive input, make sure the directive is imported by the` +
      ` current module.`;
    throw new RuntimeError(RuntimeErrorCode.INVALID_EVENT_BINDING, errorMessage);
  }
}

export function validateAgainstEventAttributes(name: string) {
  if (name.toLowerCase().startsWith('on')) {
    const errorMessage =
      `Binding to event attribute '${name}' is disallowed for security reasons, ` +
      `please use (${name.slice(2)})=...`;
    throw new RuntimeError(RuntimeErrorCode.INVALID_EVENT_BINDING, errorMessage);
  }
}

function getSanitizer(): Sanitizer | null {
  const lView = getLView();
  return lView && lView[ENVIRONMENT].sanitizer;
}

const attributeName: ReadonlySet<string> = new Set(['attributename']);

/**
 * @remarks Keep this in sync with DOM Security Schema.
 * @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
 */
const SECURITY_SENSITIVE_ELEMENTS: Readonly<Record<string, ReadonlySet<string>>> = {
  'iframe': new Set([
    'sandbox',
    'allow',
    'allowfullscreen',
    'referrerpolicy',
    'csp',
    'fetchpriority',
  ]),
  'animate': attributeName,
  'set': attributeName,
  'animatemotion': attributeName,
  'animatetransform': attributeName,
};

/**
 * Validates that the attribute binding is safe to use.
 *
 * @param value The value of the attribute.
 * @param tagName The name of the tag.
 * @param attributeName The name of the attribute.
 */
export function ɵɵvalidateAttribute(
  value: unknown,