From edfbb37a37179004d11b18bf8f2c0a18e65ba1f5 Mon Sep 17 00:00:00 2001
From: MeiMei <30769358+mei23@users.noreply.github.com>
Date: Sun, 29 Mar 2020 23:16:36 +0900
Subject: [PATCH] =?UTF-8?q?=E3=83=88=E3=83=BC=E3=82=AF=E3=83=B3=E7=B3=BB?=
 =?UTF-8?q?=E3=81=AE=E4=B9=B1=E6=95=B0=E3=82=BD=E3=83=BC=E3=82=B9=E3=81=A7?=
 =?UTF-8?q?=E3=81=AFcrypto=E3=82=92=E4=BD=BF=E3=81=86=E3=82=88=E3=81=86?=
 =?UTF-8?q?=E3=81=AB=20(#6200)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/misc/secure-rndstr.ts                     | 21 +++++++++++++++++++
 .../api/common/generate-native-user-token.ts  |  4 ++--
 src/server/api/endpoints/app/create.ts        |  4 ++--
 src/server/api/endpoints/auth/accept.ts       |  4 ++--
 src/server/api/endpoints/miauth/gen-token.ts  |  4 ++--
 5 files changed, 29 insertions(+), 8 deletions(-)
 create mode 100644 src/misc/secure-rndstr.ts

diff --git a/src/misc/secure-rndstr.ts b/src/misc/secure-rndstr.ts
new file mode 100644
index 000000000..76ee1225e
--- /dev/null
+++ b/src/misc/secure-rndstr.ts
@@ -0,0 +1,21 @@
+import * as crypto from 'crypto';
+
+const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
+const LU_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+export function secureRndstr(length = 32, useLU = true): string {
+	const chars = useLU ? LU_CHARS : L_CHARS;
+	const chars_len = chars.length;
+
+	let str = '';
+
+	for (let i = 0; i < length; i++) {
+		let rand = Math.floor((crypto.randomBytes(1).readUInt8(0) / 0xFF) * chars_len);
+		if (rand === chars_len) {
+			rand = chars_len - 1;
+		}
+		str += chars.charAt(rand);
+	}
+
+	return str;
+}
diff --git a/src/server/api/common/generate-native-user-token.ts b/src/server/api/common/generate-native-user-token.ts
index a372221a0..cd30ba98f 100644
--- a/src/server/api/common/generate-native-user-token.ts
+++ b/src/server/api/common/generate-native-user-token.ts
@@ -1,3 +1,3 @@
-import rndstr from 'rndstr';
+import { secureRndstr } from '../../../misc/secure-rndstr';
 
-export default () => rndstr('a-zA-Z0-9', 16);
+export default () => secureRndstr(16, true);
diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts
index ac3e8a18d..776865ffb 100644
--- a/src/server/api/endpoints/app/create.ts
+++ b/src/server/api/endpoints/app/create.ts
@@ -1,9 +1,9 @@
-import rndstr from 'rndstr';
 import $ from 'cafy';
 import define from '../../define';
 import { Apps } from '../../../../models';
 import { genId } from '../../../../misc/gen-id';
 import { unique } from '../../../../prelude/array';
+import { secureRndstr } from '../../../../misc/secure-rndstr';
 
 export const meta = {
 	tags: ['app'],
@@ -60,7 +60,7 @@ export const meta = {
 
 export default define(meta, async (ps, user) => {
 	// Generate secret
-	const secret = rndstr('a-zA-Z0-9', 32);
+	const secret = secureRndstr(32, true);
 
 	// for backward compatibility
 	const permission = unique(ps.permission.map(v => v.replace(/^(.+)(\/|-)(read|write)$/, '$3:$1')));
diff --git a/src/server/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts
index 8ba15ba81..e9281f123 100644
--- a/src/server/api/endpoints/auth/accept.ts
+++ b/src/server/api/endpoints/auth/accept.ts
@@ -1,4 +1,3 @@
-import rndstr from 'rndstr';
 import * as crypto from 'crypto';
 import $ from 'cafy';
 import define from '../../define';
@@ -6,6 +5,7 @@ import { ApiError } from '../../error';
 import { AuthSessions, AccessTokens, Apps } from '../../../../models';
 import { genId } from '../../../../misc/gen-id';
 import { ensure } from '../../../../prelude/ensure';
+import { secureRndstr } from '../../../../misc/secure-rndstr';
 
 export const meta = {
 	tags: ['auth'],
@@ -39,7 +39,7 @@ export default define(meta, async (ps, user) => {
 	}
 
 	// Generate access token
-	const accessToken = rndstr('a-zA-Z0-9', 32);
+	const accessToken = secureRndstr(32, true);
 
 	// Fetch exist access token
 	const exist = await AccessTokens.findOne({
diff --git a/src/server/api/endpoints/miauth/gen-token.ts b/src/server/api/endpoints/miauth/gen-token.ts
index efa868080..d8c74ec8d 100644
--- a/src/server/api/endpoints/miauth/gen-token.ts
+++ b/src/server/api/endpoints/miauth/gen-token.ts
@@ -1,8 +1,8 @@
-import rndstr from 'rndstr';
 import $ from 'cafy';
 import define from '../../define';
 import { AccessTokens } from '../../../../models';
 import { genId } from '../../../../misc/gen-id';
+import { secureRndstr } from '../../../../misc/secure-rndstr';
 
 export const meta = {
 	tags: ['auth'],
@@ -36,7 +36,7 @@ export const meta = {
 
 export default define(meta, async (ps, user) => {
 	// Generate access token
-	const accessToken = rndstr('a-zA-Z0-9', 32);
+	const accessToken = secureRndstr(32, true);
 
 	// Insert access token doc
 	await AccessTokens.save({