编写标记网页CVE浏览器插件
一个标注当前页面CVE编号的浏览器插件 前言
实现逻辑
window.find搜索在页面上找到用户可见的CVE编号。 代码实现
innerText匹配CVE编号,再将获取到的完整CVE编号传给window.find在用户可见页面搜索完整的CVE编号获取选块。function FindCVE() {
GetBaseURL();
if (DefaultBaseUrl.startsWith(location.hostname)){
return;
}
const regex = new RegExp('\\bCVE-\\d{4}-\\d{4,7}\\b', 'gmi');
document.designMode = "on";
const sel = window.getSelection();
sel.collapse(document.body, 0);
let m;
while (m = regex.exec(document.body.innerText)) {
while (window.find(m)) {
Mark();
}
}
document.designMode = "off";
}
function Mark() {
const userSelection = window.getSelection();
const id = userSelection.toString();
let cve = userSelection.getRangeAt(0).startContainer.parentNode;
if (cve.getElementsByClassName("Marked").length > 0) {
return;
}
const spanElement = document.createElement("span");
spanElement.setAttribute("class", "Marked");
const selectedTextRange = userSelection.getRangeAt(0);
selectedTextRange.surroundContents(spanElement);
const icon = document.createElement("a");
icon.href = DefaultBaseUrl + id;
icon.target = "_blank";
const svg = document.createElement('img');
svg.setAttribute("style", "background-color: rgb(154, 205, 50);");
svg.src = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJpY29uIGljb24tdGFibGVyIGljb24tdGFibGVyLWJ1ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggc3Ryb2tlPSJub25lIiBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTkgOXYtMWEzIDMgMCAwIDEgNiAwdjEiIC8+PHBhdGggZD0iTTggOWg4YTYgNiAwIDAgMSAxIDN2M2E1IDUgMCAwIDEgLTEwIDB2LTNhNiA2IDAgMCAxIDEgLTMiIC8+PHBhdGggZD0iTTMgMTNsNCAwIiAvPjxwYXRoIGQ9Ik0xNyAxM2w0IDAiIC8+PHBhdGggZD0iTTEyIDIwbDAgLTYiIC8+PHBhdGggZD0iTTQgMTlsMy4zNSAtMiIgLz48cGF0aCBkPSJNMjAgMTlsLTMuMzUgLTIiIC8+PHBhdGggZD0iTTQgN2wzLjc1IDIuNCIgLz48cGF0aCBkPSJNMjAgN2wtMy43NSAyLjQiIC8+PC9zdmc+";
icon.appendChild(svg);
spanElement.appendChild(icon);
}
第一个插件

manifest.json**文件的标注需要一个一个看是实现了什么功能。 权限
activeTab获取当前激活页面的用户交互页面操作,和scripting执行注入用户代码功能,最后的storage的保存BaseURL配置的。"permissions": [
"activeTab",
"scripting",
"storage"
],
用户代码
document_idle页面加载完成后将文件content-script.js注入到页面。"content_scripts": [
{
"run_at": "document_idle",
"all_frames": false,
"matches": [
"*://*/*"
],
"js": [
"content-script.js"
]
}
],
配置
storage权限。"options_ui": {
"page": "options/options.html"
},
browser.storage.local,对象进行get和set方法操作。const KeyName = 'base_url';
const DefaultBaseUrl = 'https://scap.kali-team.cn/cve/'
let Config = {
base_url: DefaultBaseUrl,
};
async function updateUI() {
await browser.storage.local.get(KeyName)
.then((item) => {
document.querySelector('#base_url').value = item.base_url || DefaultBaseUrl;
})
}
async function updateBaseUrl() {
Config.base_url = document.querySelector('#base_url').value;
await browser.storage.local.set(Config);
updateUI();
}
async function resetBaseUrl() {
await browser.storage.local.set(Config);
updateUI();
}
document.addEventListener('DOMContentLoaded', updateUI);
/**
* Handle update and reset button clicks
*/
document.querySelector('#update').addEventListener('click', updateBaseUrl)
document.querySelector('#reset').addEventListener('click', resetBaseUrl)

调试

书签插件
content-script.js文件里面的javascript代码复制进去就可以了,注意不要复制前面的Tampermonkey**注释。
TamperMonkey
// ==UserScript==
// @name Mark CVE
// @namespace http://tampermonkey.net/
// @version 0.1.2
// @description Mark the current page CVE
// @author Kali-Team
// @match *://*/*
// @exclude https://scap.kali-team.cn/*
// @icon https://avatars.githubusercontent.com/u/99640169?s=200&v=4
// @grant none
// @run-at document-idle
// @homepage https://github.com/cn-kali-team/mark-cve
// @license GPL-3.0-only
// ==/UserScript==
效果


参考