このコミットが含まれているのは:
2026-07-09 23:11:31 +09:00
コミット b19c24cb8e
8個のファイルの変更366行の追加46行の削除
+50 -8
ファイルの表示
@@ -1,18 +1,60 @@
const puppeteer = require ('puppeteer')
const fs = require ('fs')
const dns = require ('dns').promises
const net = require ('net')
const forbiddenNetworks = [
['0.0.0.0', 8], ['10.0.0.0', 8], ['100.64.0.0', 10],
['127.0.0.0', 8], ['169.254.0.0', 16], ['172.16.0.0', 12],
['192.0.0.0', 24], ['192.0.2.0', 24], ['192.168.0.0', 16],
['198.18.0.0', 15], ['198.51.100.0', 24], ['203.0.113.0', 24],
['224.0.0.0', 4], ['240.0.0.0', 4], ['::', 128], ['::1', 128],
['fc00::', 7], ['fe80::', 10], ['ff00::', 8], ['2001:db8::', 32],
['::ffff:0:0', 96]]
const blockList = new net.BlockList ()
forbiddenNetworks.forEach (([address, prefix]) => {
blockList.addSubnet (address, prefix, net.isIPv6 (address) ? 'ipv6' : 'ipv4')
})
const safeUrl = async rawUrl => {
const url = new URL (rawUrl)
if (!['http:', 'https:'].includes (url.protocol) || url.username || url.password)
return false
const addresses = await dns.lookup (url.hostname, { all: true, verbatim: true })
return addresses.length > 0 && addresses.every (
({ address, family }) => !blockList.check (address, family === 6 ? 'ipv6' : 'ipv4'))
}
void (async () => {
const url = process.argv[2]
const output = process.argv[3]
if (!(await safeUrl (url)))
throw new Error ('Unsafe page URL')
const browser = await puppeteer.launch ({
args: ['--no-sandbox', '--disable-setuid-sandbox'] })
const page = await browser.newPage ()
await page.setViewport ({ width: 960, height: 960 })
await page.goto (url, { waitUntil: 'networkidle2', timeout: 15000 })
await page.screenshot ({ path: output })
await browser.close ()
}) ()
try
{
const page = await browser.newPage ()
await page.setRequestInterception (true)
page.on ('request', request => {
void safeUrl (request.url ())
.then (safe => safe ? request.continue () : request.abort ())
.catch (() => request.abort ())
})
await page.setViewport ({ width: 960, height: 960 })
await page.goto (url, { waitUntil: 'domcontentloaded', timeout: 12000 })
await new Promise (resolve => setTimeout (resolve, 1000))
await page.screenshot ({ path: output })
}
finally
{
await browser.close ()
}
}) ().catch (error => {
console.error (error)
process.exitCode = 1
})