programing

데이터 유효성을 확인하는 것은 누구의 책임입니까?

copysource 2021. 1. 17. 11:50
반응형

데이터 유효성을 확인하는 것은 누구의 책임입니까?


데이터 적법성을 확인 하는 것이 발신자 인지 수신자의 책임 인지 혼란 스럽습니다 .

해야 호출자 체크 전달 된 여부를 인수하지 않아야 null있도록 및 다른 요구 사항을 충족 수신자의 방법은 일반적으로 성공적으로 실행할 수 있으며, 잠재적 인 예외를 잡으려고? 아니면 이렇게하는 것이 호출자의 책임입니까?


소비자 측 (클라이언트) 공급자 측 (API) 유효성 검사 모두.

더 나은 경험을 의미하기 때문에 클라이언트가해야합니다. 예를 들어, 잘못된 텍스트 필드가 있다는 사실을 알리기 위해 네트워크를 왕복하는 이유는 무엇입니까?

공급자는 클라이언트 (예 : XSS 및 중간자 공격)를 절대 신뢰 해서는 안되므로 이를 수행해야합니다 . 요청이 차단되지 않았는지 어떻게 알 수 있습니까? 모든 것을 검증하십시오.

유효한 수준에는 여러 가지가 있습니다 .

  1. 모든 필수 필드가 있으며 올바른 형식입니다. 이것이 클라이언트가 확인하는 것입니다.
  2. # 1 + 필드 간의 유효한 관계 (예 : X가 있으면 Y가 필요함).
  3. # 1 + # 2 + 비즈니스 유효 : 적절한 처리를위한 모든 비즈니스 규칙을 충족 합니다 .

공급자 측만 # 2 및 # 3을 수행 할 수 있습니다.


API의 경우 호출 수신자는 항상 적절한 유효성 검사를 수행하고 유효하지 않은 데이터에 대한 설명 예외를 발생시켜야합니다.

IO 오버 헤드가있는 클라이언트의 경우 클라이언트도 기본 유효성 검사를 수행해야합니다.


유효성 검사 : 발신자 대 호출 됨

TLDR 버전은 둘 다입니다.

긴 버전은 누가, 왜, 언제, 어떻게, 무엇을 포함합니다.

양자 모두

둘 다 "이 데이터를 안정적으로 운영 할 수 있습니까?"라는 질문에 답할 준비가되어 있어야합니다. 이 데이터에 대해 의미있는 작업을 수행 할만큼 충분히 알고 있습니까? 많은 사람들이 데이터의 신뢰성을 절대로 신뢰해서는 안된다고 제안하지만 이는 닭고기와 달걀 문제로 이어질뿐입니다. 양 끝에서 끝없이 쫓는 것은 의미있는 가치를 제공하지는 않지만 어느 정도는 필수적입니다.

둘 다 기본 사용성을 보장하기 위해 데이터의 형태를 검증해야합니다. 어느 쪽이 데이터의 형태를 인식하지 못하거나 이해하지 못한다면 더 이상 신뢰성있게 처리하는 방법을 알 방법이 없습니다. 환경에 따라 데이터가 특정 '유형'이어야 할 수 있으며, 이는 종종 모양을 검증하는 쉬운 방법입니다. 우리는 종종 특정 조상에게 공통 혈통의 증거를 제시하고 올바른 모양을 소유하기 위해 중요한 특성을 유지하는 유형을 고려합니다. 데이터가 메모리 구조가 아닌 경우 (예 : 실행중인 컨텍스트 외부의 스트림 또는 다른 리소스 인 경우) 다른 특성이 중요 할 수 있습니다.

많은 언어에는 유형 또는 인터페이스 검사를 통한 기본 제공 언어 기능으로 데이터 모양 검사가 포함됩니다. 그러나 상속보다 구성을 선호 할 때 특성 존재를 확인하는 좋은 메커니즘을 제공하는 것은 구현 자에게 있습니다. 이를 달성하기위한 한 가지 전략은 동적 프로그래밍, 특히 유형 검사, 추론 또는 반영을 통한 것입니다.

부름

