diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue
index baa27dd8df..7f5f4b9c37 100644
--- a/src/client/app/desktop/views/pages/welcome.vue
+++ b/src/client/app/desktop/views/pages/welcome.vue
@@ -187,6 +187,7 @@ export default Vue.extend({
 
 		(this as any).api('notes/local-timeline', {
 			fileType: image,
+			excludeNsfw: true,
 			limit: 6
 		}).then((notes: any[]) => {
 			const files = concat(notes.map((n: any): any[] => n.files));
diff --git a/src/client/app/mobile/views/pages/welcome.vue b/src/client/app/mobile/views/pages/welcome.vue
index 65a7af93a9..82ccfeaff5 100644
--- a/src/client/app/mobile/views/pages/welcome.vue
+++ b/src/client/app/mobile/views/pages/welcome.vue
@@ -111,6 +111,7 @@ export default Vue.extend({
 
 		(this as any).api('notes/local-timeline', {
 			fileType: image,
+			excludeNsfw: true,
 			limit: 6
 		}).then((notes: any[]) => {
 			const files = concat(notes.map((n: any): any[] => n.files));
diff --git a/src/models/note.ts b/src/models/note.ts
index ba88e9f481..f67eeaaf6e 100644
--- a/src/models/note.ts
+++ b/src/models/note.ts
@@ -20,6 +20,7 @@ Note.createIndex('userId');
 Note.createIndex('mentions');
 Note.createIndex('visibleUserIds');
 Note.createIndex('tagsLower');
+Note.createIndex('_files._id');
 Note.createIndex('_files.contentType');
 Note.createIndex({
 	createdAt: -1
diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts
index ba9abfec61..3c7932c341 100644
--- a/src/server/api/endpoints/drive/files/update.ts
+++ b/src/server/api/endpoints/drive/files/update.ts
@@ -4,6 +4,7 @@ import DriveFile, { validateFileName, pack } from '../../../../../models/drive-f
 import { publishDriveStream } from '../../../../../stream';
 import { ILocalUser } from '../../../../../models/user';
 import getParams from '../../../get-params';
+import Note from '../../../../../models/note';
 
 export const meta = {
 	desc: {
@@ -93,6 +94,18 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		}
 	});
 
+	// ドライブのファイルが非正規化されているドキュメントも更新
+	Note.find({
+		'_files._id': file._id
+	}).then(notes => {
+		notes.forEach(note => {
+			note._files[note._files.findIndex(f => f._id.equals(file._id))] = file;
+			Note.findOneAndUpdate({ _id: note._id }, {
+				_files: note._files
+			});
+		});
+	});
+
 	// Serialize
 	const fileObj = await pack(file);
 
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index ff10e6fbaa..505454a82f 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -30,6 +30,13 @@ export const meta = {
 			}
 		}),
 
+		excludeNsfw: $.bool.optional.note({
+			default: false,
+			desc: {
+				'ja-JP': 'true にすると、NSFW指定されたファイルを除外します(fileTypeが指定されている場合のみ有効)'
+			}
+		}),
+
 		limit: $.num.optional.range(1, 100).note({
 			default: 10
 		}),
@@ -97,6 +104,12 @@ export default async (params: any, user: ILocalUser) => {
 		query['_files.contentType'] = {
 			$in: ps.fileType
 		};
+
+		if (ps.excludeNsfw) {
+			query['_files.metadata.isSensitive'] = {
+				$ne: true
+			};
+		}
 	}
 
 	if (ps.sinceId) {