mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 23:27:14 +00:00
Set max password length (100 chars) to help prevent DDOS attack
This commit is contained in:
@@ -231,10 +231,11 @@
|
|||||||
"current": "Current password",
|
"current": "Current password",
|
||||||
"current-wrong": "The current password may be wrong",
|
"current-wrong": "The current password may be wrong",
|
||||||
"new": "New password",
|
"new": "New password",
|
||||||
"validate-base": "Password should contain at least:",
|
"validate-base": "Password should contain:",
|
||||||
"validate-length": "14 characters",
|
"validate-too-short": "at least 14 characters",
|
||||||
"validate-case": "1 lowercase character",
|
"validate-too-long": "at most 100 characters",
|
||||||
"validate-number": "1 number"
|
"validate-case": "at least 1 lowercase character",
|
||||||
|
"validate-number": "at least 1 number"
|
||||||
},
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"service-tokens": "Service Tokens",
|
"service-tokens": "Service Tokens",
|
||||||
|
|||||||
@@ -215,10 +215,11 @@
|
|||||||
"current": "Mot de passe actuel",
|
"current": "Mot de passe actuel",
|
||||||
"current-wrong": "Le mot de passe actuel peut être érroné",
|
"current-wrong": "Le mot de passe actuel peut être érroné",
|
||||||
"new": "Nouveau mot de passe",
|
"new": "Nouveau mot de passe",
|
||||||
"validate-base": "Le mot de passe doit contenir au moins:",
|
"validate-base": "Le mot de passe doit contenir:",
|
||||||
"validate-length": "14 caractères",
|
"validate-too-short": "au moins 14 caractères",
|
||||||
"validate-case": "1 caractère miniscule",
|
"validate-too-long": "au maximum 100 caractères",
|
||||||
"validate-number": "1 chiffre"
|
"validate-case": "au moins 1 caractère miniscule",
|
||||||
|
"validate-number": "au moins 1 chiffre"
|
||||||
},
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"service-tokens": "Jetons de service",
|
"service-tokens": "Jetons de service",
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ interface UserInfoStepProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Errors = {
|
type Errors = {
|
||||||
length?: string,
|
tooShort?: string,
|
||||||
|
tooLong?: string,
|
||||||
upperCase?: string,
|
upperCase?: string,
|
||||||
lowerCase?: string,
|
lowerCase?: string,
|
||||||
number?: string,
|
number?: string,
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
interface PasswordCheckProps {
|
interface PasswordCheckProps {
|
||||||
password: string;
|
password: string;
|
||||||
errorCheck: boolean;
|
errorCheck: boolean;
|
||||||
setPasswordErrorLength: (value: boolean) => void;
|
setPasswordErrorTooShort: (value: boolean) => void;
|
||||||
|
setPasswordErrorTooLong: (value: boolean) => void;
|
||||||
setPasswordErrorNumber: (value: boolean) => void;
|
setPasswordErrorNumber: (value: boolean) => void;
|
||||||
setPasswordErrorLowerCase: (value: boolean) => void;
|
setPasswordErrorLowerCase: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
@@ -12,17 +13,25 @@ interface PasswordCheckProps {
|
|||||||
*/
|
*/
|
||||||
const passwordCheck = ({
|
const passwordCheck = ({
|
||||||
password,
|
password,
|
||||||
setPasswordErrorLength,
|
setPasswordErrorTooShort,
|
||||||
setPasswordErrorNumber,
|
setPasswordErrorNumber,
|
||||||
setPasswordErrorLowerCase,
|
setPasswordErrorLowerCase,
|
||||||
|
setPasswordErrorTooLong,
|
||||||
errorCheck
|
errorCheck
|
||||||
}: PasswordCheckProps) => {
|
}: PasswordCheckProps) => {
|
||||||
|
|
||||||
if (!password || password.length < 14) {
|
if (!password || password.length < 14) {
|
||||||
setPasswordErrorLength(true);
|
setPasswordErrorTooShort(true);
|
||||||
errorCheck = true;
|
errorCheck = true;
|
||||||
} else {
|
} else {
|
||||||
setPasswordErrorLength(false);
|
setPasswordErrorTooShort(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.length > 100) {
|
||||||
|
setPasswordErrorTooLong(true);
|
||||||
|
errorCheck = true;
|
||||||
|
} else {
|
||||||
|
setPasswordErrorTooLong(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/\d/.test(password)) {
|
if (!/\d/.test(password)) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
type Errors = {
|
type Errors = {
|
||||||
length?: string,
|
tooShort?: string,
|
||||||
|
tooLong?: string,
|
||||||
upperCase?: string,
|
upperCase?: string,
|
||||||
lowerCase?: string,
|
lowerCase?: string,
|
||||||
number?: string,
|
number?: string,
|
||||||
@@ -15,11 +16,12 @@ interface CheckPasswordParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that the password [password] is at least:
|
* Validate that the password [password]:
|
||||||
* - 8 characters long
|
* - Contains at least 14 characters long
|
||||||
* - Contains 1 uppercase character (A-Z)
|
* - Contains at most 100 characters long
|
||||||
* - Contains 1 lowercase character (a-z)
|
* - Contains at least 1 uppercase character (A-Z)
|
||||||
* - Contains 1 number (0-9)
|
* - Contains at least 1 lowercase character (a-z)
|
||||||
|
* - Contains at least 1 number (0-9)
|
||||||
* - Does not contain 3 repeat, consecutive characters
|
* - Does not contain 3 repeat, consecutive characters
|
||||||
*
|
*
|
||||||
* The function returns whether or not the password [password]
|
* The function returns whether or not the password [password]
|
||||||
@@ -37,24 +39,28 @@ const checkPassword = ({
|
|||||||
}: CheckPasswordParams): boolean => {
|
}: CheckPasswordParams): boolean => {
|
||||||
const errors: Errors = {};
|
const errors: Errors = {};
|
||||||
|
|
||||||
if (password.length < 8) {
|
if (password.length < 14) {
|
||||||
errors.length = "8 characters";
|
errors.tooShort = "at least 14 characters";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.length > 100) {
|
||||||
|
errors.tooLong = "at most 100 characters";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/[A-Z]/.test(password)) {
|
if (!/[A-Z]/.test(password)) {
|
||||||
errors.upperCase = "1 uppercase character (A-Z)";
|
errors.upperCase = "at least 1 uppercase character (A-Z)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/[a-z]/.test(password)) {
|
if (!/[a-z]/.test(password)) {
|
||||||
errors.lowerCase = "1 lowercase character (a-z)";
|
errors.lowerCase = "at least 1 lowercase character (a-z)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/[0-9]/.test(password)) {
|
if (!/[0-9]/.test(password)) {
|
||||||
errors.number = "1 number (0-9)";
|
errors.number = "at least 1 number (0-9)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
|
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
|
||||||
errors.specialChar = "1 special character (!@#$%^&*(),.?)";
|
errors.specialChar = "at least 1 special character (!@#$%^&*(),.?)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/([A-Za-z0-9])\1\1\1/.test(password)) {
|
if (/([A-Za-z0-9])\1\1\1/.test(password)) {
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ export default function PasswordReset() {
|
|||||||
const [privateKey, setPrivateKey] = useState("");
|
const [privateKey, setPrivateKey] = useState("");
|
||||||
const [newPassword, setNewPassword] = useState("");
|
const [newPassword, setNewPassword] = useState("");
|
||||||
const [backupKeyError, setBackupKeyError] = useState(false);
|
const [backupKeyError, setBackupKeyError] = useState(false);
|
||||||
const [passwordErrorLength, setPasswordErrorLength] = useState(false);
|
const [passwordErrorTooShort, setPasswordErrorTooShort] = useState(false);
|
||||||
|
const [passwordErrorTooLong, setPasswordErrorTooLong] = useState(false);
|
||||||
const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
|
const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
|
||||||
const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
|
const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
|
||||||
|
|
||||||
@@ -67,7 +68,8 @@ export default function PasswordReset() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const errorCheck = passwordCheck({
|
const errorCheck = passwordCheck({
|
||||||
password: newPassword,
|
password: newPassword,
|
||||||
setPasswordErrorLength,
|
setPasswordErrorTooShort,
|
||||||
|
setPasswordErrorTooLong,
|
||||||
setPasswordErrorNumber,
|
setPasswordErrorNumber,
|
||||||
setPasswordErrorLowerCase,
|
setPasswordErrorLowerCase,
|
||||||
errorCheck: false
|
errorCheck: false
|
||||||
@@ -221,7 +223,8 @@ export default function PasswordReset() {
|
|||||||
setNewPassword(password);
|
setNewPassword(password);
|
||||||
passwordCheck({
|
passwordCheck({
|
||||||
password,
|
password,
|
||||||
setPasswordErrorLength,
|
setPasswordErrorTooShort,
|
||||||
|
setPasswordErrorTooLong,
|
||||||
setPasswordErrorNumber,
|
setPasswordErrorNumber,
|
||||||
setPasswordErrorLowerCase,
|
setPasswordErrorLowerCase,
|
||||||
errorCheck: false
|
errorCheck: false
|
||||||
@@ -230,22 +233,32 @@ export default function PasswordReset() {
|
|||||||
type="password"
|
type="password"
|
||||||
value={newPassword}
|
value={newPassword}
|
||||||
isRequired
|
isRequired
|
||||||
error={passwordErrorLength && passwordErrorLowerCase && passwordErrorNumber}
|
error={passwordErrorTooShort && passwordErrorTooLong && passwordErrorLowerCase && passwordErrorNumber}
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
id="new-password"
|
id="new-password"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{passwordErrorLength || passwordErrorLowerCase || passwordErrorNumber ? (
|
{passwordErrorTooShort || passwordErrorTooLong || passwordErrorLowerCase || passwordErrorNumber ? (
|
||||||
<div className="mx-2 mt-3 mb-2 flex w-full max-w-md flex-col items-start rounded-md bg-white/5 px-2 py-2">
|
<div className="mx-2 mt-3 mb-2 flex w-full max-w-md flex-col items-start rounded-md bg-white/5 px-2 py-2">
|
||||||
<div className="mb-1 text-sm text-gray-400">Password should contain at least:</div>
|
<div className="mb-1 text-sm text-gray-400">Password should contain:</div>
|
||||||
<div className="ml-1 flex flex-row items-center justify-start">
|
<div className="ml-1 flex flex-row items-center justify-start">
|
||||||
{passwordErrorLength ? (
|
{passwordErrorTooShort ? (
|
||||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||||
) : (
|
) : (
|
||||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||||
)}
|
)}
|
||||||
<div className={`${passwordErrorLength ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
<div className={`${passwordErrorTooShort ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
||||||
14 characters
|
at least 14 characters
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="ml-1 flex flex-row items-center justify-start">
|
||||||
|
{passwordErrorTooLong ? (
|
||||||
|
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||||
|
)}
|
||||||
|
<div className={`${passwordErrorTooLong ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
||||||
|
at most 100 characters
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-1 flex flex-row items-center justify-start">
|
<div className="ml-1 flex flex-row items-center justify-start">
|
||||||
@@ -257,7 +270,7 @@ export default function PasswordReset() {
|
|||||||
<div
|
<div
|
||||||
className={`${passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"} text-sm`}
|
className={`${passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||||
>
|
>
|
||||||
1 lowercase character
|
at least 1 lowercase character
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-1 flex flex-row items-center justify-start">
|
<div className="ml-1 flex flex-row items-center justify-start">
|
||||||
@@ -267,7 +280,7 @@ export default function PasswordReset() {
|
|||||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||||
)}
|
)}
|
||||||
<div className={`${passwordErrorNumber ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
<div className={`${passwordErrorNumber ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
||||||
1 number
|
at least 1 number
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+2
-1
@@ -18,7 +18,8 @@ import { useUser } from "@app/context";
|
|||||||
import { useGetCommonPasswords } from "@app/hooks/api";
|
import { useGetCommonPasswords } from "@app/hooks/api";
|
||||||
|
|
||||||
type Errors = {
|
type Errors = {
|
||||||
length?: string,
|
tooShort?: string,
|
||||||
|
tooLong?: string,
|
||||||
upperCase?: string,
|
upperCase?: string,
|
||||||
lowerCase?: string,
|
lowerCase?: string,
|
||||||
number?: string,
|
number?: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user