피 호출자는 그것이 작동 할 주어진 컨텍스트의 도메인 (입력 세트)의 유효성을 검사해야합니다. 호출 된의 디자인은 항상 너무 많은 입력 사례 만 처리 할 수 ​​있음을 시사합니다. 일반적으로 이러한 값은 특정 하위 클래스 또는 입력 범주로 나뉩니다. 호출 된 도메인이 지역화 된 제약 조건과 밀접하기 때문에 호출 된 도메인을 확인합니다. 좋은 입력과 그렇지 않은 것을 누구보다 잘 압니다.

  • 일반 값 : 도메인의 이러한 값은 범위에 매핑됩니다. 모든 foo사람에게는 오직 하나만 bar있습니다.

  • 범위를 벗어남 / 범위를 벗어난 값 :이 값은 일반 도메인의 일부이지만 호출 된 컨텍스트의 범위에 매핑되지 않습니다. 이러한 값에 대해 정의 된 동작이 없으므로 유효한 출력이 불가능합니다. 자주 범위를 벗어난 검사에는 범위, 제한 또는 허용 된 문자 (또는 숫자 또는 복합 값)가 수반됩니다. 카디널리티 검사 (다중성)와 이후의 존재 검사 (null 또는 비어 있음)는 특수한 형태의 범위 검사입니다.

  • 비논리적이거나 정의되지 않은 동작으로 이어지는 값 : 이러한 값은 특수한 값이거나 그렇지 않으면 정상적인 경우이지만 알고리즘 설계 및 알려진 환경 제약으로 인해 예기치 않은 결과가 발생할 수 있습니다. 예를 들어, 숫자에 대해 작동하는 함수는 0으로 나누기 또는 오버플로가 발생하는 누산기 또는 의도하지 않은 정밀도 손실을 방지해야합니다. 때때로 운영 환경이나 컴파일러는 이러한 상황이 발생할 수 있다고 경고 할 수 있지만 런타임이나 컴파일러에 의존하는 것은 항상 가능한 것과 그렇지 않은 것을 추론 할 수있는 것은 아니기 때문에 좋은 습관이 아닙니다. 이 단계는 주로 2 차 검증을 통해 호출자가 유용하고 의미있는 입력을 제공했는지 확인해야합니다.

방문객

발신자는 특별합니다. 호출자는 데이터의 유효성을 검사해야하는 두 가지 상황이 있습니다.

첫 번째 상황은 할당 또는 명시 적 상태 변경으로, 일부 명시 적 메커니즘에 의해 데이터의 하나 이상의 요소가 내부적으로 또는 외부 적으로 컨테이너에있는 항목에 의해 변경됩니다. 이것은 질문의 범위를 벗어 났지만 명심해야 할 사항입니다. 중요한 것은 상태 변경이 발생하고 상태를 설명하는 하나 이상의 요소가 영향을받을 때 컨텍스트를 고려하는 것입니다.

  • 자기 / 참조 무결성 : 다른 행위자가 데이터를 참조 할 수있는 경우 내부 메커니즘을 사용하여 상태를 검증하는 것이 좋습니다. 데이터에 일관성 검사가없는 경우 불확실한 상태라고 가정하는 것이 안전합니다. 그것은 중간이 아니지만 불확실합니다. 너 자신을 알아라. 상태 변경에 대한 내부 일관성을 검증하는 메커니즘을 사용하지 않으면 데이터를 신뢰할 수 없으며 두 번째 상황에서 문제가 발생합니다. 호출자의 데이터가 알려진 양호한 상태인지 확인하십시오. 또는 알려진 전환 / 복구 상태에서. 준비가 될 때까지 전화를 걸지 마십시오.

두 번째 상황은 데이터가 함수를 호출하는 경우입니다. 발신자는 수신자에게 너무 많은 것을 기대할 수 있습니다. 발신자는 피 호출자가 특정 도메인 만 인식한다는 것을 알고 존중해야합니다. 호출자는 호출이 완료된 후에도 오랫동안 지속될 수 있으므로 이기심을 가져야합니다. 이는 호출자가 호출자가 성공할뿐만 아니라 작업에 적합하도록 도와야 함을 의미합니다. 잘못된 데이터 입력은 잘못된 데이터 출력을 생성합니다. 동일한 토큰에서 호출자에 대한 좋은 데이터도 호출자 측면에서 다음 항목에 적합하지 않을 수 있습니다. 좋은 데이터 출력은 실제로 호출자에게 잘못된 데이터 일 수 있습니다. 호출자의 출력은 호출자의 현재 상태에 대해 호출자를 무효화 할 수 있습니다.

