JavaScript投稿を可能にすべく解決しなきゃいけないセキュリティ問題
この記事は、サイトの名前とデザインを一新した時に、最初に書くネタになると思うのですが、思い付いたので構成をメモっておきます。
掲示板やSNSなどにJavaScriptの投稿を許可すると、悪意あるコードが投稿される可能性があります。代表的なのが、XSS、iframeを使った他サイトの知らぬ間操作などですね。
この攻撃は、windowや、document、location、dom、ajaxなどを使って行われます。つまり、これらが使われているか調べれば、投稿されたJavaScriptに悪意ある攻撃が仕込まれているかわかるはずです。
ところがJavaScriptには、どんな機能を使っているか偽装する方法が用意されています。分類すると次のような感じでしょうか。
1.windowやdocumentなどを偽装する
グローバルスコープでthisを使ったり、selfプロパティを使えばできます。
2.プロパティ名を偽装する
例えば、document.cookieは、
document[ "c" + "o" + "o" + "k" + "i" + "e"]
や
const c = "cookie";
document[c]
なんて書けます。
3.文字列からコードを実行する
eval("alert(document.cookie)")なんてのは可愛いほうで、setIntervalや、数値オブジェクトのconstructorプロパティを使った方法まであります。
つまり、JavaScriptの実行内容を偽装する方法は無限にある、ということですね。
特に数値のconstructorから任意のコードが実行できる仕様を作るなんてどうかしてます。JavaScript投稿サイトなど断じて許さん、という意思を感じるほどです。
でもこれらを解決しなければ、JavaScript投稿サイトなんて作れません。偽装の方法が無限にあるのなら、実行時に判定するしかありません。
実行時とはつまり、どの機能を使って良いかを実行直前に判定する、ゲートのような仕組みを構築するということです。
ざくっと説明すると、本物のwindowやdocumentを偽物と入れ替えるAプラン、全ての処理実行時にオブジェクト、プロパティ、引数をチェックするBプランで対処します。
Bプランは理論上、JavaScriptに限らず全てのプログラムで使えるのですが、速度上不利なので、バックアッププランとして控えているだけです。実際には使うことはないと思われます。
理屈上はプランAで解決できるはずなんだけど、実装はコンパイラを作るようなものなので、簡単じゃないんですよね。
もう少しで、TreeJSやangularJSに対応できる希望的観測があるので、そこまでできたら、サイトデザインを一新して、ちゃんと公開する方向に持っていきたいなー。
iphone6sのJavaScript処理性能
ポケモンGoするために、スマホをiphone6sに変えました。もうすぐ出るiphone7を待てばいいのに。
ポケモン、なかなか面白いですね。
課金を考慮した複雑なゲームと違って、スタートからシンプルで、少し童心に戻る感じがしました。
でも長くプレイすると思うこともありますね、いろいろと。前回のブログと違うこと言いますが、シンプル過ぎ!とか、ジムのレベル高すぎるやろ!とか、家よりオフィスでプレイするほうが効率的!とか。
まぁ、そのうち外でプレイします┐(´ω`)┌
で、本題。
発売日が4年差ある新しいスマホ、iphone6sにかえました。めちゃめちゃ速いですね。ベンチマークなどで前のスマホと比べ10倍ぐらい処理能力がある、というのは知っていたのですが、まさかここまで違うか。
そこで最近充実しつつある、Webブラウザの3D機能のデモページを試しに再生してみました。
再生したJavaScriptによる3Dのサンプル:
http://phoboslab.org/wipeout/
iphone6sで再生した様子:
ちょっと動画撮影時のレートが良くないですが、ネイティブでないJavaScriptが、ここまで高速に動作するかと正直驚きです。Webの再生速度だけなら、仕事用パソコンと互角ちゃうかと一瞬思いました。(実際のところは数倍差あるようです)
よく、次のメインとなる開発技術はどっち!?、Webかネイティブか、って話があります。
長期的にはWebが勝つが未来の話だ、という意見が多い気がしますが、Googleなどで調べると、2016年はハイブリッドの時代で、Webとネイティブのいいとこを合わせよう、という意見を多く目にします(英語の場合ですが)。
JavaScriptはまだまだ機能不足ですし、iphone6sは今も上位機種ですが、この性能がスマホの普通になった時を考えると、、、意外とWeb技術の復権は近いのかも知れません。
とりえあえず、開発中のサイトはJavaScriptの復権に89%賭けてますので、いいタイミングで動けるようにしたいですね。
ちなみに、JavaScriptの実行速度チェック用に作っていたゲームは次のように再生されました。とにかくサイトの開発を進めよう。
プレイしてないのにポケモンGO雑感
ポケモンGo流行ってますね。プレイしようと思ったけど、スマホが古すぎてインストールできない(´;ω;`)
古いスマホでサイトのテストしたかったので、これまで意地になって機種変更してきませんでしたが、さすがにそろそろ潮時ということか。。もう5年以上も使ってますしね。
ポケモンGo、聞くところによると、なかなか面白いらしいですね。位置ゲーム開発プラットフォームを作っている身としては嬉しいです。
でも、「この流行が続くのはこの夏限りだよ、だってゲームとして単純で没入感がないもん。移動すんのも面倒。」って声何度か聞きました。
これは発売前からそう言われてまして、いつまで流行が続くか僕にわかるわけもありませんが、没入感なし、移動面倒、って部分は視点としては真実をついていると思います。プレイしていない身で言うのもなんですが。
位置ゲームは、テレビゲームの没入感とは別の神経回路を使うと考えます。
テレビや映画を見る時に自身の体を体感として感じなくなることってありますよね。自分を忘れるといいますか。テレビゲームの没入感もこれを指してるんだろうなと思います。
この没入感というのはリラックスした状態で行う、言うなれば、「あちら側の世界」に移動しての遊びと僕は考えます。それに対して位置ゲームは、アクティブに自身の体に意識を持たせた「こちら側の世界」、没入感を持たない遊びになります。
人間は、急にリラックスしたり、アクティブになったり切り替えるのが難しいので、遊びとしてはどちらかに偏ったものである必要があると考えます。
なので、位置ゲームはそれ自身がゲームとして成り立つというよりは、アクティブな「こちら側の世界」の遊びを強化する立場である必要があります。たぶんね。
個人的に思うのは、任天堂(ナイアンテック)もその辺は分かってて、こういうゲーム設計にしたんだと思います。位置ゲームは普通のゲーム設計とは相性が悪いと分かっていたので、アクティブ感を損なわない、単純なゲームにしているのかなと。
だから普通のテレビゲームと比較して、没入感なし(あちらの世界へ行けない)って言ってると本質を見失う可能性があります。
でも、いくら「こちら側の世界」で遊ぶとは言っても、いちいち歩くの面倒、ってのは間違いなく真実です。
でも実は、歩かなくてもアクティブ側の世界で遊ぶことはできるんですよね。そしてその遊びを強化する方法もいくつもある。歩きはその代表であるってだけだと思います。
freelancersでコーディングの仕事を依頼してみた
sightlasを開発してて、なにが困るって、とにかく人手が足りない。でもタダで何ヶ月分も働いて!なんて人に頼むこともできず。多分、普通のwebサービスならもっと気軽に頼めたのでしょうけど。
補助金を受けたりもして、いろいろ手伝ってくれる人達もいるけれど、基本的には自分でひたすらコーディング。しかしこれでは限界があります。
そこで頼りになるのがクラウドソーシング。
いろいろなサイトがありますが、今回は、その中でも世界で最もワーカー登録者が多いと言われるfreelancersで頼んでみました。
依頼内容(概要):
Javascript投稿サイトを作りました。このサイトの対ハッキング機能のテストコードを書いて欲しい。誰か助けて!( TДT)まずは$300ドル分だけ働いてもらいたいです。
ものの数分のうちに沢山の返信が来ました。
さすがは、freelancers!さて、どんな提案内容なのだろう?
Aさん:
以前に似たサイトをデザインしました!PHP、Ruby、Perlなんでも来い!$555ドル。
Bさん:
私に任せてください! PHP,C# ASP.NET,MySql, Sql、さらにAndroidやiosでの開発も得意!$145ドル。
Cさん:
依頼内容を読みました!私達は10年以上にわたり様々な分野で開発をしてきました!$275ドル。
…お願いだから、依頼内容を読んでください。_| ̄|○ il||li
ま、下手な英語で書いたせいもあるでしょうけど、15人中、まともに読んだなと思えるのが1人だけ。まさか$300の報酬額が、読んだか読んでないかの判断材料になるとは思いもよりませんでした。
どうやら競争が激しく、また先に提案した人が採用される傾向が強いのでしょうね。とにかく最もらしい文言を片っ端から、それも恐らく組織的に送っているようです。
しかも提案された金額を変更できなくて、本文に書いてあるとおり、まずは$300だからね!って金額修正しようとしたら、もう一度プロジェクトを立ち上げないといけない仕様。
これでよく世界一のフリーランス数になってるな…。
(クレジットカードを広く受け付けてくれるので、それが理由なのかな…。)
数年前はちょっと仕事のお願いしたら、20人後半ぐらい募集があったけれど、今は提案人数が減っている。組織化していない人はどんどん淘汰されていっているのかも知れない。
いろいろ考えさせられます。
プログラムは目に見えない性質を持つ
よく良い・悪いプログラムとは何ぞや、って議論があります。ところが、良い悪いは宗教ですし、開発の状況にも依存します。
そのため、本ブログでは良い悪いではなく、プログラムの性質について書いていこうかなと思っています。
ここで言うプログラムの性質とは、物が上から下に落ちたり、走っている電車の中でジャンプしても後ろに移動しないといった、目に見えないが確実にコードの中に潜む、逆らうことができない力学のようなものを言います。
この力学を理解すれば、来世を信じる信じない、隣人に愛されるよりも愛したい、納豆にはネギを入れるかどうか、といった信条に惑わされることなく、一つの真実にたどり着けるでしょう(ホンマかいな)
で、これからその性質について語るわけですが、そもそも性質が見えるようになるには、実は条件があります。
それはプログラムを整理するということです。超重要です。これをしないと永遠に性質は見えません。
例えば、次のような関数があったとします(ここではjavascriptで記述しています)。
----------------------------------------------------
function f(x){
return x * 2 + 25 - 3 + x * 8 + 1 - 23;
}
----------------------------------------------------
これだと、xに対してどんな処理をして、値を返す関数なのか、さっぱり予想だにできませんが、整理すると…、
----------------------------------------------------
function f(x){
return 10 * x;
}
----------------------------------------------------
なんと!xを10倍して、その値を返しているのだ!
とわかります。
...ま、この程度なら、整理して意味あんのって感じですが。でも、これをより広く行うことで見えてくることがあるのです。
これは知っている人だけの話ですが、数学でも数式をどんどん整理して、それから考えますよね。あれと同じで、プログラムもどんどん整理していくことで見えてくることがいっぱいあるのです。
特にデザインパターンをほんとの意味で理解し、プロジェクトを炎上させないアーキテクトな設計者になるには、この整理した時に見える性質を把握していることが必須条件です。
長くなったので、また気が向いたら整理のポイントと、それにより見える性質、その後の世界について、順番に書いていこうかなと思います。
JavaScriptは、同じ名前の変数と関数が同じスコープにあった場合、常に変数が優先される
テストをしていて疑問に思ったのでメモ。
次のコードのようにJavaScriptでは、同じ名前の変数と関数を同じスコープに書くことができます。
スコープが違う場合、最も近いスコープにある変数や関数が使われますが、同じスコープに同じ変数と関数がある場合はどうなのだろうと、テストしてみた。
コード:
var a = 1;
function a(){
}
console.log("a:" + a);
function b(){
var b = 1;
console.log("b:" + b);
}
b();
(function(){
var c = 1;
function c(){
}
console.log("c:" + c);
})();
結果:
同じスコープだと、常に変数が優先されます。
定義された関数が意味不明の値になる場合は、同じ名前の変数が間違って定義されていないか要チェックですね。
chrome:50.0
internet exproler:11
firefox:45.0
技術はシステムエンジニアとプログラマを一体化するほうに進化する
設計書だけ書いてプログラムを書けないSEはいらない、という話がよくあります。
その是非はともかくとして、ドッグイヤーのIT業界はSEとPGを統合する方向に技術は進化しています、って話です。
知っていますか?
昔は、プログラムといえば、パンチカードに穴をあけてやっていたらしいです。僕は知らないですが。
それが進化して、アセンブリでプログラムできるようになったらしいです。CPUのレジスタAの値をレジスタBからコピーしてレジスタBの値をクリアする、みたいな頭痛いプログラムをガリガリ書いたとか。
さらに、「高級言語」のCが登場して、コンパイラを前提にした効率的なプログラムが可能に。構造体も出現。
さらに、C++でクラスが出現。
さらに、C#とかJavaでガベージコレクションなどが当たり前に。
さらに、特定の開発に特化したフレームワークができてきて、開発スピードがぐんとアップしました。
ここで次の2つの作業があったとします。
(1)こんなシステムを作りたい、それを資料に書く(SEの仕事)
(2)資料に書かれた内容からプログラムする(PGの仕事)
昔は、
(1)SEの作業が10だとしたら、
(2)PGの作業は100ぐらいあったんですよ。きっと。
なので、システムエンジニアとプログラマを分けて作業するのが効率的だった。
今は、たぶん、
(1)SEの作業が10のまま、
(2)PGの作業だけが20-30ぐらいまでに減ってしまった。
その結果、プログラマがいらなくなった!のではなく、(1)と(2)の作業を分けないで、1つの作業として、もうそのままプログラムしたほうが早いのでね?となったようです。
(1)SEの作業に1人、(2)PGの作業に3人雇うよりも、
(1)(2)合わせて3人雇う(設計書はいらん)
そのほうが効率的なプロジェクトが増えたのだと思います。
たぶん、PGとSEを一体化したほうがいいかの判断は、業界、開発の規模、使用する開発環境にもよると思います。
でも、ここで重要なことは、この技術の進化はまだ当分続くだろう、と思われることです。
今の状況がすぐに変わることはないと思いますが、長くこの業界で働こうという方は気を付けたほうが良さげです。