Robert C. Martin은 SQL이 불필요하다는 의미는 무엇입니까? [닫은]


45

로버트 C. 마틴의 많은 내용을 읽거나보고 있습니다. 나는 솔리드 스테이트 드라이브로 인해 SQL이 필요하지 않다고 말했습니다. 이것을 백업하기 위해 다른 소스를 검색 할 때 하드 드라이브와 솔리드 스테이트 드라이브 간의 SQL 성능 차이 (관련되어 있지만 연구하려는 것은 아님)를 설명하는 무작위 기사가 많이 있습니다.

궁극적으로, 나는 그가 무엇을 얻으려고 노력하는지 이해하지 못한다. 그는 SQL을 No-SQL 기술로 대체한다고 말하고 있습니까? 파일 시스템의 파일에 데이터 저장을 말하는 것입니까? 아니면 사람들이 SQLi 공격으로 인해 SQL / 관계형 데이터베이스 사용을 중단하기를 원합니까? 그가 만들고자하는 요점이 빠질까 걱정이다.

나는 당신이 그의 마음에서 바로 읽을 수 있도록 여기에 링크를 제공 할 것입니다 :

  1. 바비 테이블
  2. 클린 아키텍처 강의

먼저 그는 SQL을 시스템에서 완전히 제거해야한다고 말합니다.

해결책. 유일한 해결책. 시스템에서 SQL을 완전히 제거하는 것입니다. SQL 엔진이 없으면 SQLi 공격이 없을 수 있습니다.

그는 SQL을 API로 대체하는 것에 대해 이야기하지만, 이전 인용문과 기사의 앞부분에서 말한 것처럼 API 뒤에 SQL을 배치한다는 의미는 아닙니다.

프레임 워크는 문제를 처리하지 않습니다.

참고 : SQL을 말할 때 Robert는 대부분의 관계형 데이터베이스를 의미한다고 확신합니다. 어쩌면 대부분이 아닐 수도 있습니다. 어쨌든 대부분의 사람들은 어쨌든 SQL을 사용하고 있습니다. 그래서...

SQL을 사용하여 데이터를 유지하지 않는다면 무엇을 사용해야합니까?

대답하기 전에, 나는 또한 주목해야한다. Robert는 솔리드 스테이트 드라이브가 데이터를 유지하는 데 사용하는 도구를 변경해야한다고 강조합니다. Søren D. Ptæus의 답변이 이것을 지적합니다.

또한 "하지만 데이터 무결성"그룹에도 대응해야합니다. 추가 연구 결과 Robert는 datomic 과 같은 트랜잭션 데이터베이스를 사용해야한다고 말합니다 . 그런 다음 CRUD는 CR (만들기 및 읽기)로 바뀌고 SQL 트랜잭션은 모두 사라집니다. 데이터 무결성은 물론 중요합니다.

이 모든 것을 포괄하는 질문을 찾을 수 없습니다. Robert의 지침에 맞는 대안을 찾고 있다고 생각합니다. Datomic은 하나이지만 그게 다입니까? 이 지침에 맞는 다른 옵션은 무엇입니까? 그리고 실제로 솔리드 스테이트 드라이브에서 더 잘 작동합니까?


5
@ christo8989- "SQL을 API로 대체한다는 것은 무엇을 의미합니까?" 나는 코드베이스 전체에 텍스트 쿼리 언어 (SQL 엔진에 전달됨)가 없다는 것을 의미한다고 해석합니다. 쿼리를 설명하는 안전한 메커니즘 만 제공하는 API 뒤에 이것을 숨 깁니다. API 내부에서는 무언가 SQL 엔진에 명령을 생성해야하지만 매개 변수 바인딩 등을 사용하고 변경하는 사람을 제어 할 수있는 작은 영역입니다.
andrew

42
그러나, 그러나 ... SQL API입니다. RDBMS 용 API입니다. 쉽게 오용 될 수있는 매우 강력한 API 일뿐입니다.
Bart van Ingen Schenau

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 사용을 중지하되 관계형 데이터베이스는 사용하지 않도록 설득하려고합니다. 이것들은 서로 다른 두 가지 입니다.

SQL은 매우 강력한 언어이며 어느 정도 표준화되었습니다. 읽기 쉽고 이해하기 쉽고 배우기 쉬운 방식으로 복잡한 쿼리와 명령을 매우 간단한 방식으로 만들 수 있습니다. 다른 프로그래밍 언어에 의존하지 않으므로 Java, C, C ++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP 또는 다른 것을 선호하든 대부분의 응용 프로그램 프로그래머에게 사용할 수 있습니다.

그러나이 기능은 비용이 많이 듭니다 . 안전한 SQL 쿼리 / 명령을 작성하는 것이 안전하지 않은 명령을 작성하는 것보다 어렵습니다. 안전한 API를 사용하면 "기본적으로"안전한 쿼리를 쉽게 만들 수 있습니다. 잠재적으로 안전하지 않은 사람은 더 정신적이거나 최소한 더 많은 타이핑 노력이 필요합니다. 이것이 Martin이 현재 형식으로 SQL에 대해 뛰고있는 이유입니다.

