Robert C. Martinは、SQLが不要であるとはどういう意味ですか?[閉まっている]


45

私は多くのRobert C. Martinのコンテンツを読んだり見たりしています。私は、ソリッドステートドライブのためにSQLが不要であると言ってきました。これをバックアップするために他のソースを検索すると、ハードドライブとソリッドステートドライブのSQLパフォーマンスの違いを説明するランダムな記事がたくさんあります(これは関連していますが、研究しようとしているものではありません)。

最終的に、私は彼が何を得ようとしているのか理解できません。彼はSQLをNo-SQLテクノロジーに置き換えると言っていますか?彼はファイルシステムのファイルにデータを保存すると言っていますか?それとも、SQLi攻撃のために、人々にSQL /リレーショナルデータベースの使用をやめさせたいのでしょうか?彼がやろうとしているポイントを逃しているのではないかと心配しています。

あなたが彼の心から直接読むことができるように、ここにいくつかのリンクを提供します:

  1. ボビーテーブル
  2. クリーン建築レクチャー

まず、SQLをシステムから完全に削除する必要があると述べています。

ソリューション。唯一の解決策。システムからSQLを完全に削除することです。SQLエンジンがない場合、SQLi攻撃はありません。

また、彼はSQLをAPIに置き換えることについて語っていますが、その前の引用と彼が記事の前半で述べていることから、SQLをAPIの背後に置くことを意味するとは思いません。

フレームワークは問題を処理しません; ...

サイドノート:SQLと言って、Robertはほとんどのリレーショナルデータベースを意味すると確信しています。すべてではないかもしれませんが、ほとんどです。いずれにせよ、ほとんどの人はとにかくSQLを使用しています。そう...

データの永続化にSQLが使用されていない場合、何を使用することになりますか?

それに答える前に、私も注意する必要があります。ロバートは、ソリッドステートドライブがデータの永続化に使用するツールを変更する必要があることを強調しています。SørenD.Ptæusの答えはこれを指摘しています。

また、「データ整合性」グループに対応する必要があります。さらなる調査の結果、ロバートは、datomicなどのトランザクションデータベースを使用する必要があると述べています。その後、CRUDはCR(作成および読み取り)に変わり、SQLトランザクションは完全になくなります。データの整合性はもちろん重要です。

このすべてを網羅する質問は見つかりません。私はロバートのガイドラインに一致する代替案を探していると思います。Datomicは1つですが、それですか?これらのガイドラインに適合する他のオプションは何ですか?また、ソリッドステートドライブで実際に機能しますか?


5
@ christo8989-「SQLをAPIに置き換えるとはどういう意味ですか?」コードベース全体にテキストクエリ言語(SQLエンジンに渡される)がないことを意味すると彼は解釈します。これを、クエリを記述する安全なメカニズムのみを公開するAPIの背後に隠します。APIの何かSQLエンジンにコマンドを生成することがあるが、それはあなたが結合パラメータなどの使用を強制することが可能な小さな面積で、変更などを行い制御する内部
アンドリュー

42
しかし、しかし、しかし... SQL APIです。これは、RDBMSのAPIです。たまたま、簡単に悪用される可能性がある非常に強力なAPIです。
バートヴァンインゲンシェ

25
テキストインターフェイスを持たないDB APIを作成すると、遅かれ早かれ、貧しいプログラマーが次のようなコードを書くことになりますeval(request.GET["table_name"] + ".get(pk=" + request.GET["pk"] + ")"))。本当に問題があるのはSQLではありませんが、貧弱で無知なプログラマーです。
ライライアン

6
@JimmyJames SQLは言語です。ただし、それはAPIではないという意味ではありません。SQLは、基礎となるストレージにアクセスするためのAPIを提供する言語です。
キュービック

5
@nocomprende SQLは、常にアプリケーションで使用するように設計されています。そうでなければ、それは事実上役に立たなかっただろう。ポイントは常に、アプリケーションに奇妙なカスタム形式をいじったり、データの保存方法に注意を払ったりすることなく、データを保存および取得する方法を提供することでした。
キュービック

回答:


74

ボブ・マーティンは、彼の主張をより明確にするために明らかに誇張しています。しかし、彼のポイントは何ですか?

彼は、SQLi攻撃のために、人々にSQL /リレーショナルデータベースの使用をやめてほしいと思っていますか?

