hpkp.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import ExternalLink from 'sentry/components/links/externalLink';
  2. import LoadingError from 'sentry/components/loadingError';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. import Panel from 'sentry/components/panels/panel';
  5. import PanelBody from 'sentry/components/panels/panelBody';
  6. import PanelHeader from 'sentry/components/panels/panelHeader';
  7. import PreviewFeature from 'sentry/components/previewFeature';
  8. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  9. import {t, tct} from 'sentry/locale';
  10. import type {ProjectKey} from 'sentry/types/project';
  11. import {useApiQuery} from 'sentry/utils/queryClient';
  12. import routeTitleGen from 'sentry/utils/routeTitle';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import {useParams} from 'sentry/utils/useParams';
  15. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  16. import ReportUri, {
  17. getSecurityDsn,
  18. } from 'sentry/views/settings/projectSecurityHeaders/reportUri';
  19. function getInstructions(keyList: ProjectKey[]) {
  20. return (
  21. 'def middleware(request, response):\n' +
  22. " response['Public-Key-Pins'] = \\\n" +
  23. ' \'pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; \' \\\n' +
  24. ' \'pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="; \' \\\n' +
  25. " 'max-age=5184000; includeSubDomains; ' \\\n" +
  26. ` \'report-uri="${getSecurityDsn(keyList)}"\' \n` +
  27. ' return response\n'
  28. );
  29. }
  30. function getReportOnlyInstructions(keyList: ProjectKey[]) {
  31. return (
  32. 'def middleware(request, response):\n' +
  33. " response['Public-Key-Pins-Report-Only'] = \\\n" +
  34. ' \'pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; \' \\\n' +
  35. ' \'pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="; \' \\\n' +
  36. " 'max-age=5184000; includeSubDomains; ' \\\n" +
  37. ` \'report-uri="${getSecurityDsn(keyList)}"\' \n` +
  38. ' return response\n'
  39. );
  40. }
  41. function ProjectHpkpReports() {
  42. const organization = useOrganization();
  43. const {projectId} = useParams();
  44. const {
  45. data: keyList,
  46. isLoading,
  47. isError,
  48. refetch,
  49. } = useApiQuery<ProjectKey[]>([`/projects/${organization.slug}/${projectId}/keys/`], {
  50. staleTime: 0,
  51. });
  52. if (isLoading) {
  53. return <LoadingIndicator />;
  54. }
  55. if (isError) {
  56. return <LoadingError onRetry={refetch} />;
  57. }
  58. return (
  59. <div>
  60. <SentryDocumentTitle
  61. title={routeTitleGen(t('HTTP Public Key Pinning (HPKP)'), projectId, false)}
  62. />
  63. <SettingsPageHeader title={t('HTTP Public Key Pinning')} />
  64. <PreviewFeature />
  65. <ReportUri keyList={keyList} orgId={organization.slug} projectId={projectId} />
  66. <Panel>
  67. <PanelHeader>{t('About')}</PanelHeader>
  68. <PanelBody withPadding>
  69. <p>
  70. {tct(
  71. `[link:HTTP Public Key Pinning]
  72. (HPKP) is a security feature that tells a web client to associate a specific
  73. cryptographic public key with a certain web server to decrease the risk of MITM
  74. attacks with forged certificates. It's enforced by browser vendors, and Sentry
  75. supports capturing violations using the standard reporting hooks.`,
  76. {
  77. link: (
  78. <ExternalLink href="https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning" />
  79. ),
  80. }
  81. )}
  82. </p>
  83. <p>
  84. {t(
  85. `To configure HPKP reports
  86. in Sentry, you'll need to send a header from your server describing your
  87. policy, as well specifying the authenticated Sentry endpoint.`
  88. )}
  89. </p>
  90. <p>
  91. {t(
  92. 'For example, in Python you might achieve this via a simple web middleware'
  93. )}
  94. </p>
  95. <pre>{getInstructions(keyList)}</pre>
  96. <p>
  97. {t(`Alternatively you can setup HPKP reports to simply send reports rather than
  98. actually enforcing the policy`)}
  99. </p>
  100. <pre>{getReportOnlyInstructions(keyList)}</pre>
  101. <p>
  102. {tct(
  103. `We recommend setting this up to only run on a percentage of requests, as
  104. otherwise you may find that you've quickly exhausted your quota. For more
  105. information, take a look at [link:the documentation on MDN].`,
  106. {
  107. link: (
  108. <ExternalLink href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning" />
  109. ),
  110. }
  111. )}
  112. </p>
  113. </PanelBody>
  114. </Panel>
  115. </div>
  116. );
  117. }
  118. export default ProjectHpkpReports;