
Java 함정 - 비트 연산자와 부울 연산자
Java 함정 - 비트 연산자와 부울 연산자
“Java Gotcha” - 의도치 않게 쉽게 구현되는 흔한 오류 패턴.
의외로 빠지기 쉬운 아주 간단한 Java 문제는: 부울 비교 연산자 대신 비트 연산자를 사용하는 것이다.
예를 들어, 실제로 "&&"를 입력하려 할 때 간단한 입력 오류로 인해 "&"가 입력될 수 있습니다.
코드를 검토할 때 우리가 배운 일반적인 휴리스틱 방법은 다음과 같습니다:
조건문에서 "&" 또는 "|"를 사용하는 것은 의도적이지 않을 수 있습니다.
이 블로그 글에서는 휴리스틱 접근법을 살펴보고, 이 코딩 문제를 식별하고 수정하는 방법을 확인해 보겠습니다.
문제는 어디에 있는가? 부울 연산을 사용하면 비트 연산을 정상적으로 수행할 수 있다.
부울 값을 사용하는 비트 연산자는 완전히 유효하므로 Java는 문법 오류를 보고하지 않습니다.
비트별 OR(|) 및 비트별 AND(&) 연산자의 진리값 표를 탐색하기 위해 JUnit 테스트를 구성한다면, 비트 연산자의 출력이 진리값 표와 일치하는 것을 확인할 수 있을 것입니다. 이를 고려할 때, 비트 연산자 사용이 문제가 되지 않는다고 생각할 수 있습니다.
AND 진상표

@Test
void 비트 연산자와 진리표 () {
assertions.assertEquals(true, true, true);
assertions.assertEquals(false, true, false);
assertions.assertEquals(false, false, true);
assertions.assertEquals(false, false, false);
}
테스트를 통과했습니다. 이것은 완전히 유효한 Java입니다.
OR 진상표