私の理解では、そのブログ投稿(最初のリンク)で、Martinはリレーショナルデータベースではなく、SQLの使用をやめるように人々を説得しようとしています。これらは2つの異なるものです。

SQLは非常に強力な言語であり、ある程度標準化されています。複雑なクエリとコマンドを非常にコンパクトな方法で、読みやすく、理解しやすく、学習しやすい方法で作成できます。別のプログラミング言語に依存しないため、Java、C、C ++、C#、Python、Ruby、JavaScript、Basic、Go、Perl、PHPなどを好む場合でも、ほとんどのアプリケーションプログラマーが使用できます。

ただし、この機能にはコストがかかります。安全なSQLクエリ/コマンドを記述することは、安全でないSQLクエリ/コマンドを記述するよりも困難です。安全なAPIを使用すると、「デフォルト」で安全なクエリを簡単に作成できます。安全でない可能性のある人は、より精神的な、または少なくともタイピングの努力が必要です。それが、Martinが現在の形式でSQLに対して暴言を唱えている理由です。

問題は新しいものではなく、リレーショナルデータベースにアクセスするための標準SQLよりも安全なAPIがあります。たとえば、私が知っているすべてのORマッパーは、そのようなAPIを提供しようとしています(通常、他の主要な目的のために設計されています)。静的SQLバリアントは、サニタイズされていない入力データを使用した動的クエリの作成を困難にします(これは新しい発明ではありません:静的SQLをよく使用する埋め込みSQLは約30年前です)。

残念ながら、柔軟性があり、標準化された、成熟した、言語に依存せず、SQL、特に動的SQLほど強力なAPIはありません。それが、言及された問題を解決する現実的な方法として「SQLを使用しない」というMartinの提案に疑問を抱く理由です。彼の記事は、明日から盲目的に辿ることができる「ベストプラクティス」としてではなく、正しい方向への思考として読んでください。


2
少なくとも、通常はORMのようなものが提供する書き込み操作に使用することは避けられます。データベースのクエリに関しては、独自のSQLを記述しなくても、すでにかなりのことができます。今日では、データベース機能の「高度な」使用のみで、SQLの記述または複雑なデータ型(グラフ、地理データ、再帰)の使用が必要になります。
ウォルフラット

7
Martinは具体的に、使用するAPI はSQLほど強力であってはならないと主張しています。SQLの力は機能ではなく問題であるという彼の議論。彼が主張しているAPIは、アプリケーション固有のものであり、アプリケーションが絶対に必要とするのと同じくらい柔軟で強力でなければなりません。彼は、別の文字列ベースのクエリ言語を発明することに特に反対しています。
キュービック

3
@Cubic:Martinが言及した問題の解決策は、おそらくSQLほど強力ではないか、使いにくい必要があります。それが彼らの祝福と呪いです。
ドックブラウン

1
@Barmar:SQLは、あなたが得ることができるほどの高レベルであり、Bobは、それが明らかに安全でないと断言しています。
ロバートハーヴェイ

3
@ christo8989:マーティンがかつて彼のキャリアで書いたまたは言ったことのすべてに対する回答として、1つの答えを書き込もうとすることはあまり意味がないと思います。私の答えは、あなたのタイトルで与えられた質問に対するもので、私見が解釈されるべきである最初のリンクのブログ投稿がどのように説明されたかを主に説明しました。
Doc Brown

57

ボブ・マーティンの意見はまさにそれです。一人の男の意見。

プログラマーは、自分が書いているシステムを十分に理解して、そのセキュリティーとパフォーマンスについて十分な注意を払うことが求められます。つまり、SQLデータベースと通信している場合は、Bobby Tables Webサイトが行うことを実行します。つまり、入力データをサニタイズします。 これは、適切なパフォーマンスを約束するマシンにSQLデータベースを配置することを意味します。これらのことを行うには、非常によく知られた方法があり、絶対的なセキュリティや理想的なパフォーマンスを保証するものではありませんが、他の方法もありません。

現在、SSDを使用しているため、SQLが不要であるという主張は、まさにスペシャリストです。高速ハードドライブがまだ存在していなかったため、SQLは発明されませんでした。データ検索の概念を表現する業界標準の方法が必要だったために発明されました。リレーショナルデータベースシステムには、速度とセキュリティに加えて、業務に最適な他の多くの特性があります。特に、ACID。データの整合性は、少なくとも速度やセキュリティと同じくらい重要です。もしそれがなければ、不正なデータを保護したり、できるだけ早く取得したりするポイントは何ですか?

ある男性のヒステリーを福音とみなす前に、インターネットの記事をランダムに読むのではなく、アプリケーションとシステムのセキュリティとパフォーマンスを独自の用語で学ぶことをお勧めします。セキュリティ、パフォーマンス、堅牢なシステム設計には、単に「このテクノロジを回避する」だけではありません。

数人の不幸な人が誤って指を切ることがあるため、包丁を禁止していません。


16
Martinの記事をRDBMSの放棄を主張しているとは解釈しませんが、ソースコードでSQL文字列を直接エンコードまたは操作するのではなく、LINQ-to-SQLやJPA Criteria APIなどのRDBMSと対話する別の方法を使用します。
ジュール

27
だから私たちは彼の言うことを盲目的に従うべきではない...しかし彼は何を言っているのか?
-TRiG

33
ここのコミュニティで私が本当に嫌いなことの1つは、Clean Code / Uncle Bob-wayのことについて質問するとすぐに、人々はあなたが何か違うことをするべきだとあなたに急ぐことです。「ゴッホのようにペイントするには?」-「ゴッホは間違っていました。代わりにピカソのようにペイントしてください」。
R.シュミッツ

21
入力データをサニタイズしてインジェクション攻撃を回避することは、パラメーター化されたメソッド使用してコードを入力から分離したのバックアップオプションです。
ラチェットフリーク

17
すべての技術は破滅的であり、本質的に欠陥があります。それは時間の問題です。一方、私たちには、欠陥があり運命づけられた技術で、やらなければならないことがあります。

15

彼は実際に何を言っているのですか?

彼はSQLをNo-SQLテクノロジーに置き換えると言っていますか?

TL; DR:はい(並べ替え)

あなたが基本的に同じトピックでリンクしたものよりも最近の講演で彼は言います:「データベースは詳細です。なぜデータベースがあるのですか?」

彼は、データベースが回転ディスクからのデータアクセスを容易にするようになったと主張しますが、将来、新しい技術と彼が「永続RAM」と呼ぶもののおかげで、「[...]ディスクがなくなる」とハッシュテーブルやツリーなど、プログラマが使用する構造を使用してデータを保存します。

彼はさらに、新しい競合のために、リレーショナルデータベース全体がほぼ消滅すると予測しています。

もし私がオラクルだったら、自分の存在の理由が自分の下から消えていくので、かなり怖いでしょう。[...]データベースが存在する理由は消えつつあります。

おそらく生き残るいくつかのリレーショナルテーブルがあるでしょうが、今は健全な競争があります。

だから、彼にとってSQLインジェクションだけではありませんが、彼はSQLがこの点で本質的に欠陥があると意見を述べています。


著者のメモ:

この投稿の声明は、このトピックに関するRobert C. Martinの見解を理解するための引用にすぎず、著者の意見を表すものではありません。より差別化された視点については、Robert Harveyの回答を参照してください。


2
「永続RAM」は、前方互換性または後方互換性を考慮せずに、現在のアプリケーションの状態をシリアル化するためのデータベースの使用のみに対応しているようです。確かに、一部のデータベースはそのように使用されますが、決してすべてではありません(あなたではなく、Martinがこれを言っていることに気付きました)。
キュービック

7
マーティンは実際、データベースの唯一のポイントは低速ストレージを抽象化することだと言っていますか?ワオ。そして、これはロバート・ハーヴェイの答えを支持します:彼の意見は塩の巨大な粒でとられるべきです。たとえば、この観点では、DBの価値が一貫性のある永続的なデータモデルを維持しているとは見なされません。「パーシステントRAM」(SSD?)のデータ構造に対する彼の考え方は遅く、データ損失の可能性を広げます。NoSQLDBでさえ、ジャーナリングと不変データ構造を使用して永続レコードを安全に更新します。
アモン

3
@amonはい、ロバート・ハーベイはより差別化された視点を提供しています。しかし、OPがロバートC.マーティンが何を言おうとしているかについて具体的に尋ねたので、私は彼の「新しい」講演の一部を書き起こしました。
ソーレンD.プテウス

3
@amon-上記のDoc Brownの回答の最初の文を参照してください。マーティンは、それを広めるために、自分の主張を誇張した大げさな発言を頻繁に行います。彼は、すべてのデータベース操作をメモリ内のストアに置き換えることができることを意味するのではなく、何らかの形でSQLに触れるアプリケーションのコンポーネントを単純に持つことは、すべて回避する必要がある非常に十分なセキュリティリスクであることを意味するだけではありませんしかし、彼の言葉に直面して、彼はそれを言っていると解釈することができます。しかし、彼が本当にやろうとしているのは、みんなに立ち止まって考えさせることだけです。SQL/ RDBMSは私のアプリケーションに適しているのでしょうか?
ジュール

12
@Jules彼はしばしば誇張することを理解しています。しかし、彼のリーチと評判を考えると、「ボブおじさん」が彼が誇張しているとき、そして彼が実際に何を言っているのかを明確にしないのはまったく役に立ちません。彼が何かを教えていることになっている場合、特に彼が自分の考えを反映したり批判したりしないため、意味が理解されるまで、彼が言うすべてを二重に推測して再解釈することは実行不可能です。ある時点で、「彼の言うことを聞かない」と言う方が簡単な場合もあります。ボブおじさんが有害だと考えている場合もあります。
アモン

11

SQLは詳細です。詳細の知識は広がらないはずです。

コード内のより多くの場所でSQLが使用されるにつれて、コードはますますコードに依存するようになります。

より多くのSQLトリックを学ぶにつれて、SQLを使用してより多くの問題を解決します。つまり、永続化するために別のAPIに切り替えるには、単なる翻訳以上のものが必要です。あなたが持っていることに気づかなかった問題を解決しなければなりません。

データベース間でこの切り替えを実行することにもなります。1つは派手なウィズバン機能5を提供しているので、多くの場所でそれを使用して、派手なウィズバン機能5が独自のものであるかどうかを確認するだけで、ライセンス費用がかかり、費用がかかります。そのため、機能5を使用したすべての場所を掘り下げて、問題を自分で解決するだけで、後でウィズバン機能3を使用していることがわかります。

Javaの移植性を高めるものの1つは、CPUの特定の機能が利用できないことです。それらが利用可能であれば、私はそれらを使用します。そして突然、これらの機能がないためにJavaコードが動作しないCPUがあります。データベース機能についても同じです。

気づかないうちに自立を犠牲にするのは簡単です。SQLは与えられていない選択です。SQLを使用することを決定した場合は、1か所で決定してください。作ることができる方法でそれを作ります。

SQLにセキュリティ上の問題があり、永続メモリモデルに移行しているという事実は、SQLが絶望的であることを意味しません。それは選択であるという点をただ家に追いやるだけです。その選択をする権利を保持したい場合は、作業を行う必要があります。


80年代のデータベースの動きとボブおじさんの歴史はかなり厄介であることに注意してください。管理者がデータベース管理者に命を吹き込んだとき、彼はフラットファイルシステムですべての問題を解決しました。この出来事は彼を彼の素晴らしいコンサルティングキャリアへと押し上げました。(彼はこの話を彼の初期のきれいな本の1つで語っていますが、どちらも忘れてください)DBなしで問題を解決する方法を知っており、それらを使用するように振る舞う人にはほとんど忍耐がありません。

また、顧客が要求した最後の瞬間までDBをアプリケーションに追加することを延期し、オプション機能として1日で追加することについてのストーリーも語っています。私の推測では、彼は私たちのほとんどが依存症としてDBを使用する方法を見ていると思います。彼は私たちに習慣を蹴る方法を見せようとしています。


1
もちろん、アインシュタインです。

1
ああ、アインシュタインがボブを知っているのを知らなかった。または、そのボブは神でした。それは楽しいスタンドアップビットの特徴を持っているように聞こえますが。
candied_orange

9
@nocomprendeあなたは動機付けのポスターの安定した食事に住んでいますか?
candied_orange

2
しかし、ボブ神です。少なくともいくつかのために。
ピーターモーテンセン

3
私は神が人前で話すことがそれほど上手だとは信じません。
candied_orange

5

最初の引用の引用は(強調鉱山)、

ソリューション。唯一の解決策。システムからSQLを完全に削除することです。SQLエンジンがない場合、SQLi攻撃はありません。

SQLを置き換えるものは何ですか?もちろんAPI!テキスト言語を使用するAPIではありません。代わりに、適切なデータ構造と関数呼び出しのセットを使用して必要なデータにアクセスするAPI。

暴言は、アプリケーションプログラマがSQLを使用できるようにすることに反対です。

推奨される修正は、代わりにAPIを使用できるようにすることです。これは、SQLではなく、インジェクションを許可しません。

IMO、そのようなAPIの例には次のものがあります。

  • http://bobby-tables.com/csharpは、C#プログラマーがADO.NET APIを使用できることを示唆しています。

    ADO.NETは、全体または深い(すなわち、強力なまたは汎用)API、であるため、それは完璧な例ではありませんまた、入力生(または生っぽい)SQLにそのユーザーを可能にします。

  • 一部のSQL開発者またはデータベース管理者は、データベースを(限られた数の専門的に作成れた)ストアドプロシージャによるアクセスのみを許可するように構成し、アプリケーション開発者が独自の(危険な)SQLクエリの作成を許可しないように提案する

  • 「システムからSQLを削除する」別の方法は、REST APIなどを介してアクセスされる他のシステムにデータベース(SQLを公開する)を配置することです。

したがって、IMO、全体的なソリューションまたはシステムはまだデータベースを使用できます(特に、データベースエンジンが有用なACIDプロパティを実装し、適切にスケーリングすることを考えると、1つなしでやろうとするのは愚かかもしれませんアプリケーション固有のもの)。

データベースのSQL APIが、他のAPI(ADO、おそらくORM、Webサービスなど)の背後にあるアプリケーション開発者から隠されている場合、暴言の要件は満たされます。

より一般的には、アプリケーション固有のDAL(「データアクセス層」または「データベース抽象化層」)を持つことを意味すると思います。DALは、データを保存および/またはフェッチする方法と場所の詳細からアプリケーションを隔離します。DALは、SQLデータベースを使用して実装される場合とされない場合があります。


30年前にまさにこれを実現する製品を開発しました。また、基礎となるデータベースはSQLをサポートしていませんでした(まだ)。そして、関連テーブルのセットはデータベースに保存されました(それを待ちます...)。それを思いついた男は本当に頭が良かった。しかし、もはやプログラマーではありません。

私はこの答えが好きですが、彼はこれを言っていないかもしれないと思います。また、「Frameworksはこの問題を処理しません...」とも述べています。あなたの答えから、あなたはLinq-to-Sqlの使用は大丈夫だと言っているようですが、それは問題を処理するフレームワークではありませんか?
christo8989

@ christo8989わかりません。彼は、問題を処理しないフレームワークの例としてHibernateに言及しています。実際、OWASPは、「HibernateはSQLインジェクションに対する免疫を付与しません。APIを誤用する可能性があります。HQL(SQLのHibernatesサブセット)には、多少なりとも影響を与える特別なものはありません。」一方、私が述べたAPIの一部は、SQLをまったく公開せず、より優れたインシュレーターになるでしょう。HibernateはDALを実装するために使用するものかもしれません(ただし、それ自体は完全な絶縁DALではありません)。
-ChrisW

1
@ christo8989 augustl.com/blog/2016/... Datomicは(おそらく-SQL)データベースの周りに(ちょうど)別のラッパー/層であることを示唆している- 。Datomicは、ファイルシステムに直接書き込みません」の代わりに、あなたは番号を使用することができますDatomicのストレージバックエンドとしてのさまざまなデータベース:任意のSQL JDBCデータベースなど」
ChrisW

ADO.NETでSQLインジェクションを回避するためソリューションはそれほど複雑ではないことに注意してください。SQLでプレースホルダーを使用し、コマンドでパラメーターを使用し、そのパラメーターの値を設定します。
ZEVスピッツ

3

誰もがセキュリティの観点から、またはSQLレンズでこの質問に答えているようです。

ロバート・マーティンの講義を見ました。彼は、プログラマーとして、特定のプログラムに最適な多くの異なるデータ構造を使用していると語っています。したがって、すべてのデータを表構造に普遍的に保存するのではなく、データを取得してプログラムに直接ジャンプできるように、データをハッシュテーブル、ツリーなどに保存する必要があります。

私は彼のメッセージを、永続ストレージに関する現在の仮定を一瞬だけ捨てて、古いSQL表形式以外の将来の可能性を検討するべきだとだけ解釈した。SSDは候補ソリューションですが、唯一のソリューションではありません。


彼は、データのマルチユーザー同時読み取り/書き込みについてどう思いますか?
ChrisW

1
@ChrisWこれは実装の問題ではなく、永続的なデータストレージを改善する方法を見つけるという高レベルのアイデアだとは思いません。
キーナン

@ChrisW彼はまた、トランザクションデータベースについても語っています。永続化ツールとしてソース管理テクノロジーを使用します。その場合、トランザクションと更新よりもはるかに同時並行のフレンドリーな作成と読み取りのみを行います。
christo8989

@Keenanだから、彼は実際に実装を介してソリューションを提供していません。彼はただ何を考えているのか?
christo8989

1
@ christo8989彼が個人的にコンピューターサイエンスの永続的なストレージの問題に対する候補ソリューションの開発を先導してきたかどうかはわかりません。これはOPの質問の範囲外です。ボブおじさんは、すべてプラグインアーキテクチャです。アプリケーション開発の現在の業界標準は、データベースと緊密に結合し、その周りにアプリケーションを構築しているため、アプリケーションがデータベースに依存する場合、アプリケーションはデータベースに依存します。むしろ、ボブおじさんは「データベースは詳細である」と提案し、分離して交換可能にする必要があると提案しています。
キーナン

2

実際、彼はデータベースとSQLを使用するべきではありません-かなり明示的に。最初の参照はよく知られている問題であり、2番目の参照は暴言のように聞こえます。ただし、データベースを使用し、SQLを使用しない正当な理由があると解釈しています。私の観点からすると、これは合理的なアドバイスすらありません。

残念ながら、彼が使用している例は、彼が指摘するよく知られた解決策を備えたよく知られた例です。通常、プログラマーが自分が何をしているのか理解していないときに発生します。たとえば、次のようなSQLを含む文字列を作成します。

    my $sql="select a from b where a=$ui_val;";
    prepare($sql)
    execute($sql)

とは対照的に

    my $sql="select a from b where a=?;";
    prepare($sql)
    execute($sql,$ui_val);

これは、Ruby on Railsコードの例のようなDBI perlです。彼が提供するRailsコードは、安全なものと安全でないものとを混同しやすい。多くのORMがSQLの下にあるものを隠すので、多くの場合、SQLを構築して実行するインターフェイスを扱っています。これは、APIがあなたのために何をしているのとほとんど似ていませんか?

最初の参考文献の私の解釈は、よく知られている解決策を持っているよく知られている問題を置き換えるべきだと彼が提案しているということです。

また、これが正しく行われた場合、コードの記述が容易になり、読みやすくなることを言及していないことも残念です。さらに、彼は、SQLは非常に読みやすく、一般に期待されることを実行するということについては言及していません。

彼は部分的には正しいです。最終的には、無限に大きくて高速なメモリと無限に高速なプロセッサを備えています。コンピューティングを制約する現在の物理学から抜け出すまで、彼は正しくありません。

はい、回転ディスクは過去のものであり、現在はSSDを使用しています。ディスクはデータ転送ごとに約10ミリ秒で動作し、SSDは約0.5ミリ秒(500マイクロ秒)のデータアクセス時間で動作します。RAMは100ナノ秒のオーダーであり、プロセッサーは数百ピコ秒のオーダーで動作します。これが、データベースが必要な理由の中心です。データベースは、回転ディスクまたはメインメモリを備えたSSD間のデータ転送を管理します。SSDの出現は、データベースの必要性を排除していません。


4
「SQLの使用を停止」(最初のリンクから引用)は、彼がSQLを使用しないことを言っているように聞こえますが、私の理解では。
ドックブラウン

6
これは語順の問題です。実際には、これは元々電報

6
@nocomprendeそれで、あなたは彼が競合状態の犠牲者だと言っているのですか?まあ、おっと。彼はSQLトランザクションを使用することでそれを回避できました。
コンラッドルドルフ

たぶん、Visual BasicとFortranの非常に短い混合物です。すべてはどこで終わりますか?

1
@KonradRudolph:まあ、アセンブリから直接TSXを使用する人はほとんどいないということに同意すると思います。より高いレベルの抽象化があります。これらの抽象トランザクションはSQLトランザクションになりますか?私はそうは思いません。インタプリタ言語として、SQLはパフォーマンスのオーバーヘッドをもたらします。回転するハードディスク上のデータにアクセスするとき、それは本当に重要ではありませんでした。ただし、RAMのデータにアクセスする場合は手頃です。
–MSalters

2

回答

SQLi攻撃のために、人々にSQL /リレーショナルデータベースの使用をやめさせたいのでしょうか。

「Bobby Tables」の記事は、これとそれ自体がSQLを使用しない理由であることを示唆しているようです:

ソリューション。唯一の解決策。システムからSQLを完全に削除することです。SQLエンジンがない場合、SQLi攻撃はありません。

彼は他の場所で議論する他の理由があるかもしれません。私は彼の作品をあまり読んでいないので、知りません。

余談

この部分は実際には答えではありませんが、SQLの価値の問題ははるかに興味深いと思います(明らかに他の人もそうです)。

SQLの使用経験は豊富であり、SQLの長所と短所については十分に理解していると思います。私の個人的な感じは、使いすぎで濫用されているということですが、決して使用すべきではないという考えは、ばかげています。「SQL always」または「SQL never」を選択する必要があるという考えは、誤った二分法です。

SQLインジェクションがSQLを使用しないことの論点である限り、それは笑うことができます。これは非常にシンプルなソリューションでよく理解されている問題です。この引数の問題は、存在する脆弱性はSQLiだけではないということです。JSON APIを使用すると安全であると思われる場合、大きな驚きがあります。

すべての開発者は、「13日の金曜日:Attacking JSON-AlvaroMuñoz&Oleksandr Mirosh-AppSecUSA 2017」というタイトルのこのビデオ見る必要があると思います

それを監視する時間や傾向がない場合、ここに要点があります。多くのJSONデシリアライゼーションライブラリには、リモートでコードが実行される脆弱性があります。XMLを使用している場合、さらに心配する必要があります。SQLをアーキテクチャから禁止しても、システムは安全になりません。


SQLを禁止するだけでシステムが安全になると主張する人はいません。ボブおじさんは、システムがより安全になると主張し、SQLインジェクションが10年以上にわたってWebアプリケーションセキュリティの最大のリスクであり続けていることを考えると、業界がデータベースと通信する方法を改善する必要性を軽視すべきではないと思います。
メリトン-ストライキ

@meriton申し訳ありませんが、「解決策、唯一の解決策」はかなり明確に思えます。SQLiの問題の解決策は知られており、非常に簡単です。SQLの使用を停止するかどうかに関係なく、prepareステートメントを使用することに煩わされない人々は、安全でないシステムを作成することになります。これらは、基本的なグッドプラクティスに従うか、新しい仕事に就く必要がある専門家ではない人々です。
ジミージェームズ

2

私は短い声明だけに対処したい:

あるいは、SQLi攻撃のために、人々にSQL /リレーショナルデータベースの使用をやめさせたいのでしょうか?

いいえ。それは間違った仮定です。車の事故で死ぬ人々の責任があるので、私たちは車の使用をやめなければならないとは言えません。同様に、SQL /リレーショナルデータベース(またはこのコンテキストではRDBMSなど)は、攻撃者がWebアプリケーションで実行できる悪意のあるSQLペイロードに対して責任を負いません。この目的のために、SQLインジェクション防止チートシート全体があるので、著者はそれを意味していないと確信しています


2
自動化された車は、自動車事故の約98%を防ぎます。マシンをもっと信頼する必要があります。

3
「自動車事故で亡くなった人々に責任があるので、自動車の使用を停止する必要があるとは言えません(特別なおよび/または入念に管理された状況を除く)。我々はできる、絶対にそれを言います。そして、多くの合理的な人々はそうします。
コンラッドルドルフ

1
基本的に言っているのは、Javaで開発されたアプリケーションがハッキングされているため、Javaの使用を停止する必要があるということです。ダウン投票は十分であり、残りの部分については、常識を教えるためにここにいるのではありません。@KonradRudolph
ビラルベゲラジ18

2
@BillalBEGUERADJこれはやや誤った同等性です(ハッキングに対して安全なものはないため)たとえば、システムプログラミングのコンテキスト外でCを使用している場合は、間違っています。とにかく、私はあなたの答えをダウン票しませんでしたが、それ間違っています:あなたが主張することとは反対に、それはまさにボブ・マーティンが言っていることです(他の答えが示すように)。
コンラッドルドルフ

2

Martinの問題は、ユーザー入力から動的SQLを直接構築するプログラマーにあるようです(ご容赦ください。私は主にCおよびC ++プログラマーです)。

sprintf( query, "select foo from bar where %s;", user_input );

これは絶対に胸焼けのためのレシピ(したがってボビーテーブルのストリップ)。そのようなコードを実動システムに配置するプログラマーはパドリンに値します。

準備されたステートメントを使用し、入力を適切にサニタイズすることにより、問題を軽減できます(完全に排除されない場合)。プログラマーがクエリ文字列を直接構築しないように、SQLをAPIの背後に隠すことができれば、はるかに優れています(これはMartinが提唱するものの一部です)。

しかし、SQLを完全に取り除くことに関しては、それが実用的または望ましいとは思いません。リレーショナルモデルは有用であり、それがそもそも存在する理由であり、おそらくSQLはリレーショナルモデルを操作するための最適なインターフェイスです。

いつものように、それは仕事に適切なツールを使用することの問題です。ショッピングカートアプリが完全なリレーショナルモデルを必要としない場合は、リレーショナルモデルを使用しないでください(つまり、SQLを使用する必要はありません)。リレーショナルモデルが必要な場合は、ほぼ確実にSQLを使用することになります。


一方でsprintfSQLが必要とするサニタイズの種類が含まれていない、この目的のために特別に設計されている機能はやる、と完全に安全です。例:Entity Frameworkの中のSQLQuery
ロバートハーベイ

@RobertHarvey:そうだと思います。私の場合、私は主にCとC ++でサーバー側の仕事をしているのでsprintf、動的SQLを使用している人の例(ありがたいことに珍しい)を時々見ることがあります。
ジョンボード

1

リンクする2つのソースは、異なるメッセージを伝えます。

ブログ投稿では、実行時にデータアクセスロジックがテキストとして存在してはならず、信頼されていないユーザー入力と混同されないようにしています。つまり、ブログの投稿では、文字列を連結することでクエリの作成を非難しています。

講義は異なります。最初の違いは口調にあります:講義は推測し疑問を投げかけますが、非難しません。彼は、データベースが悪だとは言いませんが、データベースなしの永続性を想像するように私たちに挑戦します。彼は、リレーショナルデータベースが普及してから30年で多くのことが変わったと主張し、永続性テクノロジの選択に影響を与える可能性のある2つを強調します。

  • ストレージスペースは約100万倍増加しました-同等の価格で!その結果、ストレージを節約する必要が少なくなり、特に、削除する必要がなくなりました。追加専用ストレージを使用すると、読み取りロックが不要になるため、同時実行制御を簡素化できます。これにより、トランザクションが不要になります。
  • ほとんどのデータセットがRAMに適合し、読み取りレイテンシが大幅に削減されたため、アクセス時間が短縮されました。

これらの変化した状況は、最適な永続化テクノロジーを変更しますか?おもしろいことに、ボブおじさんは言っていない-おそらく彼は答えがすべてのプログラムにとって正しいとは思わないからだ。だからこそ、私たちが選択した持続性テクノロジーを石版に刻み込むのではなく、細部として扱うように警告し、受け取った知恵を仲間に伝えます。

代替手段はありますか?

文字列なしでデータアクセスロジックを記述することは完全に可能です。Javaランドでは、QueryDSLを使用できます。ここでは、データベーススキーマから生成されたタイプセーフな流れるようなAPIを使用してクエリが記述されます。このようなクエリは次のようになります。

JPAQuery<?> query = new JPAQuery<Void>(entityManager);
Customer bob = query.select(customer)
  .from(customer)
  .where(customer.firstName.eq("Bob"))
  .fetchOne();

ご覧のとおり、クエリロジックは文字列として表現されておらず、クエリの信頼できる構造と信頼できないパラメータを明確に分離しています(もちろん、QueryDSLはクエリテキストにパラメータを含めず、クエリを分離するために準備されたステートメントを使用しますJDBCレベルのパラメーターの場合)。QueryDSLでSQLインジェクションを実現するには、独自のパーサーを作成して文字列を解析し、構文ツリーに変換する必要があります。それを行ったとしても、おそらくのような厄介なもののサポートは追加しないでしょうselect ... into file。要するに、QueryDSLはSQLインジェクションを不可能にし、プログラマの生産性を向上させ、リファクタリングの安全性を高めます。実行中のギャグを生成するのに十分長い間存在していたWebアプリケーションセキュリティに対する最大のリスクを防止、開発者の生産性を向上させましたか?それでもクエリを文字列として記述しているとしたら、それは間違っています。

リレーショナルデータベースへの代替案としては、Postgresのことを知って好奇心旺盛であるマルチバージョン同時実行制御は、彼はおそらくのより多くのことを考えていたものの、追加専用のデータ構造アンクルボブの種類が話していることを正確にあるイベント・ストア、およびイベントソーシング一般的なパターン。これは、RAMに現在の状態を保持するという概念にもうまく適合します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.