diff --git a/api/funkwhale_api/federation/factories.py b/api/funkwhale_api/federation/factories.py
index 7370ebd77d73694178a326ede77a2d0269ed16e6..7dad1daa97337c2466f92dd2fd4317892aa389d9 100644
--- a/api/funkwhale_api/federation/factories.py
+++ b/api/funkwhale_api/federation/factories.py
@@ -5,6 +5,7 @@ import requests
 import requests_http_signature
 from django.conf import settings
 from django.utils import timezone
+from django.utils.http import http_date
 
 from funkwhale_api.factories import registry
 
@@ -39,7 +40,7 @@ class SignedRequestFactory(factory.Factory):
         default_headers = {
             "User-Agent": "Test",
             "Host": "test.host",
-            "Date": "Right now",
+            "Date": http_date(timezone.now().timestamp()),
             "Content-Type": "application/activity+json",
         }
         if extracted:
diff --git a/api/funkwhale_api/federation/signing.py b/api/funkwhale_api/federation/signing.py
index 15525b3e513b2ccc861cbf34b693b30aa0850d29..5b74b8577fb08606641e3bf00b02e302032e49ee 100644
--- a/api/funkwhale_api/federation/signing.py
+++ b/api/funkwhale_api/federation/signing.py
@@ -1,4 +1,10 @@
+import datetime
 import logging
+import pytz
+
+from django import forms
+from django.utils import timezone
+from django.utils.http import parse_http_date
 
 import requests
 import requests_http_signature
@@ -7,8 +13,33 @@ from . import exceptions, utils
 
 logger = logging.getLogger(__name__)
 
+#  the request Date should be between now - 30s and now + 30s
+DATE_HEADER_VALID_FOR = 30
+
+
+def verify_date(raw_date):
+    if not raw_date:
+        raise forms.ValidationError("Missing date header")
+
+    try:
+        ts = parse_http_date(raw_date)
+    except ValueError as e:
+        raise forms.ValidationError(str(e))
+    dt = datetime.datetime.utcfromtimestamp(ts)
+    dt = dt.replace(tzinfo=pytz.utc)
+    delta = datetime.timedelta(seconds=DATE_HEADER_VALID_FOR)
+    now = timezone.now()
+    if dt < now - delta or dt > now + delta:
+        raise forms.ValidationError(
+            "Request Date is too far in the future or in the past"
+        )
+
+    return dt
+
 
 def verify(request, public_key):
+    verify_date(request.headers.get("Date"))
+
     return requests_http_signature.HTTPSignatureAuth.verify(
         request, key_resolver=lambda **kwargs: public_key, use_auth_header=False
     )
diff --git a/api/tests/federation/test_signing.py b/api/tests/federation/test_signing.py
index 159f31cd96fdce747cd48120d4999940de5dd66c..298462142ffeab15a3e020c8baaef6ae3de1811a 100644
--- a/api/tests/federation/test_signing.py
+++ b/api/tests/federation/test_signing.py
@@ -1,4 +1,7 @@
 import cryptography.exceptions
+import datetime
+from django.utils.http import http_date
+from django import forms
 import pytest
 
 from funkwhale_api.federation import keys, signing
@@ -36,6 +39,20 @@ def test_verify_fails_with_wrong_key(nodb_factories):
         signing.verify(prepared_request, wrong_public)
 
 
+def test_verify_fails_with_wrong_date(nodb_factories, now):
+    too_old = now - datetime.timedelta(seconds=31)
+    too_old = http_date(too_old.timestamp())
+    private, public = nodb_factories["federation.KeyPair"]()
+    auth = nodb_factories["federation.SignatureAuth"](key=private)
+    request = nodb_factories["federation.SignedRequest"](
+        auth=auth, headers={"Date": too_old}
+    )
+    prepared_request = request.prepare()
+
+    with pytest.raises(forms.ValidationError):
+        signing.verify(prepared_request, public)
+
+
 def test_can_verify_django_request(factories, fake_request):
     private_key, public_key = keys.get_key_pair()
     signed_request = factories["federation.SignedRequest"](
@@ -95,14 +112,18 @@ def test_can_verify_django_request_digest_failure(factories, fake_request):
         signing.verify_django(django_request, public_key)
 
 
-def test_can_verify_django_request_failure(factories, fake_request):
+def test_can_verify_django_request_failure(factories, fake_request, now):
     private_key, public_key = keys.get_key_pair()
     signed_request = factories["federation.SignedRequest"](
         auth__key=private_key, auth__headers=["date"]
     )
     prepared = signed_request.prepare()
     django_request = fake_request.get(
-        "/", **{"HTTP_DATE": "Wrong", "HTTP_SIGNATURE": prepared.headers["signature"]}
+        "/",
+        **{
+            "HTTP_DATE": http_date((now + datetime.timedelta(seconds=31)).timestamp()),
+            "HTTP_SIGNATURE": prepared.headers["signature"],
+        }
     )
-    with pytest.raises(cryptography.exceptions.InvalidSignature):
+    with pytest.raises(forms.ValidationError):
         signing.verify_django(django_request, public_key)
diff --git a/changes/changelog.d/328.bugfix b/changes/changelog.d/328.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..cb28e4c9729cf72eaeddf6eecb8e26c6159930ce
--- /dev/null
+++ b/changes/changelog.d/328.bugfix
@@ -0,0 +1 @@
+Validate Date header in HTTP Signatures (#328)