@Test
void 비트 연산자 또는 진리값 표 () {
assertions.asserteQuals(true, true | true);
assertions.asserteQuals(true, true | false);
assertions.asserteQuals(true, false | true);
assertions.asserteQuals(false, false | false);
}
이 테스트도 통과했는데, 왜 우리는 "&&"와 "||"를 더 선호할까요?
진상표 도형은 생성된 진실표 도구 에서 web.standfor.edu에서 생성된 것입니다.
문제: 단락 작업
진정한 문제는 비트 연산자(&, |)와 부울 연산자(&&, ||) 사이의 동작 차이입니다.
부울 연산자는 단락 연산자로, 필요한 경우에만 평가됩니다.
예를 들어
if (args!= null & args.length () > 23) {
system.out.println (args);
}
위의 코드에서는 비트 연산자를 사용했기 때문에 두 부울 조건 모두 평가됩니다:
- args!= 0
- args.length() > 23
args가 비어 있을 경우, 이는 내 코드가 NullPointerException 위험에 노출되게 합니다. 왜냐하면 두 개의 부울 조건을 반드시 평가해야 하기 때문에, 매개변수가 비어 있더라도 항상 args.length를 검사하게 되기 때문입니다.
부울 연산자의 단락 평가
&&를 사용할 때, 예를 들어
if (args!= null && args.length () > 23) {
system.out.println (args);
}
arg = null 이 아닐 때만 false로 계산되며, 조건 표현식의 계산이 중단됩니다.
우측을 평가할 필요가 없습니다.
오른쪽 조건의 결과가 어떻든, 부울 표현식의 최종 값은 거짓이 될 것입니다.
그러나 이는 실제 코드에서는 절대 발생하지 않습니다.
이는 매우 흔히 저지르는 실수이며, 정적 분석 도구가 항상 이 실수를 범하는 것은 아닙니다.
다음 Google Dork를 사용하여 이러한 패턴의 공개된 예시를 찾을 수 있는지 확인했습니다:
파일 유형: java if “!=null &”
이번 검색에서 rootwindowContainer 내에서 Android에서 유래한 코드 일부를 찾아냈습니다.
isDocument = Intent != null & intent.isDocument()
이 코드는 코드 검토를 통과할 수 있습니다. 왜냐하면 우리는 종종 할당문에서 비트 연산자를 사용하여 값을 가리기 때문입니다. 하지만 이 경우 결과는 위의 if 문 예제와 동일합니다. intent가 영원히 null이라면 NullPointerException이 발생합니다.
우리는 방어적 코딩을 하고 중복 코드를 작성하는 경우가 많아 종종 이러한 구조에서 벗어나곤 합니다. `check! = null`은 대부분의 사용 사례에서 불필요할 가능성이 높습니다.
이것은 프로그래머가 생산 코드에서 저지르는 실수입니다.
검색 결과가 얼마나 최신인지 모르겠지만, 제가 검색을 할 때 반환되는 코드는 구글, 아마존, 아파치... 그리고 저에게서 비롯됩니다.
최근의 풀 리퀘스트는 제 오픈소스 프로젝트에서 바로 이 오류를 해결하기 위한 것입니다.
if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}
이것을 어떻게 찾을 수 있나요?
여러 정적 분석기에서 내 예제 코드를 살펴봤을 때, 그들 중 어느 것도 이 숨겨진 자폭 코드를 발견하지 못했습니다.
Secure Code Warrior 우리는 이 문제를 해결할 수 있는 상당히 간단한 Sensei 작성하고 검토했습니다.
비트 연산자는 완전히 유효하며 할당에 자주 사용되기 때문에, 문제의 코드를 찾기 위해 if 문 사용 사례와 비트 단위 AND 연산자(Bitwise &) 사용에 중점을 두어 연구했습니다.
搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”
조건 표현식으로 사용될 때, 정규 표현식을 사용하여 "&"를 일치시킵니다. 예를 들어 if 문에서.
이 문제를 해결하기 위해 우리는 다시 정규 표현식에 의존합니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식 내의 &를 &&로 전역 대체합니다.
사용 가능한 수정 프로그램:
- 이름: "비트별 AND 연산자를 논리 AND 연산자로 대체"
작업:
- 재작성:
변경 내용: "{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}"
각주
이것은 가장 흔한 비트 연산자 오용 사례, 즉 실제로 부울 연산자를 사용할 때를 포함합니다.
다른 상황에서는 이러한 현상이 발생할 수 있습니다. 예를 들어 작업 예시에서 그렇습니다. 그러나 레시피를 작성할 때는 가짜 양성 식별을 최대한 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 비활성화될 수 있습니다. 우리는 가장 일반적인 상황에 부합하도록 레시피를 생성합니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 추가 특이성을 도입할 가능성이 높습니다.
현재 형태로 볼 때, 이 공식은 많은 실제 사용 사례를 식별할 것이며, 무엇보다도제 프로젝트에서 보고된 그 사례를 포함합니다.
참고: 이 예제와 레시피 검토에 기여한 많은 코드 전사들이 있습니다—찰리 에릭슨, 매튜 칼리, 로빈 클레어호트, 브라이슨 액스, 네이선 데스메트, 도니 로버슈턴. 도움 주셔서 감사합니다.
---
IntelliJ에서 Sensei 설치하려면 "환경설정\ 플러그인"(Mac) 또는 "설정\ 플러그인"(Windows)을 사용한 Sensei "sensei Sensei
Secure Code Warrior "sensei" 저장소에는 이 글을 포함한 여러 블로그 글의 소스 코드와 레시피가 있습니다.
https://github.com/securecodewarrior/sensei-blog-examples
이 블로그 글에서는 흔히 발생하는 Java 코딩 오류(조건 연산자 대신 비트 연산자 사용), 이로 인해 코드가 취약해지는 오류 유형, 그리고 Sensei 문제를 Sensei 탐지하는 Sensei 살펴보겠습니다.
Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

