Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report]MD5 哈希算法用于缓存的漏洞 #995

Open
3 tasks done
kexinoh opened this issue Dec 10, 2024 · 5 comments
Open
3 tasks done

[Bug Report]MD5 哈希算法用于缓存的漏洞 #995

kexinoh opened this issue Dec 10, 2024 · 5 comments
Labels
🐞bug Something isn't working

Comments

@kexinoh
Copy link

kexinoh commented Dec 10, 2024

Prerequisites

Version

all

Reproduction Link

No response

Describe the Bug

1.描述

在当前的 Cherry Markdown 引擎代码中,MD5 哈希算法被用于生成字符串的唯一标识符,主要用于缓存机制和大文本数据缓存。
MD5 是一种广泛使用的哈希算法,但由于其设计上的缺陷,已经不再被推荐用于安全性要求较高的场景。

2. MD5 哈希碰撞的风险

MD5 哈希算法的主要问题在于其存在哈希碰撞的风险。哈希碰撞指的是两个不同的输入数据生成相同的哈希值。尽管 MD5 的哈希值长度为 128 位,但在实际应用中,由于其算法设计的缺陷,攻击者可以通过构造特定的输入数据,生成相同的 MD5 哈希值。

2.1 碰撞攻击的可能性

实际应用中的风险:在 Cherry Markdown 引擎中,MD5 被用于生成缓存键和大文本数据的标识符。如果攻击者能够构造出具有相同 MD5 哈希值的不同输入数据,可能会导致以下问题:

缓存污染:攻击者可以通过构造碰撞数据,使得缓存机制返回错误的结果,从而影响系统的正确性。

数据篡改:如果大文本数据的标识符被攻击者利用碰撞攻击篡改,可能会导致数据完整性问题,进而影响系统的安全性。
例如使用该引擎的页面包含文章主题和评论区,那么将会允许攻击者通过评论纂改文章主题。

2.2 潜在的安全隐患
缓存机制的漏洞:如果攻击者能够构造出具有相同 MD5 哈希值的不同输入数据,可能会导致缓存机制返回错误的结果,从而影响系统的正确性。

大文本数据的安全性:大文本数据的标识符依赖于 MD5 哈希值,如果攻击者能够利用碰撞攻击篡改这些数据,可能会导致数据完整性问题,进而影响系统的安全性。

3. 建议的解决方案

为了降低 MD5 哈希碰撞带来的风险,建议采取以下措施:

替换 MD5 算法
使用更安全的哈希算法:建议将 MD5 替换为更安全的哈希算法,如 SHA-256 或 SHA-3。这些算法在设计上更加安全,能够有效避免哈希碰撞问题。

System Information

No response

Contributing

None

@kexinoh kexinoh added pending-no-confirmed The direction of this issue has not yet been determined. 🐞bug Something isn't working labels Dec 10, 2024
@sunsonliu
Copy link
Collaborator

感谢建议,当时选择MD5不选择SHA256是出于性能考虑。确实会有MD5碰撞问题,不过我们认为目前的碰撞几率带来的安全、数据一致性风险是可接受的,所以目前并没有替换成SHA-256等碰撞几率更低的哈希算法的计划哈。

@kexinoh
Copy link
Author

kexinoh commented Dec 10, 2024 via email

@sunsonliu
Copy link
Collaborator

收到,我们近期会再次评估下两种哈希算法的性能差异哈。

@kexinoh
Copy link
Author

kexinoh commented Dec 10, 2024

我下面有一个在浏览器环境下使用crypto-js的md5和sha256测时数据,下面所有的数据都是重复1000次的结果:
Hash Function Performance Test

String Length: 16

MD5 Average Time: 0.0065 ms
SHA256 Average Time: 0.0062 ms

String Length: 256

MD5 Average Time: 0.0096 ms
SHA256 Average Time: 0.0085 ms

String Length: 10000

MD5 Average Time: 0.2621 ms
SHA256 Average Time: 0.1649 ms

String Length: 100000

MD5 Average Time: 3.2312 ms
SHA256 Average Time: 2.1220 ms

代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>Hash Function Test</title>
    <!-- 引入CryptoJS库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
</head>
<body>
    <h1>Hash Function Performance Test</h1>
    <div id="results"></div>

    <script>
        const md5 = (str) => CryptoJS.MD5(str).toString();
        const sha256 = (str) => CryptoJS.SHA256(str).toString();

        // 生成指定长度的随机字符串
        function getRandomString(length) {
            let result = '';
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            for (let i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * characters.length));
            }
            return result;
        }

        // 测试哈希函数性能
        function testHashFunction(func, length, iterations = 1000) {
            const data = getRandomString(length);
            let startTime, endTime, total = 0;
            for (let i = 0; i < iterations; i++) {
                startTime = performance.now();
                func(data);
                endTime = performance.now();
                total += endTime - startTime;
            }
            const average = total / iterations;
            return average;
        }

        // 测试不同长度的字符串
        const lengths = [16, 256, 10000, 100000];
        const resultsElement = document.getElementById('results');

        lengths.forEach(length => {
            const md5Avg = testHashFunction(md5, length);
            const sha256Avg = testHashFunction(sha256, length);

            resultsElement.innerHTML += `
                <h2>String Length: ${length}</h2>
                <p>MD5 Average Time: ${md5Avg.toFixed(4)} ms</p>
                <p>SHA256 Average Time: ${sha256Avg.toFixed(4)} ms</p>
                <hr>
            `;
        });
    </script>
</body>
</html>

@sunsonliu
Copy link
Collaborator

震惊了,没想到sha256性能比md5还要好!我们这就安排替换,感谢建议哈

@sunsonliu sunsonliu removed the pending-no-confirmed The direction of this issue has not yet been determined. label Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants