質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

2回答

3102閲覧

メタプログラミングの危険性について

marimo.

総合スコア48

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2017/08/23 14:36

コードからコードを生成するのがメタプログラミングという認識でいます。
またこれはすなわち文字列を変数として扱う必要性が伴うことも指しています。
しかしながら文字列を変数として扱うことは危険である、やめた方がいい、ということがいろんな記事で見かけます。
メタプログラミングが危険なのか、そもそも文字列を変数として扱うことが危険なだけで、文字列を変数として扱わないメタプログラミングもあるのか、その点についてご指摘いただければと思います。
宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

おそらく、インジェクション攻撃で任意のコードを実行させられる危険と言うことを言っているのだと思うので、メタプログラミング一般の話では無いでしょう。

メタプログラミングを行うと、初心者にわかりにくいプログラムになると言うことはありますが、それは危険性とは別の話です。

投稿2017/08/23 14:40

otn

総合スコア84557

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marimo.

2017/08/23 15:08

文字列を評価して変数として扱うのはメタプログラミングの中の一種であって全てではない、ということでしょうか。抽象化、というのがメタプログラミングの1つのキーワードな気がしますが、べつに抽象クラスを定義するのも極論メタプログラミングな気も致します。 抽象化=初心者にはわかりにくい、というようにコメントから理解致しました。
mattn

2017/08/23 15:53 編集

文字列評価はメタプログラミングの一種にすぎないですね。C++ であればテンプレートメタプログラミングですし、Lisp であればマクロです。どちらも文字列を使っている訳ではないです。また抽象化というのはまた別の話の様な気がします。Wikipedia に書いてありますが、ある言語のあるロジックを直接書かずに組み上げるのがメタプログラミングなので、例えばリフレクションを使った処理の記述もメタプログラミングの一つかと思います。初心者に分かりづらいというのはあくまで直感的でないという意味で仰られたのではと思います。
marimo.

2017/08/23 15:56

なるほどなるほど。補足説明ありがとうございます。 ggってもそれぞれの言語のメタプログラミング情報しか無かった(一般的なものが少なかった)のは、言語ごとにメタプログラミング手法があるからかもしれないですね。
mattn

2017/08/23 15:56

危険性というお題で話すならば、メタプログラミングではなく JavaScript の eval の様な物が該当するかと思います。こちらもメタプログラミングではないですが。
marimo.

2017/08/23 16:00

javascriptなどのフロントの言語は確かに危険性が密になっていそうです。 メタプログラミングについて誤解してた(というよりも理解の視野が狭かった)ようです。
otn

2017/08/23 22:12

こういう意見を求める質問は、すぐにBAを選ばずに、もっとたくさんの人の意見を聞いた方が良いと思いますよ。
marimo.

2017/08/24 15:00

確かにおっしゃるとおりですね。 これは議論的な話題なので暫く集まるまで待ってみます。 アドバイスありがとうございます。
guest

0

コードからコードを生成するのがメタプログラミングという認識でいます。

そうだね

またこれはすなわち文字列を変数として扱う必要性が伴うことも指しています。
しかしながら文字列を変数として扱うことは危険である、やめた方がいい

ん?話飛びすぎじゃない?
「文字列を変数」は単なるString型だから、「文字列を評価」と読み替えて考えていくよ。

さて、例えばAltJSはメタプログラミングの一種だけど危険とは思えないし、
Lispなんかのマクロに至っては文字列の評価ですらない。

そして「文字列を評価」すること自体も危険性を分かって使うなら大丈夫。
開発者が書いたコードはそんなに危険じゃないんだよ。
危険なのは「ユーザーの入力値」を評価すること。

例えばTwitterのツイートやSNSの日記にクッキーのセション情報を別の鯖に保存するJavaScript文を記載して動作させて、その文章を見ただけでログイン情報を抜き出されてしまう脆弱性に繋がるとか、
ユーザーの入力値をDBに保存しようとしたら、SQL文を改ざんされてDELETE FROM usersみたいな文章を埋め込まれて実行してしまうとかね。
(もちろん有名なサービスは全て対策済だろうから安心して使えるけどね!)

JavaScriptやPHPでevalは危険だから使うなよ!絶対使うなよ!と言われる理由は下記3つだと思う

  • ユーザーからの入力値に使ってしまい脆弱性の原因に
  • 抽象化されるので読みづらいコードになる
  • テストがしにくく、不具合を突き止めづらい

未熟なエンジニアは何も考えずに脆弱性を埋め込んでしまう。
この論外な事件が相次いだから皆が口酸っぱくして言ってるだけの話だと思うんだよね。
下2つも初心者は基礎も出来ないのに応用(メタプログラミング)しても読みづらい糞コードになるだけでしょ?
まず自分の使っている言語で上手く解決出来ないか頭をひねろという戒め的な所がある。

上級者は上手に抽象化するからあまり気にしないで良いと思う。
読みづらかったり、テストしにくいコードになるだけなら本末転倒だしね。
試してみたけどイケてないから結局辞めたとかもしょっちゅう。

投稿2017/08/24 13:58

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marimo.

2017/08/24 15:09

評価関数が何故危険なのか、について具体的な説明をしていただき助かります。 当方メタプログラミングについては学び途中でして、「メタプログラミング」でggっても言語別なものばかり…一般的なモノの「メタプログラミング」についての認識を理解をしてみたかったのです。 でもなぜ言語別にメタプログラミングが説明されるのかも、なんとなくですが理解できました。 自分自身、やはりコードは可能なだけ抽象化して書いておきたい、というのがあります。というのもプロダクトにおける機能を開発しているときに、他でも使うような共通クラス、コンポーネントを作る必要が出てきます。もちろん共通化させなくもできますが、それはつまりメンテナンスが大変になることに繋がると思っています。(同じコードが量産されるので) これを割けるためになるべく切り分けてコーディングすることを心がけているうちに「メタプログラミング」というのにぶつかりました。 それで今回のような質問をした次第です。 本当に勉強になりました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問