Secure Code Warrior는 조직이 소프트웨어 개발 생명주기 전반에 걸쳐 코드를 보호하고 사이버 보안을 최우선으로 하는 문화를 조성하도록 지원합니다. 앱 보안 관리자, 개발자, 최고정보보안책임자(CISO) 또는 보안 관련 업무를 수행하는 모든 분들에게, 저희는 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 돕습니다.
데모 예약Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.
Java 함정 - 비트 연산자와 부울 연산자
“Java Gotcha” - 의도치 않게 쉽게 구현되는 흔한 오류 패턴.
의외로 빠지기 쉬운 아주 간단한 Java 문제는: 부울 비교 연산자 대신 비트 연산자를 사용하는 것이다.
예를 들어, 실제로 "&&"를 입력하려 할 때 간단한 입력 오류로 인해 "&"가 입력될 수 있습니다.
코드를 검토할 때 우리가 배운 일반적인 휴리스틱 방법은 다음과 같습니다:
조건문에서 "&" 또는 "|"를 사용하는 것은 의도적이지 않을 수 있습니다.
이 블로그 글에서는 휴리스틱 접근법을 살펴보고, 이 코딩 문제를 식별하고 수정하는 방법을 확인해 보겠습니다.
문제는 어디에 있는가? 부울 연산을 사용하면 비트 연산을 정상적으로 수행할 수 있다.
부울 값을 사용하는 비트 연산자는 완전히 유효하므로 Java는 문법 오류를 보고하지 않습니다.
비트별 OR(|) 및 비트별 AND(&) 연산자의 진리값 표를 탐색하기 위해 JUnit 테스트를 구성한다면, 비트 연산자의 출력이 진리값 표와 일치하는 것을 확인할 수 있을 것입니다. 이를 고려할 때, 비트 연산자 사용이 문제가 되지 않는다고 생각할 수 있습니다.
AND 진상표

@Test
void 비트 연산자와 진리표 () {
assertions.assertEquals(true, true, true);
assertions.assertEquals(false, true, false);
assertions.assertEquals(false, false, true);
assertions.assertEquals(false, false, false);
}
테스트를 통과했습니다. 이것은 완전히 유효한 Java입니다.
OR 진상표

@Test
void 비트 연산자 또는 진리값 표 () {
assertions.asserteQuals(true, true | true);
assertions.asserteQuals(true, true | false);
assertions.asserteQuals(true, false | true);
assertions.asserteQuals(false, false | false);
}
이 테스트도 통과했는데, 왜 우리는 "&&"와 "||"를 더 선호할까요?
진상표 도형은 생성된 진실표 도구 에서 web.standfor.edu에서 생성된 것입니다.
문제: 단락 작업
진정한 문제는 비트 연산자(&, |)와 부울 연산자(&&, ||) 사이의 동작 차이입니다.
부울 연산자는 단락 연산자로, 필요한 경우에만 평가됩니다.
예를 들어
if (args!= null & args.length () > 23) {
system.out.println (args);
}
위의 코드에서는 비트 연산자를 사용했기 때문에 두 부울 조건 모두 평가됩니다:
- args!= 0
- args.length() > 23
args가 비어 있을 경우, 이는 내 코드가 NullPointerException 위험에 노출되게 합니다. 왜냐하면 두 개의 부울 조건을 반드시 평가해야 하기 때문에, 매개변수가 비어 있더라도 항상 args.length를 검사하게 되기 때문입니다.
부울 연산자의 단락 평가
&&를 사용할 때, 예를 들어
if (args!= null && args.length () > 23) {
system.out.println (args);
}
arg = null 이 아닐 때만 false로 계산되며, 조건 표현식의 계산이 중단됩니다.
우측을 평가할 필요가 없습니다.
오른쪽 조건의 결과가 어떻든, 부울 표현식의 최종 값은 거짓이 될 것입니다.
그러나 이는 실제 코드에서는 절대 발생하지 않습니다.
이는 매우 흔히 저지르는 실수이며, 정적 분석 도구가 항상 이 실수를 범하는 것은 아닙니다.
다음 Google Dork를 사용하여 이러한 패턴의 공개된 예시를 찾을 수 있는지 확인했습니다:
파일 유형: java if “!=null &”
이번 검색에서 rootwindowContainer 내에서 Android에서 유래한 코드 일부를 찾아냈습니다.
isDocument = Intent != null & intent.isDocument()
이 코드는 코드 검토를 통과할 수 있습니다. 왜냐하면 우리는 종종 할당문에서 비트 연산자를 사용하여 값을 가리기 때문입니다. 하지만 이 경우 결과는 위의 if 문 예제와 동일합니다. intent가 영원히 null이라면 NullPointerException이 발생합니다.
우리는 방어적 코딩을 하고 중복 코드를 작성하는 경우가 많아 종종 이러한 구조에서 벗어나곤 합니다. `check! = null`은 대부분의 사용 사례에서 불필요할 가능성이 높습니다.
이것은 프로그래머가 생산 코드에서 저지르는 실수입니다.
검색 결과가 얼마나 최신인지 모르겠지만, 제가 검색을 할 때 반환되는 코드는 구글, 아마존, 아파치... 그리고 저에게서 비롯됩니다.
최근의 풀 리퀘스트는 제 오픈소스 프로젝트에서 바로 이 오류를 해결하기 위한 것입니다.
if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}
이것을 어떻게 찾을 수 있나요?
여러 정적 분석기에서 내 예제 코드를 살펴봤을 때, 그들 중 어느 것도 이 숨겨진 자폭 코드를 발견하지 못했습니다.
Secure Code Warrior 우리는 이 문제를 해결할 수 있는 상당히 간단한 Sensei 작성하고 검토했습니다.
비트 연산자는 완전히 유효하며 할당에 자주 사용되기 때문에, 문제의 코드를 찾기 위해 if 문 사용 사례와 비트 단위 AND 연산자(Bitwise &) 사용에 중점을 두어 연구했습니다.
搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”
조건 표현식으로 사용될 때, 정규 표현식을 사용하여 "&"를 일치시킵니다. 예를 들어 if 문에서.
이 문제를 해결하기 위해 우리는 다시 정규 표현식에 의존합니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식 내의 &를 &&로 전역 대체합니다.
사용 가능한 수정 프로그램:
- 이름: "비트별 AND 연산자를 논리 AND 연산자로 대체"
작업:
- 재작성:
변경 내용: "{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}"
각주
이것은 가장 흔한 비트 연산자 오용 사례, 즉 실제로 부울 연산자를 사용할 때를 포함합니다.
다른 상황에서는 이러한 현상이 발생할 수 있습니다. 예를 들어 작업 예시에서 그렇습니다. 그러나 레시피를 작성할 때는 가짜 양성 식별을 최대한 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 비활성화될 수 있습니다. 우리는 가장 일반적인 상황에 부합하도록 레시피를 생성합니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 추가 특이성을 도입할 가능성이 높습니다.
현재 형태로 볼 때, 이 공식은 많은 실제 사용 사례를 식별할 것이며, 무엇보다도제 프로젝트에서 보고된 그 사례를 포함합니다.
참고: 이 예제와 레시피 검토에 기여한 많은 코드 전사들이 있습니다—찰리 에릭슨, 매튜 칼리, 로빈 클레어호트, 브라이슨 액스, 네이선 데스메트, 도니 로버슈턴. 도움 주셔서 감사합니다.
---
IntelliJ에서 Sensei 설치하려면 "환경설정\ 플러그인"(Mac) 또는 "설정\ 플러그인"(Windows)을 사용한 Sensei "sensei Sensei
Secure Code Warrior "sensei" 저장소에는 이 글을 포함한 여러 블로그 글의 소스 코드와 레시피가 있습니다.
https://github.com/securecodewarrior/sensei-blog-examples
Java 함정 - 비트 연산자와 부울 연산자
“Java Gotcha” - 의도치 않게 쉽게 구현되는 흔한 오류 패턴.
의외로 빠지기 쉬운 아주 간단한 Java 문제는: 부울 비교 연산자 대신 비트 연산자를 사용하는 것이다.
예를 들어, 실제로 "&&"를 입력하려 할 때 간단한 입력 오류로 인해 "&"가 입력될 수 있습니다.
코드를 검토할 때 우리가 배운 일반적인 휴리스틱 방법은 다음과 같습니다:
조건문에서 "&" 또는 "|"를 사용하는 것은 의도적이지 않을 수 있습니다.
이 블로그 글에서는 휴리스틱 접근법을 살펴보고, 이 코딩 문제를 식별하고 수정하는 방법을 확인해 보겠습니다.
문제는 어디에 있는가? 부울 연산을 사용하면 비트 연산을 정상적으로 수행할 수 있다.
부울 값을 사용하는 비트 연산자는 완전히 유효하므로 Java는 문법 오류를 보고하지 않습니다.
비트별 OR(|) 및 비트별 AND(&) 연산자의 진리값 표를 탐색하기 위해 JUnit 테스트를 구성한다면, 비트 연산자의 출력이 진리값 표와 일치하는 것을 확인할 수 있을 것입니다. 이를 고려할 때, 비트 연산자 사용이 문제가 되지 않는다고 생각할 수 있습니다.
AND 진상표

@Test
void 비트 연산자와 진리표 () {
assertions.assertEquals(true, true, true);
assertions.assertEquals(false, true, false);
assertions.assertEquals(false, false, true);
assertions.assertEquals(false, false, false);
}
테스트를 통과했습니다. 이것은 완전히 유효한 Java입니다.
OR 진상표

@Test
void 비트 연산자 또는 진리값 표 () {
assertions.asserteQuals(true, true | true);
assertions.asserteQuals(true, true | false);
assertions.asserteQuals(true, false | true);
assertions.asserteQuals(false, false | false);
}
이 테스트도 통과했는데, 왜 우리는 "&&"와 "||"를 더 선호할까요?
진상표 도형은 생성된 진실표 도구 에서 web.standfor.edu에서 생성된 것입니다.
문제: 단락 작업
진정한 문제는 비트 연산자(&, |)와 부울 연산자(&&, ||) 사이의 동작 차이입니다.
부울 연산자는 단락 연산자로, 필요한 경우에만 평가됩니다.
예를 들어
if (args!= null & args.length () > 23) {
system.out.println (args);
}
위의 코드에서는 비트 연산자를 사용했기 때문에 두 부울 조건 모두 평가됩니다:
- args!= 0
- args.length() > 23
args가 비어 있을 경우, 이는 내 코드가 NullPointerException 위험에 노출되게 합니다. 왜냐하면 두 개의 부울 조건을 반드시 평가해야 하기 때문에, 매개변수가 비어 있더라도 항상 args.length를 검사하게 되기 때문입니다.
부울 연산자의 단락 평가
&&를 사용할 때, 예를 들어
if (args!= null && args.length () > 23) {
system.out.println (args);
}
arg = null 이 아닐 때만 false로 계산되며, 조건 표현식의 계산이 중단됩니다.
우측을 평가할 필요가 없습니다.
오른쪽 조건의 결과가 어떻든, 부울 표현식의 최종 값은 거짓이 될 것입니다.
그러나 이는 실제 코드에서는 절대 발생하지 않습니다.
이는 매우 흔히 저지르는 실수이며, 정적 분석 도구가 항상 이 실수를 범하는 것은 아닙니다.
다음 Google Dork를 사용하여 이러한 패턴의 공개된 예시를 찾을 수 있는지 확인했습니다:
파일 유형: java if “!=null &”
이번 검색에서 rootwindowContainer 내에서 Android에서 유래한 코드 일부를 찾아냈습니다.
isDocument = Intent != null & intent.isDocument()
이 코드는 코드 검토를 통과할 수 있습니다. 왜냐하면 우리는 종종 할당문에서 비트 연산자를 사용하여 값을 가리기 때문입니다. 하지만 이 경우 결과는 위의 if 문 예제와 동일합니다. intent가 영원히 null이라면 NullPointerException이 발생합니다.
우리는 방어적 코딩을 하고 중복 코드를 작성하는 경우가 많아 종종 이러한 구조에서 벗어나곤 합니다. `check! = null`은 대부분의 사용 사례에서 불필요할 가능성이 높습니다.
이것은 프로그래머가 생산 코드에서 저지르는 실수입니다.
검색 결과가 얼마나 최신인지 모르겠지만, 제가 검색을 할 때 반환되는 코드는 구글, 아마존, 아파치... 그리고 저에게서 비롯됩니다.
최근의 풀 리퀘스트는 제 오픈소스 프로젝트에서 바로 이 오류를 해결하기 위한 것입니다.
if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}
이것을 어떻게 찾을 수 있나요?
여러 정적 분석기에서 내 예제 코드를 살펴봤을 때, 그들 중 어느 것도 이 숨겨진 자폭 코드를 발견하지 못했습니다.
Secure Code Warrior 우리는 이 문제를 해결할 수 있는 상당히 간단한 Sensei 작성하고 검토했습니다.
비트 연산자는 완전히 유효하며 할당에 자주 사용되기 때문에, 문제의 코드를 찾기 위해 if 문 사용 사례와 비트 단위 AND 연산자(Bitwise &) 사용에 중점을 두어 연구했습니다.
搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”
조건 표현식으로 사용될 때, 정규 표현식을 사용하여 "&"를 일치시킵니다. 예를 들어 if 문에서.
이 문제를 해결하기 위해 우리는 다시 정규 표현식에 의존합니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식 내의 &를 &&로 전역 대체합니다.
사용 가능한 수정 프로그램:
- 이름: "비트별 AND 연산자를 논리 AND 연산자로 대체"
작업:
- 재작성:
변경 내용: "{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}"
각주
이것은 가장 흔한 비트 연산자 오용 사례, 즉 실제로 부울 연산자를 사용할 때를 포함합니다.
다른 상황에서는 이러한 현상이 발생할 수 있습니다. 예를 들어 작업 예시에서 그렇습니다. 그러나 레시피를 작성할 때는 가짜 양성 식별을 최대한 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 비활성화될 수 있습니다. 우리는 가장 일반적인 상황에 부합하도록 레시피를 생성합니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 추가 특이성을 도입할 가능성이 높습니다.
현재 형태로 볼 때, 이 공식은 많은 실제 사용 사례를 식별할 것이며, 무엇보다도제 프로젝트에서 보고된 그 사례를 포함합니다.
참고: 이 예제와 레시피 검토에 기여한 많은 코드 전사들이 있습니다—찰리 에릭슨, 매튜 칼리, 로빈 클레어호트, 브라이슨 액스, 네이선 데스메트, 도니 로버슈턴. 도움 주셔서 감사합니다.
---
IntelliJ에서 Sensei 설치하려면 "환경설정\ 플러그인"(Mac) 또는 "설정\ 플러그인"(Windows)을 사용한 Sensei "sensei Sensei
Secure Code Warrior "sensei" 저장소에는 이 글을 포함한 여러 블로그 글의 소스 코드와 레시피가 있습니다.
https://github.com/securecodewarrior/sensei-blog-examples

