diff --git a/opentech/apply/stream_forms/blocks.py b/opentech/apply/stream_forms/blocks.py
index fd7dcdfaf08550809dc5a5451691061ac584fcba..1f0db044b550db62f3ff6804f3ef32e16602fb2c 100644
--- a/opentech/apply/stream_forms/blocks.py
+++ b/opentech/apply/stream_forms/blocks.py
@@ -3,7 +3,10 @@ import bleach
 from django_bleach.templatetags.bleach_tags import bleach_value
 
 from django import forms
+from django.conf import settings
+from django.core.validators import FileExtensionValidator
 from django.db.models import BLANK_CHOICE_DASH
+from django.forms.widgets import ClearableFileInput
 from django.utils.dateparse import parse_datetime
 from django.utils.encoding import force_text
 from django.utils.text import slugify
@@ -315,11 +318,19 @@ class UploadableMediaBlock(OptionalFormFieldBlock):
 
 class ImageFieldBlock(UploadableMediaBlock):
     field_class = forms.ImageField
+    widget = ClearableFileInput
 
     class Meta:
         label = _('Image field')
         icon = 'image'
 
+    def get_field_kwargs(self, struct_value):
+        kwargs = super().get_field_kwargs(struct_value)
+        # We do not need this when we are on Django 2.1
+        # https://docs.djangoproject.com/en/2.1/releases/2.1/#forms
+        kwargs['widget'] = self.get_widget(struct_value)(attrs={'accept': 'image/*'})
+        return kwargs
+
 
 class FileFieldBlock(UploadableMediaBlock):
     """This doesn't know how to save the uploaded files
@@ -327,11 +338,20 @@ class FileFieldBlock(UploadableMediaBlock):
     You must implement this if you want to reuse it.
     """
     field_class = forms.FileField
+    widget = ClearableFileInput
 
     class Meta:
         label = _('File field')
         icon = 'download'
 
+    def get_field_kwargs(self, struct_value):
+        kwargs = super().get_field_kwargs(struct_value)
+        kwargs['validators'] = [
+            FileExtensionValidator(allowed_extensions=settings.FILE_ALLOWED_EXTENSIONS)
+        ]
+        kwargs['widget'] = self.get_widget(struct_value)(attrs={'accept': settings.FILE_ACCEPT_ATTR_VALUE})
+        return kwargs
+
 
 class MultiFileFieldBlock(UploadableMediaBlock):
     field_class = MultiFileField
diff --git a/opentech/apply/stream_forms/fields.py b/opentech/apply/stream_forms/fields.py
index c45d4f1337f7f482c984b52976827e52c3e92baa..c7a8deed5921ec957558420f721f73f737fdcbef 100644
--- a/opentech/apply/stream_forms/fields.py
+++ b/opentech/apply/stream_forms/fields.py
@@ -1,3 +1,5 @@
+from django.conf import settings
+from django.core.validators import FileExtensionValidator
 from django.forms import ClearableFileInput, FileField, CheckboxInput
 
 
@@ -63,7 +65,11 @@ class MultiFileField(FileField):
         cleared = value['cleared']
         if not files and not cleared:
             return initial
-        new = [FileField().clean(file, initial) for file in files]
+        new = [
+            FileField(validators=[
+                FileExtensionValidator(allowed_extensions=settings.FILE_ALLOWED_EXTENSIONS)
+            ]).clean(file, initial) for file in files
+        ]
 
         if initial:
             old = [file for i, file in enumerate(initial) if i not in cleared]
@@ -71,3 +77,9 @@ class MultiFileField(FileField):
             old = []
 
         return old + new
+
+    def widget_attrs(self, widget):
+        attrs = super().widget_attrs(widget)
+        if isinstance(widget, MultiFileInput) and 'accept' not in widget.attrs:
+            attrs.setdefault('accept', settings.FILE_ACCEPT_ATTR_VALUE)
+        return attrs
diff --git a/opentech/apply/stream_forms/testing/factories.py b/opentech/apply/stream_forms/testing/factories.py
index 902ba4ce90239e439023ae722f12e5ca5079e6d1..f3421670610081f668ae6adeb5b2929cb521468d 100644
--- a/opentech/apply/stream_forms/testing/factories.py
+++ b/opentech/apply/stream_forms/testing/factories.py
@@ -143,6 +143,8 @@ class UploadableMediaFactory(FormFieldBlockFactory):
     def make_answer(cls, params=dict()):
         params = params.copy()
         params.setdefault('data', b'this is some content')
+        if params.get('filename') is None:
+            params['filename'] = 'example.pdf'
         file_name, file = cls.default_value()._make_content(params)
         return SimpleUploadedFile(file_name, file.read())
 
diff --git a/opentech/apply/stream_forms/tests.py b/opentech/apply/stream_forms/tests.py
index 5bdf4b189f2951344bc06e496c9bf9a4f9a2283a..a8d37d02de09a7a503431f897d4c7299db54e86a 100644
--- a/opentech/apply/stream_forms/tests.py
+++ b/opentech/apply/stream_forms/tests.py
@@ -10,7 +10,7 @@ fake = Faker()
 
 
 def make_files(number):
-    file_names = [f'{fake.word()}_{i}' for i in range(3)]
+    file_names = [f'{fake.word()}_{i}.pdf' for i in range(number)]
     files = [
         StreamFieldFile(SimpleUploadedFile(name, b'Some File Content'), filename=name)
         for name in file_names
diff --git a/opentech/settings/base.py b/opentech/settings/base.py
index 72f065276b6b29c03f650879a4413c36c293f502..e2157aecbcae27912724a158ffa0f1e0ef98c85d 100644
--- a/opentech/settings/base.py
+++ b/opentech/settings/base.py
@@ -438,6 +438,12 @@ BLEACH_STRIP_TAGS = True
 
 BLEACH_STRIP_COMMENTS = True
 
+# File Field settings
+FILE_ALLOWED_EXTENSIONS = ['doc', 'docx', 'odp', 'ods', 'odt', 'pdf', 'ppt', 'pptx', 'rtf', 'txt', 'xls', 'xlsx']
+
+# Accept attribute in input tag of type file needs filename extensions, starting with a period (".") character.
+FILE_ACCEPT_ATTR_VALUE = ", ".join(['.' + ext for ext in FILE_ALLOWED_EXTENSIONS])
+
 # Hijack Settings
 HIJACK_LOGIN_REDIRECT_URL = '/dashboard/'
 HIJACK_LOGOUT_REDIRECT_URL = '/account/'