'use strict'
var assert = require('assert')
var path = require('path')
var fs = require('fs')
var yaml = require('yamlparser')
var regexes = readYAML('../regexes.yaml')
var safe = require('safe-regex')
var refImpl = require('uap-ref-impl')
function readYAML (fileName) {
var file = path.join(__dirname, fileName)
var data = fs.readFileSync(file, 'utf8')
return yaml.eval(data)
}
suite('regexes', function () {
Object.keys(regexes).forEach(function (parser) {
suite(parser, function () {
regexes[parser].forEach(function(item) {
test(item.regex, function () {
assert.ok(safe(item.regex))
})
})
})
})
Object.keys(regexes).forEach(function (parser) {
suite(`no reverse lookup in ${parser}`, function () {
regexes[parser].forEach(function(item) {
test(item.regex, function () {
if (/\(\?<[!=]/.test(item.regex)) {
assert.ok(false, 'go parser does not support regex lookbehind. See https://github.com/google/re2/wiki/Syntax')
}
if (/\(\?[!=]/.test(item.regex)) {
assert.ok(false, 'go parser does not support regex lookahead. See https://github.com/google/re2/wiki/Syntax')
}
})
})
})
})
})
suite('redos', function(){
const parse = refImpl(regexes).parse
const tests = [
'"a"+"a"*3500+"a"',
'"SmartWatch"+" "*3500+"z"',
'";A Build HuaweiA"+"4"*3500+"z"',
'"HbbTV/0.0.0 (;LGE;"+" "*3500+"z"',
'"HbbTV/0.0.0 (;CUS:;"+" "*3500+"z"',
'"HbbTV/0.0.0 (;"+" "*3500+"z"',
'"HbbTV/0.0.0 (;z;"+" "*3500+"z"',
'"AppleWebKit/1."+"0"*10000+"!"',
'"AppleWebKit/1.1"+" Safari"*10000+"!"',
'"/0"+"0"*10000+"◎"',
'"Mozilla"+"Mobile"*10000+"!"',
'"Mozilla"+"Mobile"*10000+"!"',
'"Mozilla"+"Mobile"*10000+"!"',
'"Mozilla"+"Mobile"*10000+"!"',
'"Mozilla"+"Mobile"*10000+"!"',
'"Opera/"+"Opera Mobi"*10000+"!"',
'"Opera/1."+"0"*10000+"!"',
'"Mozilla"+"Android"*10000+"!"',
'"Chrome/1.1."+"0"*10000+"!"',
'"Chrome/1.1."+"0"*10000+"!"',
'"MSIE 1."+"0"*10000+"!"',
'"iPod"+"Version/1.1"*10000+"!"',
'"iPod;ACPUAOS 0_0"+"0"*10000+"◎"',
'"iPod;"+"CPU"*10000+"!"',
'"iPod;"+"CPUOS 1_1"*10000+"!"',
'"iPod;CPU"+"OS 1_1"*10000+"!"',
'"Version/0.0"+"0"*10000+"◎\n"',
'"HbbTV/0.0.0"+"0"*10000+"◎"',
'"HbbTV/1.1.1 ("+";a;"*10000+"!"',
'"HbbTV/1.1.1 ("+";a;2011"*10000+"!"',
'"HbbTV/1.1.1 (;a;"+"2011"*10000+"!"',
'"CPU OS 0.0"+"0"*10000+"◎"',
'"ArcGIS.iOS-0.0"+"0"*10000+"◎"',
'"x86_64 1.1."+"0"*10000+"!"',
'"x86_64 1.1.1"+"Chrome"*10000+"!"',
'" Darwin/91"+"0"*10000+"!"',
'" Darwin/101"+"0"*10000+"!"',
'" Darwin/111"+"0"*10000+"!"',
'" Darwin/121"+"0"*10000+"!"',
'" Darwin/131"+"0"*10000+"!"',
'"iPhone"+"Mac OS X"*10000+"!"',
'"CFNetwork/C Darwin/17.0"+"0"*10000+"◎"',
'"CFNetwork/"+" Darwin/17.1"*10000+"!"',
'"CFNetwork/"+" Darwin/16.1"*10000+"!"',
'"CFNetwork/ Darwin/16."+"0"*10000+"!"',
'"CFNetwork/8"+" Darwin/15.1"*10000+"!"',
'"CFNetwork/8 Darwin/15."+"0"*10000+"!"',
'"Linux 0.0"+"0"*10000+"◎"',
'" PTST/0"+"0"*10000+"◎\n"',
'"Mozilla"+"Mobile"*10000+"!"',
'"; AIRIS "+" "*10000+"◎"',
'";ASUS"+"_"*10000+"!"',
'";Excite "+"0"*10000+"!"',
'"; "+" "*10000+"◎"',
'";"+"Coolpad_"*10000+"!"',
'";TAC-"+"0"*10000+"!"',
'"; "+" "*10000+"◎"',
'"; Fly F30"+"0"*10000+"◎"',
'"; FONE 0"+"0"*10000+"◎"',
'"; "+" "*10000+"◎"',
'"; "+" "*10000+"◎"',
'"; "+" "*10000+"◎"',
'"; Build HuaweiA0"+"0"*10000+"◎"',
'"; "+" "*10000+"◎\n"',
'"; Ideos "+" "*10000+"◎"',
'"; NT-0"+"0"*10000+"◎"',
'";ImPAD"+"0"*10000+"!"',
'"; Intex AQUA "+" "*10000+"◎"',
'"; IBuddy Connect "+" "*10000+"◎"',
'"; I-Buddy "+" "*10000+"◎"',
'"; Karbonn "+" "*10000+"◎"',
'"; "+" "*10000+"◎\n"',
'"; LAVA IRIS "+" "*10000+"◎"',
'"; VS60"+"0"*10000+"◎"',
'"; VS60 "+" "*10000+"◎"',
'"; PhonePad 000"+"0"*10000+"◎"',
'"; SmartPad 000"+"0"*10000+"◎"',
'"; meizu_ "+" "*10000+"◎"',
'"; Cynus F5 "+" "*10000+"◎"',
'"; NXM0"+"0"*10000+"◎"',
'";Nokia"+"_"*10000+"!"',
'";IM-A111"+"0"*10000+"!"',
'";Pantech"+"0"*10000+"!"',
'"; Polaroid MIDC0000"+"0"*10000+"◎"',
'"; POMP "+" "*10000+"◎"',
'"; SAMSUNG Galaxy Note II "+" "*10000+"◎"',
'"; SAMSUNG-"+"0"*10000+"!"',
'"; SCH-0"+"0"*10000+"◎\n"',
'"; SC-0"+"0"*10000+"◎"',
'" SCH-0"+"0"*10000+"◎"',
'"; Xperia X0"+"0"*10000+"◎"',
'"; Sprint "+" "*10000+"◎"',
'"; TM-MID0"+"0"*10000+"◎"',
'";TM-SM"+"0"*10000+"!"',
'"; Videocon "+" "*10000+"◎"',
'";XOLO "+"tab"*10000+"!"',
'"; PAD 70"+"0"*10000+"◎"',
'";SmartTab"+"0"*10000+"!"',
'"; v89_"+"0"*10000+"◎"',
'"; e0000a_v0"+"0"*10000+"◎"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; IEMobile/ ; ARM; Touch; HTC_blocked "+" "*10000+"◎"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"Windows Phone ; "+"IEMobile/"*10000+"!"',
'"SAMSUNG-"+"0"*10000+"!"',
'"(Mobile; LYF/0/ ;"+";"*10000+"◎"',
'"(Mobile; LYF/A/"+";0rv:"*10000+"!"',
'"(Mobile; LYF/A/1;"+"rv:"*10000+"!"',
'"(Mobile; Nokia_A_"+"; rv:"*10000+"!"',
'"CFNetwork/"+" Darwin/1"*10000+"!"',
'"CFNetwork/ Darwin/1"+"(Mac"*10000+"!"',
'"Android 0.0-update1; AA-A ; "+" "*10000+"◎\n"',
'"Android 0.0.0; AA-A- ; "+" "*10000+"◎"',
'"Android 0.0.0; A- ; "+" "*10000+"◎"',
'"Android 0.0.0; -AA; "+" "*10000+"◎\n"',
'"Android 1; "+" Build"*10000+"!"',
'"Android 1; "+" Build"*10000+"!"',
'"foobar!/!./"+"/"*40000+"◎"',
'" #- regex: \'(iPad;(Version/0.0.08"+"8"*40000+"◎"',
'" #- regex: \'(iPad;"*8000',
'" #- regex: \'HbbTV/0.0.0 (; Sony;H;"+";"*40000+"◎1\n_\n"',
'" #- regex: \'HbbTV/1.1.1 (; Sony;"*600',
'"Windows Phone ; IEMobile/ ; ARM; Touch; HTC_blockedd"+"d"*40000+"◎1\n_\n)"',
'"Windows Phone "*8000',
'"HTC/HTC "+" "*20000+"\n"',
'"HTC/HTC "+" "*10000+"\n"',
'""+"Google"*5000+"! _1SLQ_2"',
'""+"MSIE 1.1;"*10000+"! _1SLQ_2"',
'""+"[FB"*10000+"! _1SLQ_2"',
'""+"[FB"*10000+"! _1SLQ_2"',
'""+"[Pinterest/"*5000+"@1 _SLQ_2"',
'""+"Mobile;"*5000+"! _1SLQ_2"',
'""+"FirefoxTablet browser 1."*3000+"! _1SLQ_2"',
'""+"Opera TabletVersion/1."*3000+"! _1SLQ_2"',
'""+"Opera/9180Version/"*5000+"! _1SLQ_2"',
'""+"Chrome/1 MMS/11"*5000+"! _1SLQ_2"',
'""+"PLAYSTATION 3"*5000+"! _1SLQ_2"',
'""+"AppleWebKit1 NX/1."*5000+"! _1SLQ_2"',
'""+"Windows Phone Edge/1."*3000+"! _1SLQ_2"',
'""+"amarok/"*10000+"@1 _SLQ_2"',
'""+"iPod1GSA/1."*5000+"! _1SLQ_2"',
'""+"iPod"*10000+"! _1SLQ_2"',
'""+"PlayBook"*10000+"! _1SLQ_2"',
'""+"Blackberry1Version/"*5000+"! _1SLQ_2"',
'""+"AppleWebKit/1+ "*5000+"! _1SLQ_2"',
'""+"HbbTV/1.1.1 (;Samsung;SmartTV0000;"*2000+"! _1SLQ_2"',
'""+"HbbTV/1.1.1 (;Samsung;SmartTV0000;"*2000+"! _1SLQ_2"',
'""+"HbbTV/1.1.1 (; Philips;"*3000+"! _1SLQ_2"',
'""+"HbbTV/1.1.1 (; Philips;"*3000+"! _1SLQ_2"',
'""+"HbbTV/1.1.1 (; Philips;"*3000+"! _1SLQ_2"',
'""+"Symbian/3"*10000+"! _1SLQ_2"',
'""+"Symbian/3"*10000+"! _1SLQ_2"',
'""+"BB10;1Version/"*5000+"! _1SLQ_2"',
'""+"BlackBerry"*5000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/1810 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/1811 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/2610 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/2810 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/3010 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/3210 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Gecko/3410 Firefox/"*3000+"! _1SLQ_2"',
'""+"(Mobile;1Firefox/1."*5000+"! _1SLQ_2"',
'""+"DoCoMo"*10000+"! _1SLQ_2"',
'""+"Mozilla"*10000+"! _1SLQ_2"',
'""+"SmartWatch("*10000+"@1 _SLQ_2"',
'""+"Android Application - Sony 1 "*3000+"! _1SLQ_2"',
'""+"Android Application - HTC HTC 1 "*3000+"! _1SLQ_2"',
'""+"Android Application - - 1 "*3000+"! _1SLQ_2"',
'""+"Android 3"*10000+"! _1SLQ_2"',
'""+";Vega"*10000+"! _1SLQ_2"',
'""+";ALLVIEWSpeed"*5000+"! _1SLQ_2"',
'""+";ARCHOSGAMEPAD"*5000+"! _1SLQ_2"',
'""+";BlackBird I8"*5000+"! _1SLQ_2"',
'""+";BlackBird "*5000+"! _1SLQ_2"',
'""+";CatNova"*10000+"! _1SLQ_2"',
'""+";P-1"*1000+"@1 _SLQ_2"',
'""+";Explay_"*10000+"! _1SLQ_2"',
'""+";IQ"*10000+"! _1SLQ_2"',
'""+";Pixel"*10000+"! _1SLQ_2"',
'""+";GSmart "*10000+"! _1SLQ_2"',
'""+";imx51_"*10000+"! _1SLQ_2"',
'""+";Haier "*10000+"! _1SLQ_2"',
'""+"Build/HCL ME Tablet "*3000+"@1 _SLQ_2"',
'""+";HP "*10000+"! _1SLQ_2"',
'""+"HTC Streaming Player "*3000+"@1 _SLQ_2"',
'""+";HYUNDAI T1"*5000+"! _1SLQ_2"',
'""+";imobile "*10000+"! _1SLQ_2"',
'""+";i-style"*10000+"! _1SLQ_2"',
'""+";iOCEAN "*10000+"! _1SLQ_2"',
'""+";NEC-"*10000+"! _1SLQ_2"',
'""+";Pantech "*10000+"! _1SLQ_2"',
'""+"Android 4."*5000+"! _1SLQ_2"',
'""+";PLT0000"*10000+"! _1SLQ_2"',
'""+";SAMSUNG "*10000+"@1 _SLQ_2"',
'""+";GT-B1111"*10000+"@1 _SLQ_2"',
'""+"; SAMSUNG-"*5000+"! _1SLQ_2"',
'""+";SK-"*10000+"! _1SLQ_2"',
'""+";ST1111"*10000+"! _1SLQ_2"',
'""+";ST1111"*10000+"! _1SLQ_2"',
'""+";Build/"*10000+"! _1SLQ_2"',
'""+"TOOKY "*10000+"! _1SLQ_2"',
'""+"TOUCHTAB"*10000+"! _1SLQ_2"',
'""+"VERTU "*10000+"! _1SLQ_2"',
'""+";GTablet"*10000+"! _1SLQ_2"',
'""+"Vodafone "*10000+"! _1SLQ_2"',
'""+"sprd-"*10000+"@1 _SLQ_2"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"Windows Phone "*5000+"@1 _SLQ_2)"',
'""+"(Mobile; ALCATELOneTouch ; rv:"*3000+"@1 _SLQ_2"',
'""+"(Mobile; ZTE ; rv:"*5000+"@1 _SLQ_2"',
'""+"(Mobile; ALCATELA; rv:"*3000+"@1 _SLQ_2"',
'""+"PlayBook"*10000+"! _1SLQ_2"',
'""+"webOS"*10000+"! _1SLQ_2"',
'""+"HPiPAQ"*10000+"!1 _SLQ_2"',
'""+"HbbTV;CE-HTML;"*5000+"@1 _SLQ_2"',
'""+"InettvBrowser/0.0 (;Sony"*3000+"@1 _SLQ_2"',
'""+"InettvBrowser/0.0 ("*5000+"@1 _SLQ_2"',
'""+"MSIE"*10000+"! _1SLQ_2"',
'""+"SMART-TV; "*10000+"! _1SLQ_2"',
'""+"SymbianOS/9.1"*5000+"! _1SLQ_2"',
'""+"Android "*10000+"@1 _SLQ_2"',
'""+"Android-1.1; AA-; WOWMobile "*3000+"! _1SLQ_2"',
'""+"Android-1.1-update1; AA-;"*3000+"! _1SLQ_2"',
'""+"Android-1.1;AA_;"*5000+"! _1SLQ_2"',
'""+"Android-1.1;-;"*5000+"! _1SLQ_2"',
'""+"Android 1; Build"*3000+"! _1SLQ_2"',
'""+"Android 1; Build"*3000+"! _1SLQ_2"'
]
function buildAttackString (attackString) {
const uas = attackString
.replace(/^"|"$/g, '')
.replace(/"?\+"([^"]+)"\*(\d+)/, (m, str, i) => {
const size = parseInt(i, 10)
if (!isNaN(size)) {
return (new Array(size).fill(str).join(''))
} else {
return m
}
})
.replace(/\+"/, '')
return uas
}
tests.forEach(attackString => {
test(attackString, function() {
const ua = buildAttackString(attackString)
const start = Date.now()
const parsed = parse(ua)
const diff = Date.now() - start
assert.ok(diff < 500)
})
})
})