아래 링크를 클릭하고 이 자료의 PDF를 다운로드하세요.
Secure Code Warrior는 조직이 소프트웨어 개발 생명주기 전반에 걸쳐 코드를 보호하고 사이버 보안을 최우선으로 하는 문화를 조성하도록 지원합니다. 앱 보안 관리자, 개발자, 최고정보보안책임자(CISO) 또는 보안 관련 업무를 수행하는 모든 분들에게, 저희는 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 돕습니다.
보고서 보기데모 예약Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.
Java 함정 - 비트 연산자와 부울 연산자
“Java Gotcha” - 의도치 않게 쉽게 구현되는 흔한 오류 패턴.
의외로 빠지기 쉬운 아주 간단한 Java 문제는: 부울 비교 연산자 대신 비트 연산자를 사용하는 것이다.
예를 들어, 실제로 "&&"를 입력하려 할 때 간단한 입력 오류로 인해 "&"가 입력될 수 있습니다.
코드를 검토할 때 우리가 배운 일반적인 휴리스틱 방법은 다음과 같습니다:
조건문에서 "&" 또는 "|"를 사용하는 것은 의도적이지 않을 수 있습니다.
이 블로그 글에서는 휴리스틱 접근법을 살펴보고, 이 코딩 문제를 식별하고 수정하는 방법을 확인해 보겠습니다.
문제는 어디에 있는가? 부울 연산을 사용하면 비트 연산을 정상적으로 수행할 수 있다.
부울 값을 사용하는 비트 연산자는 완전히 유효하므로 Java는 문법 오류를 보고하지 않습니다.
비트별 OR(|) 및 비트별 AND(&) 연산자의 진리값 표를 탐색하기 위해 JUnit 테스트를 구성한다면, 비트 연산자의 출력이 진리값 표와 일치하는 것을 확인할 수 있을 것입니다. 이를 고려할 때, 비트 연산자 사용이 문제가 되지 않는다고 생각할 수 있습니다.
AND 진상표