좋아요, 충분한 설명입니다. 발신자는 구체적으로 무엇을 검증해야합니까?

  • 논리적이고 정상적 : 데이터가 주어지면 목적과 의도에 맞는 좋은 전략이라고 부릅니까? 특정 값으로 실패 할 것이라는 것을 알고 있다면 적절한 가드없이 대부분의 경우 호출을 수행 할 필요가 없습니다. 피 호출자가 0을 처리 할 수 ​​없다는 것을 알고 있다면 성공하지 못할 것이기 때문에 요청하지 마십시오. 더 비싸고 관리하기 어려운 것은 무엇입니까? [중복 (알고 있습니까?)] 가드 절 또는 예외 [오래 실행되고 외부에서 사용 가능한 리소스 종속 프로세스에서 늦게 발생]? 구현은 변경 될 수 있으며 갑자기 변경 될 수 있습니다. 호출자에게 보호를 제공하면 해당 구현을 변경하는 데 따른 영향과 위험이 줄어 듭니다.

  • 반환 값 : 실패한 완료를 확인합니다. 이것은 발신자가 할 필요가 있거나 할 필요가없는 일입니다. 반환 된 데이터를 사용하거나 의존하기 전에 시스템 설계에 실제 반환 값에 수반 될 수있는 성공 및 실패 값이 포함되어 있는지 대체 결과를 확인하십시오.

각주 : 명확하지 않은 경우. Null은 도메인 문제입니다. 논리적이고 정상적 일 수도 있고 아닐 수도 있으므로 상황에 따라 다릅니다. null이 함수에 대한 자연스러운 입력이고 함수가 의미있는 출력을 생성 할 것으로 합리적으로 예상 될 수있는 경우 호출자에게 그대로 두어 사용합니다. 호출자의 도메인이 null이 논리적이지 않은 경우 두 곳 모두에서 경계하십시오.

중요한 질문 : 만약 당신이 호출 된 사람에게 null을 전달하고, 호출 된 사람이 무언가를 생산하고 있다면, 그것은 숨겨진 창조 패턴이 아닌 무로부터 무언가를 창조하는 것입니까?


그것은 모두 "계약"에 관한 것입니다. 그것은 어떤 매개 변수가 좋은지 아닌지를 결정하는 피 호출자입니다. "null"매개 변수가 유효하지 않다는 문서를 넣은 다음 던지 NullPointerException거나 InvalidArgumentException괜찮습니다.

null 매개 변수에 대한 결과를 반환하는 것이 합리적이면 문서에 명시하십시오. 일반적으로 이러한 상황은 잘못된 설계입니다. null을 받아들이는 대신 더 적은 매개 변수로 재정의 된 메서드를 만듭니다.

설명적인 예외를 던지는 것만 기억하십시오. 경험상 :

  1. 호출자가 문서에 설명 된 것과 다른 잘못된 인수를 전달한 경우 (예 : null, id <0 등)-확인되지 않은 예외 발생 ( NullPointerException또는 InvalidArgumentException)
  2. 호출자가 올바른 인수를 전달했지만 호출을 처리 할 수없는 예상되는 비즈니스 케이스가있는 경우 확인 된 설명 예외를 발생시킬 수 있습니다. 예를 들어- getPermissionsForUser(Integer userId)호출자는 userId그러한 사용자가 존재하는지 알지 못하지만 null이 아닌 정수입니다. 귀하의 메서드는 권한 목록을 반환하거나 UserNotFoundException. 확인 된 예외 일 수 있습니다.
  3. 문서에 따르면 매개 변수가 정확하지만 내부 오류를 처리하는 경우 확인되지 않은 예외가 발생할 수 있습니다. 이것은 일반적으로 방법이 잘 테스트되지 않았 음을 의미합니다 ;-)

글쎄 ...

수신자 내부에서 유효하지 않은 데이터를 처리하는 방법을 확신 할 수 있다면 거기에서 수행하십시오.

확실하지 않은 경우 (예 : 방법이 매우 일반적이고 몇 가지 다른 장소와 방법에서 사용되기 때문에) 호출자가 결정하도록하십시오.

예를 들어 특정 엔터티를 검색해야하지만 찾을 수없는 DAO 메서드를 상상해보십시오. 예외를 던질 지, 트랜잭션을 롤백할지 아니면 괜찮다고 생각할지 결정할 수 있습니까? 이와 같은 경우 처리 방법을 결정하는 것은 확실히 호출자에게 달려 있습니다.


양자 모두. 이는 환경 (C / S, 웹, 내부 API) 및 언어와 관계없이 양측 모두에서 좋은 소프트웨어 개발의 문제입니다.

The callee should be validating all parameters against the well documented parameter list (you did document it, right?). Depending on the environment and architecture, good error messages or exceptions should be implemented to give clear indication of what is wrong with the parameters.

