gregjacobs / Autolinker.js

Utility to Automatically Link URLs, Email Addresses, Phone Numbers, Twitter handles, and Hashtags in a given block of text/HTML
MIT License
1.48k stars 238 forks source link

Vulnerability: unterminated img src causes long execution #257

Closed wheresrhys closed 5 years ago

wheresrhys commented 5 years ago

The following test runner demonstrates the problem


const test = async (zeroes) => {
    const start = Date.now();
    const characterCount = Number('1' + [...Array(Number(zeroes))].map(() => '0').join(''))
    autolinker.link(`<img src="${[...Array(characterCount)].join('a')}`)
    console.log(`src of length ${characterCount} took ${Date.now() - start} ms`)
}

const testRunner = async degrees=> {

    const zeroes = [...Array(degrees)].map((_, i) => i);
    for (i in zeroes) {
        await test(i)
    }

}

testRunner(7)
gregjacobs commented 5 years ago

Hey @wheresrhys, thanks for this. I'll check it out!

gregjacobs commented 5 years ago

Figured it out: The regular expression which processed email addresses must have been doing a lot of backtracking on your input string. I replaced both the regexp-based html parser (#259) and email matcher (#260) with a state machine parser that runs in linear time. New output of your test driver with the changes:

src of length 1 took 0 ms
src of length 10 took 32 ms
src of length 100 took 2 ms
src of length 1000 took 3 ms
src of length 10000 took 11 ms
src of length 100000 took 98 ms
src of length 1000000 took 784 ms

Will be released in 3.0

gregjacobs commented 5 years ago

This is now up in 3.0. Let me know if you come across any other issues, and thanks for reporting!

wheresrhys commented 5 years ago

That sounds like an epic rewrite. Thanks a lot 🥂

gregjacobs commented 5 years ago

It definitely was an epic rewrite! But a long time coming, and definitely needed :) Glad to help!