@Test
void 비트 연산자와 진리표 () {
assertions.assertEquals(true, true, true);
assertions.assertEquals(false, true, false);
assertions.assertEquals(false, false, true);
assertions.assertEquals(false, false, false);
}
테스트를 통과했습니다. 이것은 완전히 유효한 Java입니다.
OR 진상표

@Test
void 비트 연산자 또는 진리값 표 () {
assertions.asserteQuals(true, true | true);
assertions.asserteQuals(true, true | false);
assertions.asserteQuals(true, false | true);
assertions.asserteQuals(false, false | false);
}
이 테스트도 통과했는데, 왜 우리는 "&&"와 "||"를 더 선호할까요?
진상표 도형은 생성된 진실표 도구 에서 web.standfor.edu에서 생성된 것입니다.
문제: 단락 작업
진정한 문제는 비트 연산자(&, |)와 부울 연산자(&&, ||) 사이의 동작 차이입니다.
부울 연산자는 단락 연산자로, 필요한 경우에만 평가됩니다.
예를 들어
if (args!= null & args.length () > 23) {
system.out.println (args);
}
위의 코드에서는 비트 연산자를 사용했기 때문에 두 부울 조건 모두 평가됩니다:
- args!= 0
- args.length() > 23
args가 비어 있을 경우, 이는 내 코드가 NullPointerException 위험에 노출되게 합니다. 왜냐하면 두 개의 부울 조건을 반드시 평가해야 하기 때문에, 매개변수가 비어 있더라도 항상 args.length를 검사하게 되기 때문입니다.
부울 연산자의 단락 평가
&&를 사용할 때, 예를 들어
if (args!= null && args.length () > 23) {
system.out.println (args);
}
arg = null 이 아닐 때만 false로 계산되며, 조건 표현식의 계산이 중단됩니다.
우측을 평가할 필요가 없습니다.
오른쪽 조건의 결과가 어떻든, 부울 표현식의 최종 값은 거짓이 될 것입니다.
그러나 이는 실제 코드에서는 절대 발생하지 않습니다.
이는 매우 흔히 저지르는 실수이며, 정적 분석 도구가 항상 이 실수를 범하는 것은 아닙니다.
다음 Google Dork를 사용하여 이러한 패턴의 공개된 예시를 찾을 수 있는지 확인했습니다:
파일 유형: java if “!=null &”
이번 검색에서 rootwindowContainer 내에서 Android에서 유래한 코드 일부를 찾아냈습니다.
isDocument = Intent != null & intent.isDocument()
이 코드는 코드 검토를 통과할 수 있습니다. 왜냐하면 우리는 종종 할당문에서 비트 연산자를 사용하여 값을 가리기 때문입니다. 하지만 이 경우 결과는 위의 if 문 예제와 동일합니다. intent가 영원히 null이라면 NullPointerException이 발생합니다.
우리는 방어적 코딩을 하고 중복 코드를 작성하는 경우가 많아 종종 이러한 구조에서 벗어나곤 합니다. `check! = null`은 대부분의 사용 사례에서 불필요할 가능성이 높습니다.
이것은 프로그래머가 생산 코드에서 저지르는 실수입니다.
검색 결과가 얼마나 최신인지 모르겠지만, 제가 검색을 할 때 반환되는 코드는 구글, 아마존, 아파치... 그리고 저에게서 비롯됩니다.
최근의 풀 리퀘스트는 제 오픈소스 프로젝트에서 바로 이 오류를 해결하기 위한 것입니다.
if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}
이것을 어떻게 찾을 수 있나요?
여러 정적 분석기에서 내 예제 코드를 살펴봤을 때, 그들 중 어느 것도 이 숨겨진 자폭 코드를 발견하지 못했습니다.
Secure Code Warrior 우리는 이 문제를 해결할 수 있는 상당히 간단한 Sensei 작성하고 검토했습니다.
비트 연산자는 완전히 유효하며 할당에 자주 사용되기 때문에, 문제의 코드를 찾기 위해 if 문 사용 사례와 비트 단위 AND 연산자(Bitwise &) 사용에 중점을 두어 연구했습니다.
搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”
조건 표현식으로 사용될 때, 정규 표현식을 사용하여 "&"를 일치시킵니다. 예를 들어 if 문에서.
이 문제를 해결하기 위해 우리는 다시 정규 표현식에 의존합니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식 내의 &를 &&로 전역 대체합니다.
사용 가능한 수정 프로그램:
- 이름: "비트별 AND 연산자를 논리 AND 연산자로 대체"
작업:
- 재작성:
변경 내용: "{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}"
각주
이것은 가장 흔한 비트 연산자 오용 사례, 즉 실제로 부울 연산자를 사용할 때를 포함합니다.
다른 상황에서는 이러한 현상이 발생할 수 있습니다. 예를 들어 작업 예시에서 그렇습니다. 그러나 레시피를 작성할 때는 가짜 양성 식별을 최대한 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 비활성화될 수 있습니다. 우리는 가장 일반적인 상황에 부합하도록 레시피를 생성합니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 추가 특이성을 도입할 가능성이 높습니다.
현재 형태로 볼 때, 이 공식은 많은 실제 사용 사례를 식별할 것이며, 무엇보다도제 프로젝트에서 보고된 그 사례를 포함합니다.
참고: 이 예제와 레시피 검토에 기여한 많은 코드 전사들이 있습니다—찰리 에릭슨, 매튜 칼리, 로빈 클레어호트, 브라이슨 액스, 네이선 데스메트, 도니 로버슈턴. 도움 주셔서 감사합니다.
---
IntelliJ에서 Sensei 설치하려면 "환경설정\ 플러그인"(Mac) 또는 "설정\ 플러그인"(Windows)을 사용한 Sensei "sensei Sensei
Secure Code Warrior "sensei" 저장소에는 이 글을 포함한 여러 블로그 글의 소스 코드와 레시피가 있습니다.
https://github.com/securecodewarrior/sensei-blog-examples
목록
Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

Secure Code Warrior는 조직이 소프트웨어 개발 생명주기 전반에 걸쳐 코드를 보호하고 사이버 보안을 최우선으로 하는 문화를 조성하도록 지원합니다. 앱 보안 관리자, 개발자, 최고정보보안책임자(CISO) 또는 보안 관련 업무를 수행하는 모든 분들에게, 저희는 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 돕습니다.
데모 예약다운로드



%20(1).avif)
.avif)