The caller should be ensuring that only appropriate parameter values are passed in the api call. Any invalid values should be caught as soon as possible and somehow reflected to the user.

As often occurs in life, neither side should just assume that the other guy will do the right thing and ignore the potential problem.


Depends on whether you program nominally, defensively, or totally.

  • If you program defensively (my personal favourite for most Java methods), you validate input in the method. You throw an exception (or fail in another way) when validation fails.
  • If you program nominally, you don't validate input (but expect the client to make sure the input is valid). This method is useful when validation would aversely impact performance, because the validation would take a lot of time (like a time-consuming search).
  • If you program totally (my personal favourite for most Objective-C methods), you validate input in the method, but you change invalid input into valid input (like by snapping values to the nearest valid value).

In most cases you would program defensively (fail-fast) or totally (fail-safe). Nominal programming is risky IMO and should be avoided when expecting input from an external source.

Of course, don't forget to document everything (especially when programming nominally).


I'm going to take a different perspective on the question. Working inside a contained application, both caller and callee are in the same code. Then any validation that is required by the contract of the callee should be done by the callee.

So you've written a function and your contract says, "Does not accept NULL values." you should check that NULL values have not been sent and raise an error. This ensures that your code is correct, and if someone else's code is doing something it shouldn't they'll know about it sooner.

Furthermore, if you assume that other code will call your method correctly, and they don't, it will make tracking the source of potential bugs more difficult.

This is essential for "Fail Early, Fail Often" where the idea is to raise an error condition as soon as a problem is detected.


It is callee responsibility to validate data. This is because only callee knows what is valid. Also this is a good security practice.


It needs to be on both end in client side and server(callee and caller) side too.

Client :

  1. This is most effective one.
  2. Client validation will Reduce one request to server.
  3. To reduce the bandwidth traffic.
  4. Time comsuming (if it has delay responase from server)

Server :

  1. Not to believe on UI data (due to hackers).
  2. Mostly backend code will be reused, so we dont know whether the data will be null,etc,. so we need to validate on both callee and caler methods.

Overall, 1. If data comes from UI, Its always better to validate in UI layer and make an double check in server layer. 2. If data transfer with in server layer itself, we need to validate on callee and for double check, we requre to do on caller side also.

Thanks


In my humble opinion, and in a few more words explaining why, it is the callee's responsibility most of the time, but that doesn't mean the caller is always scot-free.

The reason why is that the callee is in the best position to know what it needs to do its work, because it's the one doing the work. It's thus good encapsulation for the object or method to be self-validating. If the callee can do no work on a null pointer, that's an invalid argument and should be thrown back out as such. If there are arguments out of range, that's easy to guard against as well.

However, "ignorance of the law is no defense". It's not a good pattern for a caller to simply shove everything it's given into its helper function and let the callee sort it out. The caller adds no value when it does this, for one thing, especially if what the caller shoves into the callee is data it was itself given by its own caller, meaning this layer of the call stack is likely redundant. It also makes both the caller's and callee's code very complex, as both sides "defend" against unwanted behavior by the other (the callee trying to salvage something workable and testing everything, and the caller wrapping the call in try-catch statements that attempt to correct the call).

The caller should therefore validate what it can know about the requirements for passed data. This is especially true when there is a time overhead inherent in making the call, such as when invoking a service proxy. If you have to wait a significant portion of a second to find out your parameters are wrong, when it would take a few ticks to do the same client-side, the advantage is obvious. The callee's guard clauses are exactly that; the last line of defense and graceful failure before something ugly gets thrown out of the actual work routine.


There should be something between caller and callee that is called a contract. The callee ensures that it does the right thing if the input data is in specified values. He still should check if the incomming data is right according to those specifications. In Java you could throw an InvalidArgumentException.

The caller should also work within the contract specifications. If he should check the data he hands over depends on the case. Ideally you should program the caller in a way that checking is unescessary because you are sure of the validity your data. If it is e.g. user input you cannot be sure that it is valid. In this case you should check it. If you don't check it you at least have to handle the exceptions and react accordingly.


The callee has the responsibility of checking that the data it receives is valid. Failure to perform this task will almost certainly result in unreliable software and exposes you to potential security issues.

Having said that if you have control of the client (caller) code then you should also perform at least some validation there as well since it will result in a better over all experience.

As a general rule try to catch problems with data as early as possible, it results in far less trouble further down the line.

ReferenceURL : https://stackoverflow.com/questions/17187905/whose-responsibility-is-it-to-check-data-validity

반응형