문제는 새로운 것이 아니며 관계형 데이터베이스에 액세스하는 표준 SQL보다 안전한 API가 있습니다. 예를 들어, 내가 아는 모든 OR 맵퍼는 이러한 API를 제공하려고 시도합니다 (일반적으로 다른 기본 목표를 위해 설계되었지만). 정적 SQL 변형을 사용하면 비위생 입력 데이터로 동적 쿼리를 작성하기가 어렵습니다 (새로운 발명이 아닙니다. 정적 SQL을 자주 사용하는 Embedded SQL은 약 30 세입니다).

불행히도, 표준화, 성숙, 언어 독립적이며 SQL, 특히 동적 SQL만큼 강력하고 유연한 API는 알지 못합니다. 이것이 내가 언급 한 문제를 해결하는 현실적인 방법으로 "SQL을 사용하지 않는다"는 Martin의 제안에 대해 의문을 갖는 이유입니다. 따라서 그의 기사를 올바른 방향에 대한 생각으로 읽으십시오. 내일부터 맹목적으로 따를 수있는 "모범 사례"가 아닙니다.


2
최소한 ORM과 같은 것들이 제공하는 글쓰기 작업에는 사용하지 않는 것이 좋습니다. 데이터베이스 쿼리와 관련하여 자체 SQL을 작성하지 않고도 이미 몇 가지 작업을 수행 할 수 있습니다. 요즘에는 데이터베이스 기능을 "고급"으로 사용하기 위해서는 SQL 또는 복잡한 데이터 유형 (그래프, 지리 데이터, 재귀)을 사용해야합니다.
Walfrat

7
마틴은 특히 사용하는 API가해야한다고 주장 않습니다 하지 SQL 강력한으로 될; SQL의 힘은 기능이 아니라 문제라는 그의 주장. 그가 주장하는 API는 응용 프로그램에 따라 달라야하며 응용 프로그램이 절대적으로 필요로하는만큼 유연하고 강력해야합니다. 그는 특히 다른 문자열 기반 쿼리 언어를 발명하는 것에 반대하고 있습니다.
큐빅

3
@Cubic : Martin이 언급 한 문제에 대한 해결책은 아마도 SQL보다 덜 강력하거나 사용하기 쉽지 않을 것입니다. 이것이 그들의 축복과 저주입니다.
Doc Brown

1
@Barmar : SQL은 가능한 한 높은 수준이며 Bob은 특허 적으로 안전하지 않다고 주장합니다.
Robert Harvey

3
@ christo8989 : Martin이 한 번 그의 경력에서 쓰거나 말한 모든 것에 대한 답변으로 하나의 답변을 작성하려고 시도하는 것이 의미가 없다고 생각합니다. 내 대답은 제목에있는 질문 중 하나였으며 IMHO가 처음으로 제공 한 링크의 블로그 게시물을 어떻게 해석해야하는지 설명했습니다.
Doc Brown

57

밥 마틴의 의견은 바로 그 것입니다. 한 사람의 의견.

프로그래머는 보안 및 성능에 대해 합리적인주의를 기울일 수있을 정도로 자신이 작성중인 시스템을 이해해야합니다. 즉, SQL 데이터베이스와 대화하는 경우 Bobby Tables 웹 사이트의 지시에 따라 입력 데이터를 삭제해야합니다. 이는 적절한 성능을 약속하는 머신에 SQL 데이터베이스를 두는 것을 의미합니다. 이러한 작업을 수행하는 방법은 잘 알려져 있고 잘 이해되어 있으며 절대적인 보안이나 이상적인 성능을 보장하지는 않지만 다른 방법은 없습니다.

이제 SSD가 있기 때문에 더 이상 SQL이 필요하지 않다는 주장은 그저 의심 스럽다. 고속 하드 드라이브가 아직 없기 때문에 SQL이 발명되지 않았습니다. 데이터 검색 개념을 표현하기 위해 업계 표준 방법이 필요했기 때문에 발명되었습니다. 관계형 데이터베이스 시스템은 비즈니스 운영에 이상적인 속도 및 보안 외에도 다른 많은 특성을 가지고 있습니다. 특히 ACID 입니다. 데이터 무결성은 최소한 속도 나 보안만큼 중요하며, 그렇지 않은 경우 불량 데이터를 보호하거나 가능한 빨리 데이터를 검색하는 요점은 무엇입니까?

한 사람의 히스테리를 복음으로 받아들이 기 전에 무작위 인터넷 기사를 읽지 않고 자신의 용어로 응용 프로그램 및 시스템 보안 및 성능에 대해 배우는 것이 좋습니다. 보안, 성능 및 강력한 시스템 설계에는 "이 기술을 피하는 것"보다 훨씬 많은 것이 있습니다.

우연한 소수의 개인이 실수로 손가락을자를 수 있기 때문에 부엌 칼을 금지하지 않습니다.


