From 6f3fa739e3c45800ce3f21fc5b62b9516b5287b0 Mon Sep 17 00:00:00 2001 From: Sascha Leib Date: Mon, 8 Sep 2025 20:38:07 +0200 Subject: [PATCH] General cleanup --- .gitignore | 1 + action.php | 2 +- data/known-bots.json | 12 +++---- data/known-clients.json | 6 +++- data/rules.json | 78 ++++++++++++++++++++++------------------- php_errors.log | 45 ------------------------ plugin.info.txt | 2 +- script.js | 24 +++++++------ style.less | 2 +- 9 files changed, 69 insertions(+), 103 deletions(-) delete mode 100644 php_errors.log diff --git a/.gitignore b/.gitignore index 9e5648a..d0f2f3e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ logs/*.log.txt logs/*.srv.txt logs/*.tck.txt +php_errors.log diff --git a/action.php b/action.php index c85feaa..b422d75 100644 --- a/action.php +++ b/action.php @@ -91,7 +91,7 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin { $_SERVER['HTTP_USER_AGENT'] ?? '', /* User agent */ $_SERVER['HTTP_REFERER'] ?? '', /* HTTP Referrer */ substr($conf['lang'],0,2), /* page language */ - implode(',', array_unique(array_map( function($it) { return substr($it,0,2); }, explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE'])))) /* accepted client languages */ + implode(',', array_unique(array_map( function($it) { return substr($it,0,2); }, explode(',',trim($_SERVER['HTTP_ACCEPT_LANGUAGE'], " \t;,*"))))) /* accepted client languages */ ); //* create the log line */ diff --git a/data/known-bots.json b/data/known-bots.json index b91de3b..228d576 100644 --- a/data/known-bots.json +++ b/data/known-bots.json @@ -14,7 +14,7 @@ "n": "Google Ads Bot", "r": ["AdsBot-Google", "AdsBot-Google-Mobile", "Mediapartners-Google"], "rx": ["AdsBot-Google;","AdsBot-Google-Mobile;", "Mediapartners-Google\\/(\\d+\\.\\d+);"], - "url": "http://www.google.com/mobile/adsbot.html" + "url": "https://developers.google.com/search/docs/crawling-indexing/google-special-case-crawlers" }, {"id": "googleapi", "n": "Google API Crawler", @@ -154,10 +154,10 @@ "rx": ["ImagesiftBot[;\\s\\/]"], "url": "https://darkvisitors.com/agents/imagesiftbot" }, - {"id": "dotbot", - "n": "Moz.com DotBot", - "r": ["ImagesiftBot"], - "rx": ["DotBot\\/(\\d\\.\\d)[\\.;\\s]"], + {"id": "moz", + "n": "Moz.com Bots", + "r": ["dotbot", "rogerbot"], + "rx": ["DotBot\\/(\\d\\.\\d)[\\.;\\s]", "RogerBot\\/(\\d\\.\\d)[\\.;\\s]"], "url": "https://moz.com/help/moz-procedures/crawlers/dotbot" }, {"id": "maui", @@ -200,6 +200,6 @@ "n": "StartmeBot", "r": ["StartmeBot"], "rx": ["StartmeBot\\/(\\d+\\.\\d+)[;\\s\\(\\.]"], - "url": "https://www.sitesoverpages.com/bot" + "url": "https://support.start.me/en/articles/9182933-what-is-startmebot" } ] \ No newline at end of file diff --git a/data/known-clients.json b/data/known-clients.json index 5663613..813f5b1 100644 --- a/data/known-clients.json +++ b/data/known-clients.json @@ -41,7 +41,11 @@ }, {"n": "Edge", "id": "msedge", - "rx": [ "\\sEdg\\/(\\d+)", "\\sEdge\\/(\\d+)", "EdgiOS\\/(\\d+)" ] + "rx": [ "\\sEdg\\/(1\\d+)", "\\sEdge\\/(1\\d+)", "EdgiOS\\/(1\\d+)" ] + }, + {"n": "Edge Legacy", + "id": "oldedge", + "rx": [ "\\sEdg\\/([7-9]\\d)\\.", "\\sEdge\\/([7-9]\\d)\\.", "EdgiOS\\/([7-9]\\d)\\." ] }, {"n": "Old Chrome", "id": "chromeold", diff --git a/data/rules.json b/data/rules.json index f9ec517..b61047f 100644 --- a/data/rules.json +++ b/data/rules.json @@ -5,11 +5,11 @@ "id": "botIpRange", "desc": "Common Bot IP range", "bot": 50 }, - {"func": "obsoleteClient", "params": ["aol", "msie", "chromeold"], + {"func": "matchesClient", "params": ["aol", "msie", "chromeold","oldedge"], "id": "oldClient", "desc": "Obsolete browser version", "bot": 40 }, - {"func": "obsoletePlatform", "params": ["winold", "macosold"], + {"func": "matchesPlatform", "params": ["winold", "macosold"], "id": "oldOS", "desc": "Obsolete platform version", "bot": 40 }, @@ -33,19 +33,19 @@ "id": "langMatch", "desc": "Client’s ‘Accept-Language’ header does not match the page language (except English pages)", "bot": 20 }, - {"func": "clientTest", "params": ["brave"], + {"func": "matchesClient", "params": ["brave"], "id": "susClient", "desc": "Client identifier that is popular with bot networks", "bot": 10 }, - {"func": "combTest", "params": [["macos", "chrome"]], + {"func": "combinationTest", "params": [["macos", "chrome"]], "id": "unusualPC", "desc": "Unusual combination of platform and client", "bot": 10 }, - {"func": "combTest", "params": [["macos", "chromeold"],["macosold", "brave"],["winold", "edge"],["winold", "brave"]], + {"func": "combinationTest", "params": [["macos", "chromeold"],["macosold", "brave"],["winold", "edge"],["winold", "brave"]], "id": "suspPC", "desc": "Suspicious combination of platform and client", "bot": 30 }, - {"func": "combTest", "params": [["macos", "msie"], ["win10", "safari"]], + {"func": "combinationTest", "params": [["macos", "msie"], ["win10", "safari"]], "id": "impPC", "desc": "Impossible combination of platform and client", "bot": 100 }, @@ -55,36 +55,40 @@ } ], "ipRanges": [ - {"from": "3.0.0.0", "to": "3.255.255.255", "isp": "Amazon Data Services", "loc":"us"}, - {"from": "8.127.0.0", "to": "8.223.255.254", "isp": "Alibaba", "loc":"cn"}, - {"from": "24.240.0.0", "to": "24.243.255.254", "isp": "Charter", "loc":"us"}, - {"from": "27.106.0.0", "to": "27.106.127.254", "isp": "Huawei", "loc":"hk"}, - {"from": "34.0.0.0", "to": "34.191.255.254", "isp": "Google LLC", "loc":"zz"}, - {"from": "45.224.0.0", "to": "45.227.195.254", "isp": "Various BR ISPs", "loc": "br"}, - {"from": "46.250.160.0", "to": "46.250.191.254", "isp": "Huawei", "loc":"mx"}, - {"from": "49.0.200.0", "to": "49.0.255.254", "isp": "Huawei", "loc":"sg"}, - {"from": "94.74.64.0", "to": "94.74.127.254", "isp": "Huawei", "loc":"hk"}, - {"from": "101.0.0.0", "to": "119.255.255.254", "isp": "SinNet", "loc":"cn"}, - {"from": "111.119.192.0", "to": "111.119.255.254", "isp": "Huawei", "loc":"sg"}, - {"from": "119.0.0.0", "to": "101.207.255.254", "isp": "Unicom", "loc":"cn"}, - {"from": "121.91.168.0", "to": "121.91.175.254", "isp": "Huawei", "loc":"hk"}, - {"from": "122.8.0.0", "to": "122.8.255.254", "isp": "CN-ISP", "loc":"cn"}, - {"from": "122.9.0.0", "to": "122.9.255.254", "isp": "Huawei", "loc":"cn"}, - {"from": "124.243.128.0", "to": "124.243.191.254", "isp": "Huawei", "loc":"sg"}, - {"from": "150.40.128.0", "to": "150.40.255.254", "isp": "Huawei", "loc":"hk"}, - {"from": "159.138.0.0", "to": "159.138.225.254", "isp": "Huawei", "loc":"th"}, - {"from": "162.128.0.0", "to": "162.128.255.254", "isp": "Zenlayer", "loc":"sg"}, - {"from": "166.108.192.0", "to": "166.108.255.254", "isp": "Huawei", "loc":"sg"}, - {"from": "177.0.0.0", "to": "177.223.255.254", "isp": "THS", "loc":"br"}, - {"from": "183.87.32.0", "to": "183.87.159.254", "isp": "Huawei", "loc":"hk"}, - {"from": "187.180.0.0", "to": "187.183.255.254", "isp": "Claro", "loc":"br"}, - {"from": "188.239.0.0", "to": "188.239.63.254", "isp": "Huawei", "loc":"sg"}, - {"from": "189.1.192.0", "to": "189.1.255.254", "isp": "Huawei", "loc":"hk"}, - {"from": "189.76.0.0", "to": "189.127.255.254", "isp": "Hard Online", "loc":"br"}, - {"from": "190.92.192.0", "to": "190.92.255.254", "isp": "Huawei", "loc":"hk"}, - {"from": "192.124.170.0", "to": "192.124.182.254", "isp": "Relcom ", "loc":"cz"}, - {"from": "2804:0000:0000:0000:0000:0000:0000:0000", "to": "2804:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "isp": "Inspire", "loc":"br"}, - {"from": "2600:1f00:0000:0000:0000:0000:0000:0000", "to": "2600:1fff:ffff:ffff:ffff:ffff:ffff:ffff", "isp": "Amazon Cloud", "loc":"us"}, - {"from": "2001:4800:0000:0000:0000:0000:0000:0000", "to": "2001:4fff:ffff:ffff:ffff:ffff:ffff:ffff", "isp": "Rackspace/Google", "loc":"us"} + {"from": "3...", "to": "3.255.255.255", "label": "Amazon Data Services [US]"}, + {"from": "8.127..", "to": "8.223.255.254", "label": "Alibaba [CN]"}, + {"from": "24.240..", "to": "24.243.255.254", "label": "Charter [US]"}, + {"from": "27.106..", "to": "27.106.127.254", "label": "Huawei [US]"}, + {"from": "34...", "to": "34.191.255.254", "label": "Google LLC"}, + {"from": "45.224..", "to": "45.227.195.254", "label": "Various BR ISPs [BR]"}, + {"from": "45.131.216.", "to": "45.131.219.254", "label": "Lonconnect [BR]"}, + {"from": "46.250.160.", "to": "46.250.191.254", "label": "Huawei [MX]"}, + {"from": "49.0.200.", "to": "49.0.255.254", "label": "Huawei [SG]"}, + {"from": "84.37.35.0", "to": "84.37.255.254", "label": "GTT.net [US]"}, + {"from": "94.74.64.0", "to": "94.74.127.254", "label": "Huawei [HK]"}, + {"from": "101...", "to": "119.255.255.254", "label": "SinNet [CN]"}, + {"from": "111.119.192.", "to": "111.119.255.254", "label": "Huawei [SG]"}, + {"from": "119...", "to": "101.207.255.254", "label": "Unicom [CN]"}, + {"from": "121.91.168.", "to": "121.91.175.254", "label": "Huawei [HK]"}, + {"from": "122.8..", "to": "122.8.255.254", "label": "CN-ISP [CN]"}, + {"from": "122.9..", "to": "122.9.255.254", "label": "Huawei [CN]"}, + {"from": "124.243.128.", "to": "124.243.191.254", "label": "Huawei [SG]"}, + {"from": "142.147.128.", "to": "1142.147.255.254", "label": "Web2Objects LLC [US]"}, + {"from": "150.40.128.", "to": "150.40.255.254", "label": "Huawei [HK]"}, + {"from": "159.138..", "to": "159.138.225.254", "label": "Huawei [TH]"}, + {"from": "162.128..", "to": "162.128.255.254", "label": "Zenlayer [SG]"}, + {"from": "166.108.192.", "to": "166.108.255.254", "label": "Huawei [SG]"}, + {"from": "177...", "to": "177.223.255.254", "label": "THS [BR]"}, + {"from": "183.87.32.", "to": "183.87.159.254", "label": "Huawei [HK]"}, + {"from": "187.180..", "to": "187.183.255.254", "label": "Claro [BR]"}, + {"from": "188.239..", "to": "188.239.63.254", "label": "Huawei [SG]"}, + {"from": "189.1.192.", "to": "189.1.255.254", "label": "Huawei [HK]"}, + {"from": "189.76..", "to": "189.127.255.254", "label": "Hard Online [BR]"}, + {"from": "190.92.192.", "to": "190.92.255.254", "label": "Huawei [HK]"}, + {"from": "192.124.170.", "to": "192.124.182.254", "label": "Relcom [CZ]"}, + {"from": "2001:4800::::::", "to": "2001:4fff:ffff:ffff:ffff:ffff:ffff:ffff", "label": "Rackspace/Google [US]"}, + {"from": "2600:1f00::::::", "to": "2600:1fff:ffff:ffff:ffff:ffff:ffff:ffff", "label": "Amazon Cloud [US]"}, + {"from": "2804:::::::", "to": "2804:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "label": "Inspire [BR]"}, + {"from": "2a0a:4cc0:0:0:0:0:0:0", "to": "2a0a:4cc0:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "label": "Netcup [DE]"} ] } \ No newline at end of file diff --git a/php_errors.log b/php_errors.log deleted file mode 100644 index ecddbba..0000000 --- a/php_errors.log +++ /dev/null @@ -1,45 +0,0 @@ -[05-Sep-2025 05:57:33 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:57:33 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 05:57:43 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:57:43 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 05:58:04 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:58:04 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 05:58:13 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:58:13 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 05:58:35 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:58:35 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 05:58:43 UTC] PHP Warning: preg_match(): No ending delimiter '/' found in D:\Webroot\development\lib\plugins\botmon\tick.php on line 17 -[05-Sep-2025 05:58:43 UTC] PHP Warning: Undefined property: ErrorException::$getMessage in D:\Webroot\development\lib\plugins\botmon\tick.php on line 55 -[05-Sep-2025 06:55:56 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:56:00 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:56:27 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:56:30 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:56:58 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:57:00 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:57:29 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:57:30 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:58:00 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:58:00 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:58:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:58:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:59:01 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:59:02 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:59:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 06:59:33 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:00:01 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:00:04 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:00:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:00:35 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:01:01 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:01:06 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:01:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:01:37 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:02:01 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:02:08 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:02:31 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:02:39 UTC] PHP Parse error: syntax error, unexpected token "=" in D:\Webroot\development\lib\plugins\botmon\tick.php on line 18 -[05-Sep-2025 07:06:01 UTC] PHP Parse error: syntax error, unexpected token "}" in D:\Webroot\development\lib\plugins\botmon\pview.php on line 36 -[05-Sep-2025 07:09:36 UTC] PHP Fatal error: Uncaught Error: Undefined constant "loadTime" in D:\Webroot\development\lib\plugins\botmon\pview.php:34 -Stack trace: -#0 {main} - thrown in D:\Webroot\development\lib\plugins\botmon\pview.php on line 34 diff --git a/plugin.info.txt b/plugin.info.txt index 3c60c14..525b0b4 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base botmon author Sascha Leib email ad@hominem.com -date 2025-09-07 +date 2025-09-08 name Bot Monitoring desc Live monitoring of bot traffic on your DokuWiki instance (under development) url https://www.dokuwiki.org/plugin:botmon diff --git a/script.js b/script.js index f571429..b8818eb 100644 --- a/script.js +++ b/script.js @@ -830,8 +830,7 @@ BotMon.live = { let item = { 'from': BotMon.t._ip2Num(it.from), 'to': BotMon.t._ip2Num(it.to), - 'isp': it.isp, - 'loc': it.loc + 'label': it.label }; list.push(item); }); @@ -906,15 +905,15 @@ BotMon.live = { // list of functions that can be called by the rules list to evaluate a visitor: func: { - // check if client is one of the obsolete ones: - obsoleteClient: function(visitor, ...clients) { + // check if client is on the list passed as parameter: + matchesClient: function(visitor, ...clients) { const clientId = ( visitor._client ? visitor._client.id : ''); return clients.includes(clientId); }, // check if OS/Platform is one of the obsolete ones: - obsoletePlatform: function(visitor, ...platforms) { + matchesPlatform: function(visitor, ...platforms) { const pId = ( visitor._platform ? visitor._platform.id : ''); return platforms.includes(pId); @@ -945,7 +944,7 @@ BotMon.live = { }, // test for specific client identifiers: - clientTest: function(visitor, ...list) { + /*matchesClients: function(visitor, ...list) { for (let i=0; i= 0) { + return visitor.accept.split(',').indexOf(visitor.lang) >= 0; } return false; }, @@ -1428,6 +1427,9 @@ BotMon.live = { dl.appendChild(make('dt', {}, "User-Agent:")); dl.appendChild(make('dd', {'class': 'agent'}, data.agent)); + dl.appendChild(make('dt', {}, "Languages:")); + dl.appendChild(make('dd', {'class': 'langs'}, "Client accepts: [" + data.accept + "]; Page: [" + data.lang + ']')); + /*dl.appendChild(make('dt', {}, "Visitor Type:")); dl.appendChild(make('dd', undefined, data._type ));*/ @@ -1495,7 +1497,7 @@ BotMon.live = { if (tObj.func == 'fromKnownBotIP') { const rangeInfo = BotMon.live.data.rules.getBotIPInfo(data.ip); if (rangeInfo) { - tDesc += ` (${rangeInfo.isp}, ${rangeInfo.loc.toUpperCase()})`; + tDesc += ' (' + (rangeInfo.label ? rangeInfo.label : 'Unknown') + ')'; } } diff --git a/style.less b/style.less index bbd9d97..e266c09 100644 --- a/style.less +++ b/style.less @@ -283,7 +283,7 @@ span.bot_serpstat::before, dd.bot_serpstat::before { background-image: url('img/serpstat.svg') } span.bot_netestate::before, dd.bot_netestate::before { background-image: url('img/netestate.png') } span.bot_imagesift::before, dd.bot_imagesift::before { background-image: url('img/hive.svg') } - /*span.bot_dotbot::before, dd.bot_dotbot::before { background-image: url('img/moz.svg') }*/ + /*span.bot_mozcom::before, dd.bot_mozcom::before { background-image: url('img/moz.svg') }*/ /*span.bot_maui::before, dd.bot_maui::before { background-image: url('img/maui.svg') }*/ span.bot_plagaware::before, dd.bot_plagaware::before { background-image: url('img/plagaware.png') }