preventCsrf.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334
  1. import MIMEType from 'whatwg-mimetype';
  2. import { BadRequestError } from './internalErrorClasses.js';
  3. export const recommendedCsrfPreventionRequestHeaders = [
  4. 'x-apollo-operation-name',
  5. 'apollo-require-preflight',
  6. ];
  7. const NON_PREFLIGHTED_CONTENT_TYPES = [
  8. 'application/x-www-form-urlencoded',
  9. 'multipart/form-data',
  10. 'text/plain',
  11. ];
  12. export function preventCsrf(headers, csrfPreventionRequestHeaders) {
  13. const contentType = headers.get('content-type');
  14. if (contentType !== undefined) {
  15. const contentTypeParsed = MIMEType.parse(contentType);
  16. if (contentTypeParsed === null) {
  17. return;
  18. }
  19. if (!NON_PREFLIGHTED_CONTENT_TYPES.includes(contentTypeParsed.essence)) {
  20. return;
  21. }
  22. }
  23. if (csrfPreventionRequestHeaders.some((header) => {
  24. const value = headers.get(header);
  25. return value !== undefined && value.length > 0;
  26. })) {
  27. return;
  28. }
  29. throw new BadRequestError(`This operation has been blocked as a potential Cross-Site Request Forgery ` +
  30. `(CSRF). Please either specify a 'content-type' header (with a type that ` +
  31. `is not one of ${NON_PREFLIGHTED_CONTENT_TYPES.join(', ')}) or provide ` +
  32. `a non-empty value for one of the following headers: ${csrfPreventionRequestHeaders.join(', ')}\n`);
  33. }
  34. //# sourceMappingURL=preventCsrf.js.map