16
Martin의 기사를 RDBMS 포기를 옹호하는 것으로 해석하지 않고 소스 코드에서 SQL 문자열을 직접 인코딩하거나 조작하는 대신 LINQ-to-SQL 또는 JPA Criteria API와 같은 다른 방식으로 상호 작용하는 방법을 사용합니다.
Jules

27
그래서 우리는 맹목적으로 그가 말하는 팔로우 안 ...하지만 그는 무엇을 말하고있다 ?
TRiG February

33
Clean Code / Uncle Bob-way 에서 무언가를하는 것에 대해 질문을하자마자 사람들이 당신이 다른 것을 어떻게해야하는지 알려주는 사람들 입니다. "반 고흐처럼 페인트하는 방법?" - "반 고흐가 틀렸어요. 대신 피카소처럼 페인트해야합니다."
R. Schmitz

21
주입 공격을 피하기 위해 입력 데이터를 소독 하는 것은 매개 변수화 된 방법사용하여 코드를 입력과 분리 한 후 백업 옵션이어야합니다 .
ratchet freak

17
모든 기술은 파멸되고 본질적으로 결함이 있습니다. 시간 문제 일뿐입니다. 한편, 우리는 결함이 있고 운명이있는 기술로해야 할 일이 있습니다.

15

그는 실제로 무엇을 말하는가?

그는 SQL을 No-SQL 기술로 대체한다고 말하고 있습니까?

TL; DR : 예 (정렬)

기본적으로 당신이 연결 한 것보다 더 최근의 대화에서 그는 "데이터베이스는 상세하다. 왜 데이터베이스가 있는가?" .

그는 데이터베이스가 회전하는 디스크에서 더 쉽게 데이터에 액세스 할 수있게 됐다고 주장하지만, 미래 에는 새로운 기술과 "지속적인 RAM"이라고하는 디스크 덕분에 디스크가 없을 것입니다. 해시 테이블이나 트리와 같은 프로그래머가 사용하는 구조를 사용하여 데이터를 저장합니다.

그는 새로운 경쟁으로 인해 전체의 관계형 데이터베이스가 크게 사라질 것이라고 예측했습니다.

내가 오라클이라면 내 존재 이유가 저 밑에서 증발하고 있기 때문에 꽤 무서울 것입니다. [...] 데이터베이스가 존재하는 이유가 사라지고 있습니다.

살아남은 관계형 테이블이 있을지 모르지만 이제는 건전한 경쟁이 있습니다.

따라서 그는 SQL 주입에 관한 것이 아니라 SQL에 대해서는 본질적으로 결함이 있다고 생각 합니다.


저자의 메모 :

이 게시물의 진술은이 주제에 대한 Robert C. Martin의 견해를 이해하기위한 인용 일 뿐이며 저자의 의견을 나타내지 않습니다. 보다 차별화 된 관점은 Robert Harvey의 답변을 참조하십시오 .


2
'영구적 RAM'은 앞으로 또는 이전 버전과의 호환성에 관계없이 현재 응용 프로그램 상태를 직렬화하기 위해 데이터베이스 사용을 해결하는 것으로 보입니다. 물론 일부 데이터베이스는 그런 식으로 사용되지만 결코 모든 데이터베이스를 사용하지는 않습니다 (마틴이 이것을 말하는 것이 아니라 당신이 아니라는 것을 알고 있습니다).
큐빅

7
Martin은 실제로 데이터베이스의 유일한 지점이 느린 스토리지를 추상화하는 것이라고 말하고 있습니까? 와. 그리고 이것은 Robert Harvey의 대답을 뒷받침합니다 : 그의 의견은 거대한 소금 알갱이로 취해야합니다. 예를 들어,이 관점은 DB의 가치가 일관되고 지속적인 데이터 모델을 유지하고 있다고 생각하지 않습니다. “SSD (persistent RAM)?”의 데이터 구조에 대한 그의 아이디어는 느리고 데이터 손실 가능성을 열어줍니다. NoSQL DB조차도 저널링과 불변 데이터 구조를 사용하여 영구 레코드를 안전하게 업데이트합니다.
amon

3
@amon 네, Robert Harvey는보다 차별화 된 관점을 제시하고 있습니다. 그러나 OP가 Robert C. Martin이 무엇을 말하려고하는지 구체적으로 물었 기 때문에 그의 "최신"대화의 일부를 필사했습니다.
Søren D. Ptæus

3
@ amon-위의 Doc Brown의 답변의 첫 번째 문장을 참조하십시오. 마틴 은 자신의 요점을 과장하기 위해 자신의 주장을 과장하는 말을 자주 합니다. 그는 모든 데이터베이스 작업이 인 메모리 저장소로 대체 ​​될 수 있음을 의미하지는 않으며 , 단순히 어떤 형태로든 SQL에 영향을주는 응용 프로그램의 구성 요소를 갖는 것이 모든 것에서 피해야 할 엄청난 보안 위험이라는 것을 의미합니다. 그러나 그의 말에 비추어 볼 때 그는 그렇게 말하는 것으로 해석 될 수있다. 그러나 그가 실제로하려고하는 것은 모두가 멈추고 생각하게하는 것입니다 : SQL / RDBMS가 내 응용 프로그램에 적합합니까?
Jules

12
@Jules 나는 그가 종종 과장한다는 것을 이해합니다. 그러나 그의 도달 범위와 명성에 비추어 볼 때“Uncle Bob”은 과장 될 때와 실제로 자신이 의미하는 바를 말할 때 명확하지 않다는 것은 매우 도움이되지 않습니다. 만약 그가 무언가를 가르치고 자한다면 , 특히 그가 자신의 아이디어를 반영하거나 비판하지 않기 때문에 말이 될 때까지 그가 말하는 모든 것을 이중으로 해석하고 재 해석하는 것은 불가능합니다. 어떤 시점에서, 심지어는 "그 말을 듣지 않는다", 또는 말을 쉽게 : 삼촌 밥 유해 고려 .
amon

11

SQL은 세부 사항입니다. 세부 사항에 대한 지식이 퍼져서는 안됩니다.

코드에서 점점 더 많은 장소에서 SQL이 사용됨에 따라 코드가 점점 더 많이 의존하게됩니다.

점점 더 많은 SQL 트릭을 배우면 SQL을 사용하여 점점 더 많은 문제를 해결합니다. 이것은 다른 API로 전환하기 위해 번역하는 것 이상의 것을 의미합니다. 당신은 당신이 알고하지 않은 문제를 해결해야합니다.

당신은 데이터베이스 사이의 전환조차도 실행합니다. 하나는 멋진 whizzbang 기능 5를 제공하므로 멋진 whizzbang 기능 5가 독점적이며 많은 비용이 드는 라이센스 문제가 있음을 알기 위해 여러 곳에서 사용합니다. 따라서 기능 5를 사용한 모든 곳에서 많은 작업을 수행하고 나중에 문제를 해결하여 나중에 위즈 방 기능 3을 사용하고 있음을 알 수 있습니다.

Java를 이식성이 좋게 만드는 것 중 하나는 CPU의 특정 기능을 사용할 수 없다는 것입니다. 그들이 가능하다면 나는 그들을 사용할 것입니다. 그리고 갑자기 Java 기능이 없기 때문에 Java 코드가 작동하지 않는 CPU가 있습니다. 데이터베이스 기능과 동일합니다.

독립을 실현하지 않고 쉽게 희생 할 수 있습니다. SQL은 주어진 선택이 아닙니다. SQL을 사용하기로 결정한 경우 한 곳에서 작성하십시오. 만들 수없는 방식으로 만드십시오.

SQL에 보안 문제가 있고 영구 메모리 모델로 전환한다고해서 SQL이 중단되었다는 것은 아닙니다. 그것은 선택의 포인트를 집으로 몰아 넣습니다. 선택을 할 권리를 유지하려면 작업을 수행해야합니다.


80 년대와 밥 삼촌의 데이터베이스 움직임이 다소 불쾌한 역사를 가지고 있다는 것은 주목할 가치가 있습니다. 그는 경영진이 데이터베이스 관리자의 삶을 강요했을 때 플랫 파일 시스템으로 모든 문제를 해결했습니다. 이 행사는 그를 훌륭한 컨설팅 경력으로 이끌었습니다. (그는이 이야기를 초기의 깨끗한 책 중 하나에서 말하고 어느 것을 잊어 버렸는지를 잊어 버립니다)

또한 고객이 요청한 마지막 순간까지 응용 프로그램에 DB를 추가하지 않고 하루에 선택적 기능으로 추가 한 것에 대한 이야기를 들려줍니다. 내 생각에 그는 우리 대부분이 DB를 중독으로 사용하는 방식이라고 생각합니다. 그는 우리에게 습관을 걷어차는 방법을 보여 주려고 노력하고 있습니다.


1
물론 아인슈타인.

1
아, 아인슈타인이 밥을 알지 못했다. 또는 밥은 신이었다. 그것은 재미있는 스탠드 업 비트를 만드는 것처럼 들리지만.
candied_orange

9
@nocomprende 당신은 동기 부여 포스터의 꾸준한 다이어트에 살고 있습니까?
candied_orange

2
그러나 밥 신이다. 적어도 일부는.
피터 Mortensen

3
나는 하나님이 대중 연설에 능숙하다고 믿기를 거부합니다.
candied_orange

5

첫 번째 인용문의 인용문은 (강조 광산)입니다.

해결책. 유일한 해결책. 하는 것입니다 시스템에서 SQL을 제거 완전히. SQL 엔진이 없으면 SQLi 공격이 없을 수 있습니다.

SQL을 대체하는 것은 무엇입니까? 물론 API! 텍스트 언어를 사용하는 API는 아닙니다. 대신, 적절한 데이터 구조 및 함수 호출을 사용하여 필요한 데이터에 액세스하는 API입니다.

이 문제는 애플리케이션 프로그래머가 SQL을 사용하지 못하게하는 것입니다.

제안 된 해결책은 대신 API를 사용하도록하는 것입니다. SQL이 아니며 주입을 허용하지 않습니다.

이러한 API의 예는 다음과 같습니다.

  • http://bobby-tables.com/csharp 는 C # 프로그래머가 ADO.NET API를 사용할 수 있다고 제안합니다.

    ADO.NET이 넓거나 깊은 (즉, 강력한 또는 범용) API이기 때문에 그 완벽한 예 아니라 또한 입력 원시 (또는 원시 틱) SQL에 그 사용자 수는.

  • 일부 SQL 개발자 또는 데이터베이스 관리자는 데이터베이스가 (전문적으로 작성된 제한된 수의) 저장 프로 시저 를 통해서만 액세스를 허용 하고 응용 프로그램 개발자가 자신의 (위험한) SQL 쿼리를 작성할 수 없도록 구성해야한다고 제안합니다.

  • "시스템에서 SQL을 제거하는"또 다른 방법은 데이터베이스 (SQL을 노출하는)를 다른 시스템에 배치하거나 REST API 또는 이와 유사한 방식으로 액세스하는 것입니다.

따라서 전체 솔루션 또는 시스템 인 IMO는 여전히 데이터베이스를 사용할 수 있습니다 (특히 데이터베이스 엔진이 유용한 ACID 속성을 구현하고 확장 성 등을 고려할 때, 하나도없이 수행하거나 작성하려고하면 어리석은 것일 수 있습니다. 응용 프로그램 별).

데이터베이스의 SQL API가 애플리케이션 개발자로부터 다른 API (예 : ADO, ORM, 웹 서비스 등) 뒤에 숨겨져 있으면 rant의 요구 사항이 충족됩니다.

더 일반적으로 나는 그것이 응용 프로그램 특정 DAL ( "데이터 액세스 계층"또는 "데이터베이스 추상화 계층")을 의미한다고 가정합니다. DAL은 데이터를 저장 및 / 또는 가져 오는 방법과 위치에 대한 세부 정보에서 응용 프로그램을 격리시킵니다. DAL은 SQL 데이터베이스를 사용하여 구현되거나 구현되지 않을 수 있습니다.


저는이 30 년 전에 정확히 한 제품을 작업했습니다. 그리고 기본 데이터베이스는 아직 SQL을 지원하지 않았습니다. 그리고 관련 테이블 세트는 데이터베이스에 저장되었습니다 (기다리십시오 ...). 그걸 생각 해낸 사람은 정말 똑똑했습니다. 더 이상 프로그래머가 아닙니다.

나는이 대답이 마음에 들지만 그가 이것을 말하지 않았을 것이라고 생각합니다. 그는 또한 "프레임 워크는이 문제를 처리하지 않습니다 ..."라고 말합니다. 귀하의 답변에서 Linq-to-Sql을 사용하는 것은 괜찮지 만 문제를 처리하는 프레임 워크가 아닌 것 같습니다.
christo8989

잘 모르겠어요. 그는이 문제를 처리하지 않는 프레임 워크의 예로 Hibernate를 언급했다. 실제로 OWASP는 "Hibernate는 SQL 인젝션에 면역성을 부여하지 않으며, 원하는대로 API를 오용 할 수있다. HQL (Hibernates 부분 집합 SQL)에 대해서는 더 이상 또는 덜 민감하게 만드는 특별한 것은 없다"고 말했다. 내가 언급 한 일부 API는 SQL을 전혀 노출시키지 않는 더 나은 절연체 일 것입니다. 아마도 최대 절전 모드는 DAL을 구현하는 데 사용할 수있는 것일 수도 있습니다 (단, 완전 격리 된 DAL은 아닙니다).
ChrisW

1
@ christo8989 augustl.com/blog/2016/… Datomic은 (아마도) SQL 데이터베이스에 대한 또 다른 래퍼 / 레이어라고 제안합니다. "Datomic은 파일 시스템에 직접 쓰지 않습니다. Datomic의 스토리지 백엔드로서 다른 데이터베이스 : 모든 SQL JDBC 데이터베이스 등 "
ChrisW

주목해야한다 ADO.NET에 SQL 인젝션을 방지하기위한 해결책은 모두 복잡하지 않은 것 -은 SQL에서 사용 지정자를 사용하여 명령의 파라미터와, 상기 파라미터의 설정 값.
Zev Spitz

3

모두 보안 관점에서 또는 SQL 렌즈를 사용하여이 질문에 대답하는 것 같습니다.

Robert Martin 강의에서 프로그래머로서 특정 프로그램에 가장 적합한 여러 가지 데이터 구조를 사용한다고 설명했습니다. 따라서 모든 데이터를 전체적으로 테이블 형식으로 저장하는 대신 데이터를 해시 테이블, 트리 등에 저장하여 데이터를 가져와 프로그램으로 바로 이동할 수 있도록해야합니다.

나는 그의 메시지를 단지 영구적 인 스토리지에 대한 현재의 가정을 버려서 오래된 SQL 테이블 형식이 아닌 다른 미래의 가능성을 고려할 것이라고 말하는 것으로 해석했습니다. SSD는 후보 솔루션이지만 유일한 솔루션은 아닙니다.


데이터의 다중 사용자 동시 읽기 / 쓰기에 대해 어떻게 생각할 수 있습니까?
ChrisW

1
@ChrisW 나는 이것이 구현의 문제라고 생각하지 않으며, 지속적인 데이터 스토리지를 더 잘 수행하는 방법을 찾는 높은 수준의 아이디어라고 생각합니다.
Keenan

@ChrisW 그는 트랜잭션 데이터베이스에 대해서도 이야기합니다. 소스 제어 기술을 지속성 도구로 활용 즉, 트랜잭션 및 업데이트보다 훨씬 더 친숙한 것을 작성하고 읽습니다.
christo8989

@Keenan 그래서 그는 실제로 구현을 통해 솔루션을 제공하지 않습니다. 그는 단지 무슨 말을하는지 생각하고 있습니까?
christo8989

1
@ christo8989 그가 컴퓨터 과학의 지속적인 저장 문제에 대한 후보 솔루션을 개인적으로 주도했는지 여부는 모르겠습니다. 그것은 OP의 질문의 범위를 벗어납니다. Bob 아저씨는 플러그인 아키텍처에 관한 모든 것입니다. 응용 프로그램 개발의 현재 산업 표준은 데이터베이스와 밀접하게 연결되어 있고 그 주위에 응용 프로그램을 구축하는 것입니다. 앱은 db가 앱에 의존해야 할 때 db에 의존합니다. 오히려, Uncle Bob은 '데이터베이스는 상세하다'고 제안하고 분리하고 교체 할 수 있어야합니다.
Keenan

2

실제로 그는 데이터베이스와 SQL을 상당히 명시 적으로 사용하지 않아야합니다. 첫 번째 참조는 잘 알려진 문제이며 두 번째 참조는 rant처럼 들립니다. 그러나 데이터베이스를 사용하고 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입니다. 그가 제공하는 레일 코드는 안전과 안전하지 않은 것을 혼동하기 쉽습니다. 많은 ORM과 마찬가지로 SQL이 무엇인지 숨기므로 SQL을 구성하고 실행하는 인터페이스를 다루는 경우가 많습니다. API가 당신을 위해하고있는 것과 거의 같지 않습니까?

첫 번째 참조에 대한 나의 해석은 그가 잘 알려진 해결책을 가진 잘 알려진 문제를 대체해야한다고 제안하고 있다는 것입니다.

또한이 작업이 올바르게 수행되면 코드를보다 쉽게 ​​작성하고 더 읽기 쉽게 만들 수 있지만, 잘 작성하면 실제로 작성하기가 더 어렵고 읽기 어려울 수 있다는 점을 언급하지 않은 것은 불행한 일입니다. 또한 SQL은 읽기가 매우 쉽고 일반적으로 기대하는 작업을 수행한다고 언급하지 않았습니다.

그는 부분적으로 정확합니다. 궁극적으로 우리는 무한대로 크고 빠른 메모리와 무한히 빠른 프로세서를 갖게됩니다. 우리가 컴퓨팅을 제약하는 물리학에서 벗어날 때까지 그는 정확하지 않습니다.

예 회전 디스크는 과거의 일이며 이제 SSD를 사용합니다. 디스크는 데이터 전송 당 ~ 10 밀리 초로 작동하고 SSD는 ~ 0.5 밀리 초 (500 마이크로 초) 데이터 액세스 시간으로 작동합니다. RAM은 100 나노초 정도이며 프로세서는 100 초의 피코 초 동안 작동합니다. 이것이 데이터베이스가 필요한 이유의 핵심입니다. 데이터베이스는 메인 메모리가있는 회전 디스크 또는 SSD 간의 데이터 전송을 관리합니다. SSD의 등장으로 데이터베이스가 필요하지 않았습니다.


4
"STOP USING SQL" (첫 번째 링크에서 인용)은 SQL을 사용하지 말라고 말하는 것처럼 들립니다.
Doc Brown

6
단어 순서 문제입니다. 실제로 이것은 원래 텔레 그램이었습니다. USING SQL STOP

6
@nocomprende 그래서 당신은 그가 경쟁 조건의 피해자라고 말하는거야? 음, 죄송합니다. 그는 SQL 트랜잭션을 사용하여이를 피할 수있었습니다.
Konrad Rudolph

어쩌면 Visual Basic과 Fortran의 매우 짧은 혼합 일 수 있습니다. 어디에서 끝날까요?

1
@ KononRudolph : 글쎄, 우리는 어셈블리에서 직접 TSX를 사용하지 않을 것이라는 데 동의 할 것입니다. 더 높은 수준의 추상화가있을 것입니다. 이러한 추상 트랜잭션은 SQL 트랜잭션입니까? 나는 그렇게 생각하지 않는다. 해석 된 언어로서 SQL은 성능 오버 헤드를 수반합니다. 회전하는 하드 디스크의 데이터에 액세스 할 때는 실제로 중요하지 않았습니다. 그러나 RAM의 데이터에 액세스 할 때는 비용이 저렴합니다.
MSalters

2

대답

그는 사람들이 SQLi 공격으로 인해 SQL / 관계형 데이터베이스 사용을 중단하기를 원합니까?

'Bobby Tables'기사는 이것이 SQL 자체를 사용하지 않는 이유라고 제안하는 것 같습니다.

해결책. 유일한 해결책. 시스템에서 SQL을 완전히 제거하는 것입니다. SQL 엔진이 없으면 SQLi 공격이 없을 수 있습니다.

다른 곳에서 논의해야 할 다른 이유가있을 수 있습니다. 나는 그의 내용을 많이 읽지 않기 때문에 몰랐습니다.

침략

이 부분은 실제로 답은 아니지만 SQL의 가치에 대한 질문은 다른 것들과 마찬가지로 훨씬 더 흥미 롭습니다.

SQL 사용 경험이 많았고 장단점에 대해 공정하게 이해하고 있다고 생각합니다. 제 개인적 느낌은 남용되고 남용되었다는 것입니다. 그러나 우리가 절대 사용해서는 안된다는 생각은 어리석은 것입니다. 'SQL always'또는 'SQL never'를 선택해야한다는 생각은 잘못된 이분법입니다.

SQL 주입이 SQL을 사용하지 않는 것에 대한 논쟁 인 한, 그것은 웃기다. 이것은 매우 간단한 해결책으로 잘 알려진 문제입니다. 이 인수의 문제점은 SQLi가 존재하는 유일한 취약점이 아니라는 것입니다. JSON API를 사용하면 안전하다고 생각하면 큰 놀라움을 느끼게됩니다.

모든 개발자는 "금요일 13 일 금요일 : JSON 공격-Alvaro Muñoz & Oleksandr Mirosh-AppSecUSA 2017"이라는 제목의 비디오를 시청 해야한다고 생각합니다 .

시간이나 성향이없는 경우 여기에 요점이 있습니다. 많은 JSON deserialization 라이브러리에는 원격 코드 실행 취약성이 있습니다. XML을 사용하는 경우 더 걱정해야합니다. 아키텍처에서 SQL을 금지해도 시스템이 안전하지는 않습니다.


아무도 SQL 금지 자체만으로 시스템을 안전하게 만들 것이라고 주장한 사람은 없습니다. 그것은 당신의 시스템이 만들어내는 삼촌 밥 청구 안전하고 SQL 주입 지금 이상 10 년 웹 애플리케이션 보안에서 가장 큰 위험이 남아 주어진, 난 당신이 가볍게는 데이터베이스 회담 방식을 개선하는 업계의 필요성을 기각하지한다고 생각합니다 .
meriton-파업에

@meriton 죄송하지만 "솔루션, 유일한 솔루션"은 꽤 분명해 보입니다. SQLi 문제에 대한 솔루션은 알려져 있으며 매우 간단합니다. 귀찮게 사용할 수없는 사람들은 Prepare 문을 사용하여 SQL 사용을 중단하는지 여부에 관계없이 안전하지 않은 시스템을 만듭니다. 이들은 기본 모범 사례를 따르거나 새로운 직업을 구해야하는 비전문가입니다.
JimmyJames

2

나는 짧은 진술만을 다루고 싶다 :

아니면 사람들이 SQLi 공격으로 인해 SQL / 관계형 데이터베이스 사용을 중단하기를 원합니까?

아닙니다. 잘못된 가정입니다. 우리는 자동차 사고로 사망하는 사람들을 책임지기 때문에 자동차 사용을 중단해야한다고 말할 수 없습니다. 마찬가지로 SQL / 관계형 데이터베이스 (또는 RDBMS와 같은이 컨텍스트의 다른 데이터베이스)는 공격자가 웹 응용 프로그램에서 수행 할 수있는 악성 SQL 페이로드에 대해 책임을지지 않습니다. 필자는 이 목적을 위해 전체 SQL 주입 방지 치트 시트 가 있기 때문에 저자가 의미하지 않았다고 확신합니다 .


2
자동화 된 자동차는 자동차 사고의 약 98 %를 예방합니다. 우리는 기계를 신뢰할 필요가 있습니다.

3
"우리는 자동차 사고로 사망하는 사람들에 대한 책임이 있기 때문에 [특별하고 신중하게 통제 된 상황을 제외하고] 자동차 사용을 중단해야한다고 말할 수 없습니다."— Uhm. 우리는 절대적으로 그렇게 말할 수 있습니다 . 그리고 많은 합리적인 사람들이합니다.
Konrad Rudolph

1
기본적으로 Java로 개발 된 응용 프로그램이 해킹되어 Java 사용을 중단해야합니다 . Downvoting은 충분하고 나머지는 상식을 가르치지 않습니다. @ KonradRudolph
Billal Begueradj

2
@BillalBEGUERADJ 그것은 다소 잘못된 등가이지만 (해킹으로부터 안전한 것은 없기 때문에) 전혀 멀지 않습니다. 예를 들어, 시스템 프로그래밍 컨텍스트 외부에서 C를 사용하는 경우 잘못하고 있습니다. 어쨌든, 나는 당신의 대답을 downvote하지 않았다 그러나 그것은 이다 잘못된 : 당신이 주장 무엇 때문에 반대, (다른 답변이 보여로) 밥 마틴 말을 정확히입니다.
Konrad Rudolph

