Language: TypeScript
Label: safe
CWE: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.

Code:
export async function detectVariables(
  context: BuilderContext,
  searchPattern?: string | null
): Promise<NgsscContext> {
  const projectName = context.target && context.target.project;
  if (!projectName) {
    throw new Error('The builder requires a target.');
  }

  const projectMetadata = await context.getProjectMetadata(projectName);
  const sourceRoot = projectMetadata.sourceRoot as string | undefined;
  const defaultSearchPattern = sourceRoot ? `${sourceRoot}/**/!(*server*).ts` : '**/!(*server*).ts';

  const detector = new VariableDetector(context.logger);
  const typeScriptFiles = await glob(searchPattern || defaultSearchPattern, {
    absolute: true,
    cwd: context.workspaceRoot,
    ignore: ['**/node_modules/**', '**/*.spec.ts', '**/*.d.ts'],
  });
  let ngsscContext: NgsscContext | null = null;
  for (const file of typeScriptFiles) {
    const fileContent = await readFileAsync(file, 'utf8');
    const innerNgsscContext = detector.detect(fileContent);
    if (!innerNgsscContext.variables.length) {
      continue;
    } else if (!ngsscContext) {
      ngsscContext = innerNgsscContext;
      continue;
    }
    if (ngsscContext.variant !== innerNgsscContext.variant) {
      context.logger.info(
        `ngssc: Detected conflicting variants (${ngsscContext.variant} and ${innerNgsscContext.variant}) being used`
      );
    }
    ngsscContext.variables.push(
      ...innerNgsscContext.variables.filter((v) => !ngsscContext!.variables.includes(v))
    );
  }
  if (!ngsscContext) {
    return { variant: 'process', variables: [] };
  }

  context.logger.info(
    `ngssc: Detected variant '${ngsscContext.variant}' with variables ` +
      `'${ngsscContext.variables.join(', ')}'`
  );

  return ngsscContext;
}