diff --git a/.eslintrc.js b/.eslintrc.js
index 93ff1d7b59..480b274fad 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -109,7 +109,7 @@ module.exports = defineConfig({
     'react/jsx-equals-spacing': 'error',
     'react/jsx-no-bind': 'error',
     'react/jsx-no-useless-fragment': 'error',
-    'react/jsx-no-target-blank': 'off',
+    'react/jsx-no-target-blank': ['error', { allowReferrer: true }],
     'react/jsx-tag-spacing': 'error',
     'react/jsx-uses-react': 'off', // not needed with new JSX transform
     'react/jsx-wrap-multilines': 'error',
diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb
index 48685db17a..3dca3a9614 100644
--- a/app/controllers/admin/base_controller.rb
+++ b/app/controllers/admin/base_controller.rb
@@ -8,6 +8,7 @@ module Admin
     layout 'admin'
 
     before_action :set_cache_headers
+    before_action :set_referrer_policy_header
 
     after_action :verify_authorized
 
@@ -17,6 +18,10 @@ module Admin
       response.cache_control.replace(private: true, no_store: true)
     end
 
+    def set_referrer_policy_header
+      response.headers['Referrer-Policy'] = 'same-origin'
+    end
+
     def set_user
       @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
     end
diff --git a/app/javascript/mastodon/components/attachment_list.jsx b/app/javascript/mastodon/components/attachment_list.jsx
index c5ac046751..f97e22f2d4 100644
--- a/app/javascript/mastodon/components/attachment_list.jsx
+++ b/app/javascript/mastodon/components/attachment_list.jsx
@@ -36,7 +36,7 @@ export default class AttachmentList extends ImmutablePureComponent {
 
             return (
               <li key={attachment.get('id')}>
-                <a href={displayUrl} target='_blank' rel='noopener noreferrer'>
+                <a href={displayUrl} target='_blank' rel='noopener'>
                   {compact && <Icon id='link' icon={LinkIcon} />}
                   {compact && ' ' }
                   {displayUrl ? filename(displayUrl) : <FormattedMessage id='attachments_list.unprocessed' defaultMessage='(unprocessed)' />}
diff --git a/app/javascript/mastodon/components/dropdown_menu.jsx b/app/javascript/mastodon/components/dropdown_menu.jsx
index d731a8e2d1..df0be8bc12 100644
--- a/app/javascript/mastodon/components/dropdown_menu.jsx
+++ b/app/javascript/mastodon/components/dropdown_menu.jsx
@@ -124,7 +124,7 @@ class DropdownMenu extends PureComponent {
 
     return (
       <li className={classNames('dropdown-menu__item', { 'dropdown-menu__item--dangerous': dangerous })} key={`${text}-${i}`}>
-        <a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex={0} ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
+        <a href={href} target={target} data-method={method} rel='noopener' role='button' tabIndex={0} ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
           {text}
         </a>
       </li>
diff --git a/app/javascript/mastodon/components/error_boundary.jsx b/app/javascript/mastodon/components/error_boundary.jsx
index 392a3ad61e..ca2f017f3b 100644
--- a/app/javascript/mastodon/components/error_boundary.jsx
+++ b/app/javascript/mastodon/components/error_boundary.jsx
@@ -98,7 +98,7 @@ export default class ErrorBoundary extends PureComponent {
             )}
           </p>
 
-          <p className='error-boundary__footer'>Mastodon v{version} 路 <a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='errors.unexpected_crash.report_issue' defaultMessage='Report issue' /></a> 路 <button onClick={this.handleCopyStackTrace} className={copied ? 'copied' : ''}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' /></button></p>
+          <p className='error-boundary__footer'>Mastodon v{version} 路 <a href={source_url} rel='noopener' target='_blank'><FormattedMessage id='errors.unexpected_crash.report_issue' defaultMessage='Report issue' /></a> 路 <button onClick={this.handleCopyStackTrace} className={copied ? 'copied' : ''}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' /></button></p>
         </div>
 
         <Helmet>
diff --git a/app/javascript/mastodon/components/follow_button.tsx b/app/javascript/mastodon/components/follow_button.tsx
index faf9d8bdb8..c62e76d4b5 100644
--- a/app/javascript/mastodon/components/follow_button.tsx
+++ b/app/javascript/mastodon/components/follow_button.tsx
@@ -88,7 +88,7 @@ export const FollowButton: React.FC<{
       <a
         href='/settings/profile'
         target='_blank'
-        rel='noreferrer noopener'
+        rel='noopener'
         className='button button-secondary'
       >
         {label}
diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx
index 59963a0a9f..95b06abc54 100644
--- a/app/javascript/mastodon/components/media_gallery.jsx
+++ b/app/javascript/mastodon/components/media_gallery.jsx
@@ -106,7 +106,7 @@ class Item extends PureComponent {
     if (attachment.get('type') === 'unknown') {
       return (
         <div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
-          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url') || attachment.get('url')} style={{ cursor: 'pointer' }} title={description} lang={lang} target='_blank' rel='noopener noreferrer'>
+          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url') || attachment.get('url')} style={{ cursor: 'pointer' }} title={description} lang={lang} target='_blank' rel='noopener'>
             <Blurhash
               hash={attachment.get('blurhash')}
               className='media-gallery__preview'
@@ -138,7 +138,7 @@ class Item extends PureComponent {
           href={attachment.get('remote_url') || originalUrl}
           onClick={this.handleClick}
           target='_blank'
-          rel='noopener noreferrer'
+          rel='noopener'
         >
           <img
             src={previewUrl}
diff --git a/app/javascript/mastodon/components/server_banner.jsx b/app/javascript/mastodon/components/server_banner.jsx
index b6ea01997b..989ac7f006 100644
--- a/app/javascript/mastodon/components/server_banner.jsx
+++ b/app/javascript/mastodon/components/server_banner.jsx
@@ -42,7 +42,7 @@ class ServerBanner extends PureComponent {
     return (
       <div className='server-banner'>
         <div className='server-banner__introduction'>
-          <FormattedMessage id='server_banner.is_one_of_many' defaultMessage='{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.' values={{ domain: <strong>{domain}</strong>, mastodon: <a href='https://joinmastodon.org' target='_blank'>Mastodon</a> }} />
+          <FormattedMessage id='server_banner.is_one_of_many' defaultMessage='{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.' values={{ domain: <strong>{domain}</strong>, mastodon: <a href='https://joinmastodon.org' target='_blank' rel='noopener'>Mastodon</a> }} />
         </div>
 
         <Link to='/about'>
diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx
index cf6fe86c3d..9f57629807 100644
--- a/app/javascript/mastodon/components/status.jsx
+++ b/app/javascript/mastodon/components/status.jsx
@@ -293,7 +293,7 @@ class Status extends ImmutablePureComponent {
     if (e?.button === 0 && !(e?.ctrlKey || e?.metaKey)) {
       history.push(path);
     } else if (e?.button === 1 || (e?.button === 0 && (e?.ctrlKey || e?.metaKey))) {
-      window.open(path, '_blank', 'noreferrer noopener');
+      window.open(path, '_blank', 'noopener');
     }
   };
 
diff --git a/app/javascript/mastodon/features/about/index.jsx b/app/javascript/mastodon/features/about/index.jsx
index 24141b13cb..34e84506f0 100644
--- a/app/javascript/mastodon/features/about/index.jsx
+++ b/app/javascript/mastodon/features/about/index.jsx
@@ -123,7 +123,7 @@ class About extends PureComponent {
           <div className='about__header'>
             <ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />
             <h1>{isLoading ? <Skeleton width='10ch' /> : server.get('domain')}</h1>
-            <p><FormattedMessage id='about.powered_by' defaultMessage='Decentralized social media powered by {mastodon}' values={{ mastodon: <a href='https://joinmastodon.org' className='about__mail' target='_blank'>Mastodon</a> }} /></p>
+            <p><FormattedMessage id='about.powered_by' defaultMessage='Decentralized social media powered by {mastodon}' values={{ mastodon: <a href='https://joinmastodon.org' className='about__mail' target='_blank' rel='noopener'>Mastodon</a> }} /></p>
           </div>
 
           <div className='about__meta'>
diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx
index 6583c1f604..fc38adc131 100644
--- a/app/javascript/mastodon/features/account/components/header.jsx
+++ b/app/javascript/mastodon/features/account/components/header.jsx
@@ -421,7 +421,7 @@ class Header extends ImmutablePureComponent {
 
         <div className='account__header__bar'>
           <div className='account__header__tabs'>
-            <a className='avatar' href={account.get('avatar')} rel='noopener noreferrer' target='_blank' onClick={this.handleAvatarClick}>
+            <a className='avatar' href={account.get('avatar')} rel='noopener' target='_blank' onClick={this.handleAvatarClick}>
               <Avatar account={suspended || hidden ? undefined : account} size={90} />
             </a>
 
diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
index 9d6ff5226a..022c9baaf7 100644
--- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
+++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
@@ -90,8 +90,8 @@ describe('emoji', () => {
     });
 
     it('keeps ordering as expected (issue fixed by PR 20677)', () => {
-      expect(emojify('<p>馃挄 <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>'))
-        .toEqual('<p><picture><img draggable="false" class="emojione" alt="馃挄" title=":two_hearts:" src="/emoji/1f495.svg"></picture> <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>');
+      expect(emojify('<p>馃挄 <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener" target="_blank">#<span>foo</span></a> test: foo.</p>'))
+        .toEqual('<p><picture><img draggable="false" class="emojione" alt="馃挄" title=":two_hearts:" src="/emoji/1f495.svg"></picture> <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener" target="_blank">#<span>foo</span></a> test: foo.</p>');
     });
   });
 });
diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.jsx b/app/javascript/mastodon/features/getting_started/components/announcements.jsx
index 3c0b53b9e7..713ad9f069 100644
--- a/app/javascript/mastodon/features/getting_started/components/announcements.jsx
+++ b/app/javascript/mastodon/features/getting_started/components/announcements.jsx
@@ -85,7 +85,7 @@ class ContentWithRouter extends ImmutablePureComponent {
       }
 
       link.setAttribute('target', '_blank');
-      link.setAttribute('rel', 'noopener noreferrer');
+      link.setAttribute('rel', 'noopener');
     }
   }
 
diff --git a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
index 3075aff31b..65ccd7c276 100644
--- a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
+++ b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
@@ -28,7 +28,7 @@ export const RelationshipsSeveranceEvent = ({ type, target, followingCount, foll
 
       <div className='notification-group__main'>
         <p>{intl.formatMessage(messages[type], { from: <strong>{domain}</strong>, target: <strong>{target}</strong>, followingCount, followersCount })}</p>
-        <a href='/severed_relationships' target='_blank' rel='noopener noreferrer' className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></a>
+        <a href='/severed_relationships' target='_blank' rel='noopener' className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></a>
       </div>
     </div>
   );
diff --git a/app/javascript/mastodon/features/notifications/components/report.jsx b/app/javascript/mastodon/features/notifications/components/report.jsx
index 52d6bfee9d..ed043ae789 100644
--- a/app/javascript/mastodon/features/notifications/components/report.jsx
+++ b/app/javascript/mastodon/features/notifications/components/report.jsx
@@ -55,7 +55,7 @@ class Report extends ImmutablePureComponent {
           </div>
 
           <div className='notification__report__actions'>
-            <a href={`/admin/reports/${report.get('id')}`} className='button' target='_blank' rel='noopener noreferrer'>{intl.formatMessage(messages.openReport)}</a>
+            <a href={`/admin/reports/${report.get('id')}`} className='button' target='_blank' rel='noopener'>{intl.formatMessage(messages.openReport)}</a>
           </div>
         </div>
       </div>
diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx
index ca0d1bc850..88e65c668b 100644
--- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx
+++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx
@@ -70,7 +70,7 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
         if (button === 0 && !(ctrlKey || metaKey)) {
           history.push(path);
         } else if (button === 1 || (button === 0 && (ctrlKey || metaKey))) {
-          window.open(path, '_blank', 'noreferrer noopener');
+          window.open(path, '_blank', 'noopener');
         }
       }
 
diff --git a/app/javascript/mastodon/features/standalone/status/index.tsx b/app/javascript/mastodon/features/standalone/status/index.tsx
index d5cb7e7f40..3b68c5c176 100644
--- a/app/javascript/mastodon/features/standalone/status/index.tsx
+++ b/app/javascript/mastodon/features/standalone/status/index.tsx
@@ -61,7 +61,7 @@ const Embed: React.FC<{ id: string }> = ({ id }) => {
         className='embed__overlay'
         href={permalink}
         target='_blank'
-        rel='noreferrer noopener'
+        rel='noopener'
         aria-label=''
       />
     </div>
diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx
index 136a5568a4..f8d5a26aff 100644
--- a/app/javascript/mastodon/features/status/components/card.jsx
+++ b/app/javascript/mastodon/features/status/components/card.jsx
@@ -208,7 +208,7 @@ export default class Card extends PureComponent {
               <div className='status-card__actions' onClick={this.handleEmbedClick} role='none'>
                 <div>
                   <button type='button' onClick={this.handleEmbedClick}><Icon id='play' icon={PlayArrowIcon} /></button>
-                  <a href={card.get('url')} onClick={this.handleExternalLinkClick} target='_blank' rel='noopener noreferrer'><Icon id='external-link' icon={OpenInNewIcon} /></a>
+                  <a href={card.get('url')} onClick={this.handleExternalLinkClick} target='_blank' rel='noopener'><Icon id='external-link' icon={OpenInNewIcon} /></a>
                 </div>
               </div>
             ) : spoilerButton}
@@ -219,7 +219,7 @@ export default class Card extends PureComponent {
       return (
         <div className={classNames('status-card', { expanded: largeImage })} ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? 'button' : null}>
           {embed}
-          <a href={card.get('url')} target='_blank' rel='noopener noreferrer'>{description}</a>
+          <a href={card.get('url')} target='_blank' rel='noopener'>{description}</a>
         </div>
       );
     } else if (card.get('image')) {
@@ -239,7 +239,7 @@ export default class Card extends PureComponent {
 
     return (
       <>
-        <a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
+        <a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener' ref={this.setRef}>
           {embed}
           {description}
         </a>
diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.jsx b/app/javascript/mastodon/features/ui/components/actions_modal.jsx
index 4e0879580b..851f828b4e 100644
--- a/app/javascript/mastodon/features/ui/components/actions_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/actions_modal.jsx
@@ -24,7 +24,7 @@ export default class ActionsModal extends ImmutablePureComponent {
 
     return (
       <li key={`${text}-${i}`}>
-        <a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
+        <a href={href} target='_blank' rel='noopener' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
           {icon && <IconButton title={text} icon={icon} iconComponent={iconComponent} role='presentation' tabIndex={-1} inverted />}
           <div>
             <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
diff --git a/app/javascript/mastodon/features/ui/components/link_footer.tsx b/app/javascript/mastodon/features/ui/components/link_footer.tsx
index 06cb92fe4f..cbfb6a3114 100644
--- a/app/javascript/mastodon/features/ui/components/link_footer.tsx
+++ b/app/javascript/mastodon/features/ui/components/link_footer.tsx
@@ -26,7 +26,7 @@ export const LinkFooter: React.FC<{
         {statusPageUrl && (
           <>
             <DividingCircle />
-            <a href={statusPageUrl} target='_blank' rel='noopener noreferrer'>
+            <a href={statusPageUrl} target='_blank' rel='noopener'>
               <FormattedMessage id='footer.status' defaultMessage='Status' />
             </a>
           </>
@@ -72,15 +72,11 @@ export const LinkFooter: React.FC<{
 
       <p>
         <strong>Mastodon</strong>:{' '}
-        <a href='https://joinmastodon.org' target='_blank' rel='noreferrer'>
+        <a href='https://joinmastodon.org' target='_blank' rel='noopener'>
           <FormattedMessage id='footer.about' defaultMessage='About' />
         </a>
         <DividingCircle />
-        <a
-          href='https://joinmastodon.org/apps'
-          target='_blank'
-          rel='noreferrer'
-        >
+        <a href='https://joinmastodon.org/apps' target='_blank' rel='noopener'>
           <FormattedMessage id='footer.get_app' defaultMessage='Get the app' />
         </a>
         <DividingCircle />
@@ -91,7 +87,7 @@ export const LinkFooter: React.FC<{
           />
         </Link>
         <DividingCircle />
-        <a href={source_url} rel='noopener noreferrer' target='_blank'>
+        <a href={source_url} rel='noopener' target='_blank'>
           <FormattedMessage
             id='footer.source_code'
             defaultMessage='View source code'
diff --git a/app/lib/text_formatter.rb b/app/lib/text_formatter.rb
index 5e8e73a217..7fbb6fce12 100644
--- a/app/lib/text_formatter.rb
+++ b/app/lib/text_formatter.rb
@@ -7,7 +7,7 @@ class TextFormatter
 
   URL_PREFIX_REGEX = %r{\A(https?://(www\.)?|xmpp:)}
 
-  DEFAULT_REL = %w(nofollow noopener noreferrer).freeze
+  DEFAULT_REL = %w(nofollow noopener).freeze
 
   DEFAULT_OPTIONS = {
     multiline: true,
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index d20266aa2c..c1e47d5b32 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -44,7 +44,7 @@
         = t("statuses.visibilities.#{status.visibility}")
         路
 
-        = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', rel: 'noopener noreferrer' do
+        = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', rel: 'noopener' do
           = t('admin.statuses.view_publicly')
 
         - if status.proper.sensitive?
diff --git a/app/views/admin/reports/actions/preview.html.haml b/app/views/admin/reports/actions/preview.html.haml
index 79c444453f..5a90bf1b8f 100644
--- a/app/views/admin/reports/actions/preview.html.haml
+++ b/app/views/admin/reports/actions/preview.html.haml
@@ -63,7 +63,7 @@
                       = material_symbol 'link'
                       = media_attachment.file_file_name
                 .strike-card__statuses-list__item__meta
-                  = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener noreferrer' do
+                  = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener' do
                     %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
                   - unless status.application.nil?
                     路
diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml
index 1ff4763158..7328eeb0a7 100644
--- a/app/views/admin/statuses/show.html.haml
+++ b/app/views/admin/statuses/show.html.haml
@@ -9,7 +9,7 @@
                data: { confirm: t('admin.reports.are_you_sure') },
                name: :report,
                type: :submit
-  = link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank', rel: 'noopener noreferrer'
+  = link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank', rel: 'noopener'
 
 %h3= t('admin.statuses.metadata')
 
diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml
index 462ca312a0..0c8b2eaec0 100644
--- a/app/views/admin/tags/show.html.haml
+++ b/app/views/admin/tags/show.html.haml
@@ -6,7 +6,7 @@
     .time-period
       = date_range(@time_period)
 
-  = link_to t('admin.tags.open'), tag_url(@tag), class: 'button', target: '_blank', rel: 'noopener noreferrer'
+  = link_to t('admin.tags.open'), tag_url(@tag), class: 'button', target: '_blank', rel: 'noopener'
 
 - if current_user.can?(:view_dashboard)
   .dashboard
@@ -17,7 +17,7 @@
                               label: t('admin.trends.tags.dashboard.tag_accounts_measure'),
                               measure: 'tag_accounts',
                               params: { id: @tag.id },
-                              rel: 'noopener noreferrer',
+                              rel: 'noopener',
                               start_at: @time_period.first,
                               target: '_blank'
     .dashboard__item
diff --git a/app/views/admin/trends/statuses/_status.html.haml b/app/views/admin/trends/statuses/_status.html.haml
index 09547ff036..aa09803ed5 100644
--- a/app/views/admin/trends/statuses/_status.html.haml
+++ b/app/views/admin/trends/statuses/_status.html.haml
@@ -6,7 +6,7 @@
     .one-liner
       = admin_account_link_to status.account
 
-      = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', class: 'emojify', rel: 'noopener noreferrer' do
+      = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', class: 'emojify', rel: 'noopener' do
         = one_line_preview(status)
 
         - status.ordered_media_attachments.each do |media_attachment|
diff --git a/app/views/admin/trends/tags/_tag.html.haml b/app/views/admin/trends/tags/_tag.html.haml
index e0f9f39e47..1686c46652 100644
--- a/app/views/admin/trends/tags/_tag.html.haml
+++ b/app/views/admin/trends/tags/_tag.html.haml
@@ -8,7 +8,7 @@
 
       %br/
 
-      = link_to tag_path(tag), target: '_blank', rel: 'noopener noreferrer' do
+      = link_to tag_path(tag), target: '_blank', rel: 'noopener' do
         = t('admin.trends.tags.used_by_over_week', count: tag.history.reduce(0) { |sum, day| sum + day.accounts })
 
       - if tag.trendable?
diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml
index ae74f1dc63..c28e18522c 100644
--- a/app/views/application/_card.html.haml
+++ b/app/views/application/_card.html.haml
@@ -2,7 +2,7 @@
 - compact ||= false
 
 .card.h-card
-  = link_to account_url, target: '_blank', rel: 'noopener noreferrer' do
+  = link_to account_url, target: '_blank', rel: 'noopener' do
     - unless compact
       .card__img
         = image_tag account.header.url, alt: ''
diff --git a/app/views/disputes/strikes/_card.html.haml b/app/views/disputes/strikes/_card.html.haml
index 58965ad600..33e4099cf9 100644
--- a/app/views/disputes/strikes/_card.html.haml
+++ b/app/views/disputes/strikes/_card.html.haml
@@ -27,7 +27,7 @@
                   = material_symbol 'link'
                   = media_attachment.file_file_name
             .strike-card__statuses-list__item__meta
-              = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener noreferrer' do
+              = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener' do
                 %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
               - unless status.application.nil?
                 路
diff --git a/app/views/filters/statuses/_status_filter.html.haml b/app/views/filters/statuses/_status_filter.html.haml
index 3476869e60..9f4605a09c 100644
--- a/app/views/filters/statuses/_status_filter.html.haml
+++ b/app/views/filters/statuses/_status_filter.html.haml
@@ -19,11 +19,11 @@
         = media_attachment.file_file_name
 
     .detailed-status__meta
-      = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'name-tag', target: '_blank', rel: 'noopener noreferrer' do
+      = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'name-tag', target: '_blank', rel: 'noopener' do
         = image_tag(status.account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar')
         .username= status.account.acct
       路
-      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', rel: 'noopener noreferrer' do
+      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', rel: 'noopener' do
         %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
       - if status.edited?
         路
diff --git a/app/views/oauth/authorized_applications/index.html.haml b/app/views/oauth/authorized_applications/index.html.haml
index eb544d079b..3745ed219f 100644
--- a/app/views/oauth/authorized_applications/index.html.haml
+++ b/app/views/oauth/authorized_applications/index.html.haml
@@ -9,7 +9,7 @@
   - @applications.each do |application|
     .applications-list__item{ id: dom_id(application) }
       - if application.website.present?
-        = link_to application.name, application.website, target: '_blank', rel: 'noopener noreferrer', class: 'announcements-list__item__title'
+        = link_to application.name, application.website, target: '_blank', rel: 'noopener', class: 'announcements-list__item__title'
       - else
         %strong.announcements-list__item__title
           = application.name
diff --git a/app/views/redirects/show.html.haml b/app/views/redirects/show.html.haml
index aa0db350a8..984a70624b 100644
--- a/app/views/redirects/show.html.haml
+++ b/app/views/redirects/show.html.haml
@@ -11,4 +11,4 @@
   .redirect__message
     %h1= t('redirects.title', instance: site_hostname)
     %p= t('redirects.prompt')
-    %p= link_to @redirect_path, @redirect_path, rel: 'noreferrer noopener'
+    %p= link_to @redirect_path, @redirect_path, rel: 'noopener'
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 6d4c30cd20..4b1d327d93 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -153,7 +153,7 @@ Rails.application.configure do
     'X-Frame-Options' => 'DENY',
     'X-Content-Type-Options' => 'nosniff',
     'X-XSS-Protection' => '0',
-    'Referrer-Policy' => 'same-origin',
+    'Referrer-Policy' => ENV['ALLOW_REFERRER_ORIGIN'] == 'true' ? 'origin' : 'same-origin',
   }
 
   # TODO: Remove once devise-two-factor data migration complete
diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb
index c264548eb5..36c11a8263 100644
--- a/lib/sanitize_ext/sanitize_config.rb
+++ b/lib/sanitize_ext/sanitize_config.rb
@@ -114,7 +114,7 @@ class Sanitize
 
       add_attributes: {
         'a' => {
-          'rel' => 'nofollow noopener noreferrer',
+          'rel' => 'nofollow noopener',
           'target' => '_blank',
         },
       },
diff --git a/spec/lib/sanitize/config_spec.rb b/spec/lib/sanitize/config_spec.rb
index b1cab85827..b4c849c427 100644
--- a/spec/lib/sanitize/config_spec.rb
+++ b/spec/lib/sanitize/config_spec.rb
@@ -39,15 +39,15 @@ RSpec.describe Sanitize::Config do
     end
 
     it 'keeps a with href' do
-      expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+      expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener" target="_blank">Test</a>'
     end
 
     it 'keeps a with translate="no"' do
-      expect(Sanitize.fragment('<a href="http://example.com" translate="no">Test</a>', subject)).to eq '<a href="http://example.com" translate="no" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+      expect(Sanitize.fragment('<a href="http://example.com" translate="no">Test</a>', subject)).to eq '<a href="http://example.com" translate="no" rel="nofollow noopener" target="_blank">Test</a>'
     end
 
     it 'removes "translate" attribute with invalid value' do
-      expect(Sanitize.fragment('<a href="http://example.com" translate="foo">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+      expect(Sanitize.fragment('<a href="http://example.com" translate="foo">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener" target="_blank">Test</a>'
     end
 
     it 'removes a with unparsable href' do
@@ -55,7 +55,7 @@ RSpec.describe Sanitize::Config do
     end
 
     it 'keeps a with supported scheme and no host' do
-      expect(Sanitize.fragment('<a href="dweb:/a/foo">Test</a>', subject)).to eq '<a href="dweb:/a/foo" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+      expect(Sanitize.fragment('<a href="dweb:/a/foo">Test</a>', subject)).to eq '<a href="dweb:/a/foo" rel="nofollow noopener" target="_blank">Test</a>'
     end
 
     it 'sanitizes math to LaTeX' do