はてなキーワード: reCAPTCHAとは
ログイン時にチート対策としてreCAPTCHAが認証システムとして採用されていますが、かなり精度が低い。
画面全体に1台のオートバイがあるだけなのに質問が「自転車を選択してください」となり、仕方がないのでスキップしたら「もう一度お試しください」と出る。
間違えたのお前やんけ!と突っ込むこともできず、バックミラーはバイクに入るのか?見切れて隣のタイルに映るほんの少しの部分は?階段の手摺りは?等、曖昧な部分があまりにも多い、ちょっと頭の悪すぎる認証システム。
例えば下記のオートバイってお題だったら、人は含めずバイクの部分だけを選択するのか?ミラーは含めるのか?複数あったら全部選択するのか?右下の人も絶対オートバイに乗ってると思うけど選ぶのかとか、ちょとだけタイヤがかすってるタイルも選ぶのかとか、まず選ぶ基準を教えてくれよと。
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 https://anond.hatelabo.jp/20250710133749# -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaG9DngAKCRBwMdsubs4+ SPMeAQCoodR1aMbbm7Fu/keBht5uqrVBrN13aFwvFfaucwuoawD/dRGES/FWTAUd BxbueiosA5qaiYxa506g9PGzXM5YUwI= =9ZTf -----END PGP SIGNATURE-----
一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。
// ==UserScript==
// @name PGP未署名検出と別タブ自動編集
// @namespace http://tampermonkey.net/
// @version 1.0
// @description PGP署名がない投稿を自動編集ページへ誘導
// @match https://anond.hatelabo.jp/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM.openInTab
// ==/UserScript==
(function () {
'use strict';
const body = document.getElementById('entry-page');
if (!body) return;
const titleText = document.title;
if (!titleText.includes('dorawii')) return;
const pgpRegex = /BEGIN.*PGP(?: SIGNED MESSAGE| SIGNATURE)?/;
const preElements = document.querySelectorAll('div.body pre');
let hasPgpSignature = false;
for (const pre of preElements) {
if (pgpRegex.test(pre.textContent)) {
hasPgpSignature = true;
break;
}
}
if (hasPgpSignature) return;
const editLink = document.querySelector('a.edit');
const childTab = GM.openInTab(editLink.href, { active: false, insert: true, setParent: true });
})();
// ==UserScript==
// @name 編集ページ処理と自動送信・閉じ
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 編集ページで署名処理と送信、タブ自動閉じ
// @match https://anond.hatelabo.jp/dorawii_31/edit?id=*
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_notification
// @connect localhost
// ==/UserScript==
(async function () {
'use strict';
const shouldRun = await GM_getValue('open-tab-for-edit', '0');
const textareaId = 'text-body';
const textarea = document.getElementById(textareaId);
if (!textarea) return;
const content = textarea.value;
const pgpSignatureRegex = /-----BEGIN PGP SIGNED MESSAGE-----[\s\S]+?-----BEGIN PGP SIGNATURE-----[\s\S]+?-----END PGP SIGNATURE-----/;
if (pgpSignatureRegex.test(content)) {
console.log('[PGPスクリプト] 署名が検出されたためそのまま送信します');
return;
}
const httpRequest = (url, data) => {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: `value=${encodeURIComponent(data)}`,
onload: function (response) {
resolve(response.responseText);
},
onerror: function (error) {
reject(error);
}
});
});
};
// textarea の値を取得
// 1. 現在のページのURLからURLオブジェクトを作成
const currentUrl = new URL(window.location.href);
// 2. ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得
const origin = currentUrl.origin;
// 3. 'id' パラメータの値 (例: "20250610184705") を取得
const idValue = currentUrl.searchParams.get('id');
// 4. ベース部分とIDを結合して、目的のURL文字列を生成
// idValueが取得できた場合のみ実行する
let newUrl = null;
if (idValue) {
newUrl = `${origin}/${idValue}`;
}
// 5. 生成されたURLを変数に代入し、コンソールに出力して確認
console.log(newUrl);
const valueToSend = newUrl;
try {
const signatureText = await httpRequest('http://localhost:12345/run-batch', valueToSend);
console.log('バッチ応答:', signatureText);
if (!signatureText.includes('BEGIN PGP SIGNED MESSAGE')) {
alert('PGP署名がクリップボードに見つかりませんでした。');
return;
}
const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';
textarea.value = newText;
console.log('[PGPスクリプト] 署名を貼り付けました。送信を再開します。');
const form = document.forms.edit;
const newForm = form.cloneNode(true);
form.replaceWith(newForm);
newForm.addEventListener('submit', async (e) => {
e.preventDefault(); // HTML標準のsubmitをキャンセル
const bodyText = textarea?.value || '';
// reCAPTCHA トークンの取得
const recaptchaToken = await new Promise((resolve) => {
grecaptcha.enterprise.ready(() => {
grecaptcha.enterprise.execute('hoge', { action: 'EDIT' })
.then(resolve);
});
});
// POSTするデータの構築
const formData = new FormData(newForm);
formData.set('body', bodyText);
formData.set('recaptcha_token', recaptchaToken);
formData.set('edit', '1');
try {
const response = await fetch(newForm.action, {
method: 'POST',
body: formData,
credentials: 'same-origin'
});
if (response.ok) {
console.log('送信成功');
window.close();
} else {
console.error('送信失敗', response.status);
}
} catch (err) {
console.error('送信中にエラーが発生', err);
}
});
// プログラム的に送信トリガー
newForm.dispatchEvent(new Event('submit', { bubbles: true }));
} catch (e) {
console.error('バッチ呼び出し失敗:', e);
}
})();
const http = require('http'); const { exec } = require('child_process'); const querystring = require('querystring'); const server = http.createServer((req, res) => { if (req.method === 'GET' && req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.method === 'POST' && req.url === '/run-batch') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { const parsed = querystring.parse(body); const value = parsed.value || 'default'; // 値を引数としてバッチに渡す exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) => { if (err) { res.writeHead(500); res.end('Error executing batch: ' + stderr); } else { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(stdout.trim()); } }); }); } else { res.writeHead(404); res.end('Not found'); } }); server.listen(12345, () => { console.log('Batch server running at http://localhost:12345/'); });
@echo off setlocal enabledelayedexpansion :: 署名するファイル名 set "infile=%~1" set outfile=%TEMP%\pgp_output.asc :: 以前の出力があれば削除 if exist "%outfile%" del "%outfile%" :signloop :: AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える) start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk" :: PGPクリア署名を作成 echo %infile% | gpg --yes --clearsign --output "%outfile%" :: 署名が成功していればループを抜ける if exist "%outfile%" ( goto postprocess ) else ( timeout /t 1 > nul goto signloop ) :postprocess powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body = Get-Content '%outfile%' -Raw; Write-Output ($header + \"`r`n\" + $body + $footer)" powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body = Get-Content 'signed.asc' -Raw; Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)" endlocal exit /b
#Persistent #SingleInstance ignore SetTitleMatchMode, 2 WinWaitActive, pinentry SendInput password Sleep 100 SendInput {Enter} ExitApp
動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 https://anond.hatelabo.jp/20250613185036 -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+ SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtl c7UqRuggNJ/UTa5xTIcKp622+7jJQQg= =Lgkl -----END PGP SIGNATURE-----
reCAPTCHAは一応基本無料でEnterpriseのほうもそんなに高くなかったような
月100万回以上呼び出すならEnterprise使えってだけ
それよりCloudflareのTurnstile使うほうがいい
https://anond.hatelabo.jp/20230123225612
あれから約8ヶ月、また新たな局面を迎えている為ここに記そうと思う。
このままでは「匿名掲示板による実況文化の消滅」が起きてしまう。
更に、匿名掲示板そのものの存続すら危なくなってきてしまったのだ。
この増田を投稿してから2ヶ月後、3ちゃんねるは閉鎖してしまった。
https://wikiwiki.jp/livejupiter/%E3%81%95%E3%82%93G
3ちゃんねる管理人はまともである分、昼間は普通に仕事をしている為昼夜逆転の生活を送っている異常なスクリプトやDDoS攻撃による荒らしに対応が遅れ、ただでさえなんG民の避難殺到でアクセスが集中していただけに耐えられなくなってしまったのだ。
先に注記しておくが、私はサーバーインフラ関連の知識は全くないため、いち掲示板の利用者としての意見・感想を述べていく。
一方こういった事態でも移住先や避難先を探し続けていたなんG民たちは防弾掲示板に着目。
https://wikiwiki.jp/livejupiter/%E9%98%B2%E5%BC%BE%E3%81%AA%E3%82%93G
ちなみに「防弾」の意味については詳しく知らないが、海外サーバーなのでちょっとやそっとの誹謗中傷や犯罪予告でも開示されないらしい。私はしたことがないので知らない。
さて、この防弾なんG・防弾なんU(一部定期スレの常駐)が避難先として定着すると春先からは徐々に野球実況もこちらで行われるようになった。
防弾なんGの最大の特徴(と私は認識している)のがスレを立てたイッチに限りスレタイがあとから変更できたり、実況モード(連投規制の緩和)や新規モード(レスをするための認証を緩和)にするなどコマンドが使えた。これは何らかの実況の後反省会スレに移行するなどなんG民の習性にあったものであり、コマンド機能は好評であった。
さてこの「レスをするための認証」だが、レスをするためには回線ごとに1日1回、簡単に言えば自動化スクリプトでは突破不能なreCAPTCHAなどを導入していた。(私はロボットではありませんみたいなやつ)
さっさと本家5ちゃんねるにも同等な機能を実装すればいいのだが・・・お気付きの通り5ちゃんねる運営は何もする気がないのでこの有様である。
ここからしばらく安定期が訪れ、防弾なんGに移住する者、5ちゃんなんGがスクリプトに荒らされた時だけ避難しに来る者、頑なに5ちゃんに残り続ける者などに分かれ、試合実況も分裂化し始めていた。
この頃はまだ試合実況が中途半端に成り立っており、実況スレにスクリプトが来たら次スレを立てるという文化になりかけたのだがいつしかそれすら追いつかなくなるほどの攻撃を受けだんだんと防弾なんGへの移住は進んだ。
そして転機は突然訪れる。
Talkという謎の掲示板が出現したことで5ちゃんねる全体が大混乱に陥った。この辺の経緯もwiki読んだ方が早い。
https://wikiwiki.jp/livejupiter/talk
簡単に説明すると、5ちゃんねる専用ブラウザ最大手であった「chmate」のみを置き去りにしてその他の専ブラが結託して「Talk」と呼ばれる自称5ちゃんねる後継を謳う掲示板に移行を図ったのだ。
一部では「もうスクリプトに悩まされなくていい」と好意的に捉えられた一方で、「あまりにも突然で何の説明もない」「chmateのみを除け者にした」「現状のTalkにはワッチョイがないどころか開発者を名乗る人物もワッチョイがなんなのか知らない」などの点から不信感・不満が噴出。
中でも問題になったのが「浪人(5ちゃんねるの課金)のサイトが閉鎖されており、返金も効かない。年間契約で購入した人間はどうなるのか?」という金銭関係の問題であり、これには消費生活センターに相談しようとするものまで現れた。
(wikiにも書いてある通り、浪人を販売していたのがジェーン社であるため)
更に、Talk出現後一旦スクリプトが止まったことやTalk掲示板にはスクリプトが出現しないことから「なんGや嫌儲を荒らしていた正体はJane Style側なのでは?」という疑惑が出た。
このあまりの横暴さと辻褄が合うことからなんG民はTalkを絶対に受け入れることが出来ず、その遺恨は今でも残る。
5ちゃんねるは自分で言うのもなんだがインターネットの財産であり、過去ログの消失は専門板に数十万数百万と残る叡智の消失に繋がる。
結局この騒動は一旦は収束を見せ、chmateによる5ちゃんねるの閲覧・書き込みが復旧した後は徐々にまたいつもの感じを取り戻していた。スクリプトは相変わらず復活したが。
そしてこの頃から防弾なんGが頻繁に鯖落ちを繰り返すようになる。原因はDDoS攻撃とされ、スクリプトが出来ない分こうしたアタックでサーバーを機能不全に陥らせていたのだ。(この攻撃もジェーンの仕業だと疑うなんG民も少なくなかった。もちろん飛躍した論議であり確証は一切なく半分陰謀論めいているが、最早何が起こっているか誰にも分からないのだ)
結局防弾なんGが使い物にならなくなるなか、新勢力「なんでも実況エッジ」通称「なんE」が誕生する。スクリプト対策はもちろんDDoS攻撃対策も施されたサーバー、クラウドフレアを使用していたらしい。私は先ほど申し上げた通りこの辺の知識がないのだが聞くところによれば攻撃自体は受けているものの一瞬重くなる程度で済んでいるとのこと。
このなんEが快適でちょっとサーバー落ちする程度ですぐ復旧していたため夏ごろからは専ら試合実況はこちらで行われていた。また、なんGでは避難誘導も行われ移住はますます進んだ。(なんEに避難してくださいとスレを立ててスクリプトが埋め立てれば勢いは上位に来るので目に留まりやすい。)
また先日、5ちゃんねるでは21時~0時まで課金しないと書き込めない謎の規制(結局21時半くらいに解除された日もあった)が始まったりすぐに終わったり、迷走が続いた。
またなんEではVTuber実況が大挙して移住してきてスレを乱立させ、歴史的経緯からバチャ豚を嫌うなんG民が多いため空気がピリピリしだした。
10月1日未明、またしても5ちゃんねる全板が重くなったりサーバー落ちしたり不安定な状態が続き、なんEが盛り上がっていた。
10月2日午前11時過ぎ、なんE管理人が突如「サービス終了について」というスレを立て、「このスレが埋まったら新規レスできなくします」と宣言。
あまりの突然の出来事に絶望、怒り、同情、感謝など反応はさまざまであったが一番異常だったのは、なんE管理人が提示した「1時間当たり400万件にのぼるDDoS攻撃」であった。
いくらDDoS攻撃に強いサーバーを使っているとはいえ、いち個人が提供し続けている個人の掲示板にこれだけの攻撃が来るのはどう考えても異常であり、犯罪行為である。
これ以上攻撃が拡大すれば迷惑がかかるだけでなく、管理人は「本格的に怖くなってしまった」と説明した。
決してサーバー費用面の問題ではなく、この異常な攻撃に個人ではもはや対処不能なのだ。
一方で翌日(本日未明)、防弾なんGが突如復活、管理人も降臨したものの忍法帖に登録している人間のIPアドレスとパスワードを流出させ死亡、一瞬のうちに閉鎖となった。
この3日間でエッジも防弾も失ってしまったなんG民に為す術はなく、また5ちゃんねるに帰らざるを得なくなったのだ。
一応今度はオフショアと呼ばれるエッジと似た仕組み?の避難所も出来たようだが、ここも個人運営な以上いつまで持つか分からない。
もっとも悲しいのは、ここ数年間の分裂、移住によりなんG人口そのものが減ったことである。
私みたいな匿名掲示板にこだわる一部の異常者を除き、まともな感性を持った人間は「またスクリプトに荒らされてるのか・・・」とうんざりして掲示板を辞めてTwitterやdiscordなどほかのツールで野球実況をするだろう。
スクリプトに荒らされていなくてもサーバーが重い状態が続き、エッジや防弾に分裂した実況スレにまで移住するのなんか少数派で、ここ最近の試合実況なんか1スレ完走するのがやっとなレベルだった。(※すでに両リーグ優勝決定後の消化試合であることには留意したい)
もう覚えてないが阪神優勝時の実況は確かエッジでやっていた気がする。
しかしまだドラフト、CS、日本シリーズ、オフシーズンのFAや現ドラが控えている。
そんな中でまともに実況や雑談が出来ない、我々はどうしたらいいのか?
この問題点について3つあげたい。
① 5ちゃんねる運営が公式的な声明を出す場がなく、また状況説明や対策等の措置が取られないこと
② DDoS攻撃・スクリプトによる埋め立て行為に対して現代の日本のサイバー警察などの技術では立件等が困難なこと
①だが、5ちゃんねるの運営はそもそも本当にいるのか?というところから私は考えたいと思う。
そして5ちゃんねるというのは「運用情報板」「規制議論板」など運営直下の板が複数あるため煩雑であり、どこで管理人とコンタクトを取り、説明し、管理人はどこで全掲示板の利用者に平等にアナウンスをするのかが一切形式化されていない。
そんな胡散臭い連中が運営している掲示板を何故使っているのかと言われればそれまでではあるが・・・。
②だが、スクリプトの特定はとても困難でIPアドレスも無数の回線に切り替えて爆撃しているため刑事ドラマでよく聞く「複数のサーバーを経由して・・・」みたいなのと同じ状況であると推察される。
これでは日本の警察どころか誰も追跡・特定出来ないのではないかと思う。そして、個人で400万件/hの被害を受けたエッジの管理人も法的措置に関しては何も言わなかった。無意味なことが分かっているからだ。
仮にネットに強い弁護士に相談したところで、「いかがでしたか?よく分かりませんでした!」というオチになるのが目に見えている。こういったサイバー攻撃に対してあまりにも無力であると痛感させられる。
③さが、匿名掲示板で雑談や実況するという文化そのものがこのままでは衰退してしまう。Twitterはいわば「強制コテハン」状態であり、いいねやフォロワーを気にしながら発言したりしなければならない。掲示板は匿名で全員が同じ立場である。インプレッション稼ぎもいないし、何かあればスレッドを立てて議論し、1000になれば解散し、日付を跨げば別人になる。もちろん5ちゃんねるに拘る必要は現時点で何もない。ないのだが、移住先はスクリプトやDDoS攻撃に潰される有様では何も出来ないのだ。
数十年と築いてきた掲示板がスクリプトに潰されるのはあまりにも無力で、情けないと思う。
スクリプトの正体は本当に不明で、もはや個人ではないのかもしれない。スクリプト自体も誰かが作ったものだろうし、DDoS攻撃を代行するサービスもあると聞いたので、本当の黒幕は1人なのかもしれないが、とにかく動機がわからないのだ。
少なくとも一瞬のうちに5ちゃんねるを機能不全に陥らせる能力があるのに、スクリプトを使って埋め立てて、阿鼻叫喚右往左往するなんG民たちを見てあざ笑っているようにしか見えない・・・