2

Martin의 문제는 프로그래머 가 사용자 입력에서 직접 동적 SQL을 작성하는 것으로 보입니다 (용서, 나는 주로 C 및 C ++ 프로그래머입니다).

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

이는 절대적 가슴위한 레시피 (따라서 바비 테이블 스트립). 프로덕션 시스템에서 이와 같은 코드를 작성하는 모든 프로그래머는 패 들린이 필요합니다.

준비된 문장을 사용하고 입력 내용을 적절하게 소독함으로써 문제를 완화시킬 수 있습니다. 프로그래머가 쿼리 문자열을 직접 작성하지 않도록 API 뒤에 SQL을 숨길 수 있다면 훨씬 더 좋습니다 (마틴이 주장하는 것의 일부입니다).

그러나 SQL을 완전히 없애는 것이 실용적이거나 바람직하지 않다고 생각합니다. 관계형 모델이 유용하기 때문에 처음부터 존재하는 것이므로 SQL은 아마도 관계형 모델 작업에 가장 적합한 인터페이스 일 것입니다.

항상 그렇듯이 작업에 적합한 도구를 사용해야합니다. 장바구니 앱에 전체 관계형 모델이 필요하지 않은 경우 관계형 모델을 사용하지 마십시오 (SQL을 사용할 필요가 없음). 관계형 모델이 필요할 때는 SQL을 사용하는 것이 거의 확실합니다.


하지만 sprintfSQL에 필요한 위생의 종류를 포함하지 않는, 특히이 목적을 위해 설계된 기능 수행 과는 완벽하게 안전합니다. 예 : 엔티티 프레임 워크에는 SQLQuery .
Robert Harvey

@RobertHarvey : 나는 그것이 사실이라고 가정합니다. 필자는 C와 C ++에서 주로 서버 측 작업을 수행하기 때문에 여전히 sprintf동적 SQL을 사용하는 사람들의 사례를 볼 수있다.
John Bode

1

연결하는 두 가지 소스는 다른 메시지를 전달합니다.

블로그 게시물에 따르면 데이터 액세스 논리는 신뢰할 수없는 사용자 입력과 혼합되지 않도록 런타임에 텍스트로 존재해서는 안됩니다. 즉, 블로그 게시물은 문자열을 연결하여 쿼리 작성을 비난합니다.

강의가 다릅니다. 첫 번째 차이점은 어조입니다. 강의는 추측하고 의문을 제기하지만 정죄하지는 않습니다. 그는 데이터베이스가 악의적이라고 말하지는 않지만 데이터베이스없이 지속성을 상상하도록 요구합니다. 그는 관계형 데이터베이스가 널리 보급 된 이후 30 년 동안 많은 것들이 변했으며 우리의 지속성 기술 선택에 영향을 줄 수있는 두 가지를 강조합니다.

  • 저장 공간이 비슷한 가격으로 약 백만 배 증가했습니다! 결과적으로 스토리지를 보존 할 필요가 없으며 특히 더 이상 삭제할 필요가 없습니다. 추가 전용 스토리지를 사용하면 읽기 잠금이 필요하지 않으므로 동시성 제어를 단순화 할 수 있습니다. 이것은 거래의 필요성을 제거 할 수 있습니다.
  • 이제 대부분의 데이터 세트가 RAM에 적합하여 읽기 대기 시간이 크게 줄어들 기 때문에 액세스 시간이 단축되었습니다.

이러한 변화된 환경이 최적 지속성 기술을 변화 시킵니까? 흥미롭게도 Bob 아저씨는 모든 프로그램에 대해 올바른 답이 없다고 생각하기 때문에 그렇게하지 않습니다. 그렇기 때문에 우리는 지속성 기술 선택을 돌판에 담기보다는 세부 사항으로 취급하고 동료들에게 지혜를 전달받은 것으로 전달하도록 경고합니다.

대안이 있습니까?

문자열없이 데이터 액세스 로직을 작성하는 것은 전적으로 가능합니다. Java land에서는 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 주입을 불가능하게하고 프로그래머 생산성을 향상 시키며 리팩토링 안전성을 향상시킵니다. 실행중인 개그 를 생성하기에 오랫동안 존재했던 웹 애플리케이션 보안에 대한 최대 위험 방지개발자 생산성을 향상 시켰습니까? 여전히 쿼리를 문자열로 작성하면 잘못하고 있다고 감히 말합니다.

관계형 데이터베이스에 대한 대안에 관해서는 postgres의 다중 버전 동시성 제어 가 Bob이 아는 다른 종류의 추가 전용 데이터 구조 라는 사실을 알고 싶습니다. 아마도 그는 이벤트 저장소이벤트 소싱에 대해 더 많이 생각하고 있었지만 패턴 또한 RAM으로 현재 상태를 유지하는 개념으로 잘 맞다 일반적.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.