From aece1d9939b6e0ff4e2388783911e0bb3fb413c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Wed, 27 May 2026 22:48:48 +0200 Subject: [PATCH 1/9] Deprecate md5() and weak algos in passwordless API Doc update reflecting future patch People willing to continue using md5 or any other algo will be able to do so with an explicit filter, so no breaking change. --- docs/guide/advanced/passwordless-api.md | 31 ++++++++----------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/docs/guide/advanced/passwordless-api.md b/docs/guide/advanced/passwordless-api.md index 8e6fb76..b7ed3e1 100644 --- a/docs/guide/advanced/passwordless-api.md +++ b/docs/guide/advanced/passwordless-api.md @@ -8,9 +8,11 @@ If you're worried about sending your credentials into the wild, you can also mak Your secret signature token will be a string like `1002a612b4` -A secret signature token is unique, associated to one account, and can be used only for API requests. It cannot be used to log in your YOURLS setup. You will find it in the Tools page of your YOURLS install. +A secret signature token is unique, associated to one account, and can be used only for API requests. It cannot be used to +log in your YOURLS setup. You will find it in the Tools page of your YOURLS install. -**NB**: Can't see this signature on the Tools page? It's probably because your install is public. Therefore, you don't use a login and password to use it. Therefore there's no signature token to be used instead of a login/password pair. +**NB**: Can't see this signature on the Tools page? It's probably because your install is public. Therefore, you don't use a +login and password to use it. Therefore there's no signature token to be used instead of a login/password pair. ## Usage of the signature token @@ -27,15 +29,16 @@ First, craft the time limited signature token: ```php ``` +By default, the hash must be one of `sha256`, `sha384` or `sha512`, unless explicitly allowed by a plugin via +the `allowed_hash_algos` filter. -Now use parameters `signature` and `timestamp` in your API requests. Example: +Now use parameters `signature`, `timestamp` and `hash_algo` in your API requests. Example: -`https://yoursite/yourls-api.php?timestamp=$timestamp&signature=$signature&action=...` +`https://yoursite/yourls-api.php?timestamp=$timestamp&signature=$signature&hash=sha256&action=...` This URL would be valid for only 43200 seconds (12 hours), the default value of constant `YOURLS_NONCE_LIFE`. @@ -43,20 +46,6 @@ To modify this duration, add the following to your `config.php`: `define( 'YOURLS_NONCE_LIFE', number_of_seconds );` (note this also affect all the internal links of YOURLS such as the ones to activate a plugin, delete a short URL, etc.) -### Use other hash algorithms than `md5` - -From YOURLS 1.7.7 you can use any hash function instead of `md5()`. Simply add the `hash=` argument to your API request, for instance: - -```php - -``` - -Now use `https://yoursite/yourls-api.php?timestamp=$timestamp&signature=$signature&hash=sha512&action=...` - **NB**: if you try to use a hash algorithm that your setup doesn't support, you will get a simple authentication error as if the timestamp or signature were incorrect. ## Reset your secret signature token From 4285df97af7e564921b65e7c7d4d4e38a888b4ff Mon Sep 17 00:00:00 2001 From: "yourls-bot[bot]" <104057305+yourls-bot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 20:51:06 +0000 Subject: [PATCH 2/9] Fix linting issues --- docs/guide/advanced/passwordless-api.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/guide/advanced/passwordless-api.md b/docs/guide/advanced/passwordless-api.md index b7ed3e1..deb9ad3 100644 --- a/docs/guide/advanced/passwordless-api.md +++ b/docs/guide/advanced/passwordless-api.md @@ -33,6 +33,7 @@ $signature = hash('sha256', $timestamp . '1002a612b4' ); // $signature = "10c28ab4a8b1b6acf3bef1a3e3284f4984d... (64 chars)" ?> ``` + By default, the hash must be one of `sha256`, `sha384` or `sha512`, unless explicitly allowed by a plugin via the `allowed_hash_algos` filter. From e990bb63b3de5a8a84192a42cc657ba089f04829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Thu, 28 May 2026 10:19:41 +0200 Subject: [PATCH 3/9] Update docs/guide/advanced/passwordless-api.md Co-authored-by: dgw --- docs/guide/advanced/passwordless-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/advanced/passwordless-api.md b/docs/guide/advanced/passwordless-api.md index deb9ad3..6fb9bfb 100644 --- a/docs/guide/advanced/passwordless-api.md +++ b/docs/guide/advanced/passwordless-api.md @@ -37,7 +37,7 @@ $signature = hash('sha256', $timestamp . '1002a612b4' ); By default, the hash must be one of `sha256`, `sha384` or `sha512`, unless explicitly allowed by a plugin via the `allowed_hash_algos` filter. -Now use parameters `signature`, `timestamp` and `hash_algo` in your API requests. Example: +Now use parameters `signature`, `timestamp` and `hash` in your API requests. Example: `https://yoursite/yourls-api.php?timestamp=$timestamp&signature=$signature&hash=sha256&action=...` From 5822d34129d97124b4757f215453b1a540f7367c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Thu, 28 May 2026 11:20:39 +0200 Subject: [PATCH 4/9] Don't promote md5 in config file --- docs/guide/essentials/credentials.md | 39 +++++----------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/docs/guide/essentials/credentials.md b/docs/guide/essentials/credentials.md index 93861eb..9086ee5 100644 --- a/docs/guide/essentials/credentials.md +++ b/docs/guide/essentials/credentials.md @@ -4,7 +4,7 @@ In `config.php`, the variable `$yourls_user_passwords` shall contain an array of usernames and passwords. -To improve security and user experience, YOURLS 1.7+ **automatically encrypts** these passwords within your config file. +To improve security and user experience, YOURLS **automatically encrypts** these passwords within your config file. ## Editing login & passwords in `config.php` @@ -33,7 +33,8 @@ $yourls_user_passwords = array( ## Password auto-encryption -Next time you'll run YOURLS, this array will be rewritten, replacing plain text passwords with encrypted and undecipherable hashes. If you check now your `config.php`, you should see something like: +Next time you'll run YOURLS, this array will be rewritten, replacing plain text passwords with encrypted and +undecipherable hashes. If you check now your `config.php`, you should see something like: ```php :< md5 of salt + password >` - -A PHP example to generate an encrypted password would be: - -```php - value` associations with encrypted passwords looks like the following: - -```php - 'md5:71688:0ce43474167f743b7b92d046ae970801', -); -``` - -Hashes using MD5 are slightly less secure than using native YOURLS encryption, but still way better than plain text passwords. - ### I don't want to encrypt my password If for some reason you'd rather keep your password unencrypted and in plain text in your config, simply add the following at the end of your `config.php`: From 4bdf265b6707302e625dfce3e0dc3962da6cc8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Thu, 28 May 2026 21:55:28 +0200 Subject: [PATCH 5/9] Explain how to remove md5 passwords --- docs/guide/essentials/credentials.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/guide/essentials/credentials.md b/docs/guide/essentials/credentials.md index 9086ee5..8663fbd 100644 --- a/docs/guide/essentials/credentials.md +++ b/docs/guide/essentials/credentials.md @@ -61,9 +61,15 @@ If YOURLS cannot edit and save your `config.php` file, you will see the followin > _Could not auto-encrypt passwords. Error was: "cannot write file"._ -Your config file is probably locked for reading and or writing (eg _chmoded_), which can be a good security practice. Temporarily lift that restriction (`chmod 0666 config.php`), load a YOURLS page again, then `chmod` it back. +Your config file is probably locked for reading and or writing (eg _chmoded_), which can be a good security practice. In a terminal console, note +the original _chmod_ (`stat -c "%a" config.php`), temporarily lift that restriction (`chmod 0666 config.php`), load a YOURLS page again, +then `chmod` it back to the original value (for example `chmod 600 config.php`). -If for some reason you cannot get it working, see **manual MD5 encryption** below +### I have an error message: "_Password stored as MD5 hash_" + +If your `config.php` contains password encrypted the old way with `md5()`, you should consider using more robust hashes. + +To do so: simply replace the string `md5:<5 digits>:<32 chars>` with your password in clear text, load a YOURLS page again. Everything should be now encrypted. ### Why hash passwords? From 61cc3b97e658bf33dc5e212570f7ea06f26b70e0 Mon Sep 17 00:00:00 2001 From: "yourls-bot[bot]" <104057305+yourls-bot[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 19:57:05 +0000 Subject: [PATCH 6/9] Fix linting issues --- docs/guide/essentials/credentials.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/essentials/credentials.md b/docs/guide/essentials/credentials.md index 8663fbd..6ca4302 100644 --- a/docs/guide/essentials/credentials.md +++ b/docs/guide/essentials/credentials.md @@ -8,7 +8,7 @@ To improve security and user experience, YOURLS **automatically encrypts** these ## Editing login & passwords in `config.php` -Edit and save your config file with an array of simple `key => value` associations like the followings: +Edit and save your config file with an array of simple `key => value` associations like the following: One login/password: @@ -73,7 +73,7 @@ To do so: simply replace the string `md5:<5 digits>:<32 chars>` with your passwo ### Why hash passwords? -Storing your password as a crypted hash is more secure: if someone has access to your `config.php`, they won't be able to determine what your password is and won't be able to log in your setup. The drawback is that if you forget your own password, you cannot retrieve it: see below. +Storing your password as a encrypted hash is more secure: if someone has access to your `config.php`, they won't be able to determine what your password is and won't be able to log in your setup. The drawback is that if you forget your own password, you cannot retrieve it: see below. ### I don't remember my password / I want to change it From f82517032c826616652c6d5eca5343d33abdca00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Thu, 28 May 2026 20:45:33 +0000 Subject: [PATCH 7/9] Add redirects for md5 removal --- static/_redirects | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/_redirects b/static/_redirects index 15caf03..c33d52b 100644 --- a/static/_redirects +++ b/static/_redirects @@ -1,7 +1,8 @@ # https://developers.cloudflare.com/workers/static-assets/redirects/ /blog/feed/ /blog/atom.xml 301 -/md5.php /md5 301 +/md5.php /docs/guide/essentials/credentials 301 +/md5 /docs/guide/essentials/credentials 301 /cookiekey.php https://api.yourls.org/services/cookiekey/1.0/ 301 /hooklist.php https://app.yourls.org/hooklist.php 308 /admin/* https://app.yourls.org/admin/:splat 308 From 901e0aa1d6a408112f89bb88d977145770cd31d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Thu, 28 May 2026 20:46:58 +0000 Subject: [PATCH 8/9] Remove md5 pages and assets --- package-lock.json | 36 ------------------- package.json | 3 +- src/components/Md5Generator/index.js | 35 ------------------ src/components/Md5Generator/styles.module.css | 11 ------ src/pages/md5.mdx | 18 ---------- 5 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 src/components/Md5Generator/index.js delete mode 100644 src/components/Md5Generator/styles.module.css delete mode 100644 src/pages/md5.mdx diff --git a/package-lock.json b/package-lock.json index 4cb3602..0dbbb04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "dependencies": { "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", - "md5": "^2.3.0", "prism-react-renderer": "^2.4.1", "react": "^19.2.6", "react-dom": "^19.2.6" @@ -8226,15 +8225,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -8854,15 +8844,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -11852,12 +11833,6 @@ "node": ">=8" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT" - }, "node_modules/is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -12584,17 +12559,6 @@ "node": ">= 0.4" } }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "license": "BSD-3-Clause", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, "node_modules/mdast-util-directive": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", diff --git a/package.json b/package.json index efb2201..ca63ac5 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,14 @@ "dependencies": { "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", - "md5": "^2.3.0", "prism-react-renderer": "^2.4.1", "react": "^19.2.6", "react-dom": "^19.2.6" }, "devDependencies": { "@docusaurus/core": "3.10.1", - "@docusaurus/preset-classic": "3.10.1", "@docusaurus/module-type-aliases": "3.10.1", + "@docusaurus/preset-classic": "3.10.1", "@docusaurus/types": "3.10.1", "graphql-request": "^7.4.0", "prettier": "^3.8.3", diff --git a/src/components/Md5Generator/index.js b/src/components/Md5Generator/index.js deleted file mode 100644 index c4c72d2..0000000 --- a/src/components/Md5Generator/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import { useState } from 'react' - -import styles from './styles.module.css' - -export default function Md5Generator() { - const [text, setText] = useState('') - const [md5, setMd5] = useState('') - - const handleChange = async (e) => { - setText(e.target.value) - const salt = Math.floor(Math.random() * (99999 - 10000 + 1)) + 10000 - const encrypted = - `md5:${salt}:${require('md5')(salt + e.target.value)}` - setMd5(encrypted) - } - - return ( -
-
- - -
-
- - -
-
- ) -} diff --git a/src/components/Md5Generator/styles.module.css b/src/components/Md5Generator/styles.module.css deleted file mode 100644 index 070b2c3..0000000 --- a/src/components/Md5Generator/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.input { - padding: calc( - var(--ifm-button-padding-vertical) * var(--ifm-button-size-multiplier) - ) - 1em; - line-height: 1.5; - display: block; - width: 100%; - margin-bottom: 1em; - font-family: var(--ifm-font-family-monospace); -} diff --git a/src/pages/md5.mdx b/src/pages/md5.mdx deleted file mode 100644 index a352f4b..0000000 --- a/src/pages/md5.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar: false ---- - -import Md5Generator from '@site/src/components/Md5Generator' - -# Salted hash generator - -:::info -This form just outputs hashes. Nothing is stored or logged, not even sent to any server. -::: - -:::danger -`md5` hash function usage is deprecated. -Consider using native password hashes instead. -::: - - From adb8d0cc2dea187e4aede0ba3da196558a609ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Sat, 30 May 2026 12:24:44 +0200 Subject: [PATCH 9/9] Revise signature token example and customization info Updated the example signature token to a 32 character string and clarified customization options. --- docs/guide/advanced/passwordless-api.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/guide/advanced/passwordless-api.md b/docs/guide/advanced/passwordless-api.md index 6fb9bfb..ae28bf2 100644 --- a/docs/guide/advanced/passwordless-api.md +++ b/docs/guide/advanced/passwordless-api.md @@ -6,7 +6,7 @@ If you're worried about sending your credentials into the wild, you can also mak ## Signature token -Your secret signature token will be a string like `1002a612b4` +Your secret signature token will be a 32 character string like `4ea59aab37f6df0755a6da98ee5ca85d`. A secret signature token is unique, associated to one account, and can be used only for API requests. It cannot be used to log in your YOURLS setup. You will find it in the Tools page of your YOURLS install. @@ -14,11 +14,13 @@ log in your YOURLS setup. You will find it in the Tools page of your YOURLS inst **NB**: Can't see this signature on the Tools page? It's probably because your install is public. Therefore, you don't use a login and password to use it. Therefore there's no signature token to be used instead of a login/password pair. +If you know what you are doing, you can customize the signature length or even content with filters `auth_signature_length` and `auth_signature`. + ## Usage of the signature token Use parameter `signature` in your API requests. Example: -`https://yoursite/yourls-api.php?signature=1002a612b4&action=...` +`https://yoursite/yourls-api.php?signature=4ea59aab37f6df0755a6da98ee5ca85d&action=...` ## Usage of a time limited signature token @@ -29,12 +31,12 @@ First, craft the time limited signature token: ```php ``` -By default, the hash must be one of `sha256`, `sha384` or `sha512`, unless explicitly allowed by a plugin via +The hash must be one of `sha256`, `sha384` or `sha512`, unless explicitly allowed by a plugin via the `allowed_hash_algos` filter. Now use parameters `signature`, `timestamp` and `hash` in your API requests. Example: