반응형

Okapi BM25는 검색엔진, 추천 시스템 등에서 사용되는 스코어링 알고리즘이다.

tf(term frequency) 와 idf(inversed document frequency) 의 개념을 바탕으로,

문서의 길이까지 고려를 하여 스코어링을 한다.

 

Okapi BM25의 기본적인 식은 다음과 같다.

 

 

 

식이 꽤 복잡해 보이지만 알고 보면 tf, idf, 문서 길이만 factor로 사용하며

나머지는 이 세 가지 요소들을 어떻게 weight를 주어 스코어링을 할 것인지를 결정하는 부분이다.

 

식을 처음부터 살펴보자.

 

 

 

Document (D) 에 Query (Q) 를 날려 얼마나 일치하는지 score를 얻는 것이 목적이다.

만약 검색에서 이 알고리즘을 사용한다면, score가 높은 순서대로 Document가 정렬되어 검색 결과로 나타날 것이다.

 

 

 

Query를 쪼개면 여러 개의 term이 생길 것이다.

제일 쉽게는 띄어쓰기를 기준으로 쪼갤 수 있을 것이다.

각 term을 Document에 적용한 결과를 모두 더하여 score가 결정된다.

 

 

 

idf의 식이다.

해당 term을 가지고 있는 문서의 갯수 / 전체 문서의 갯수 (=df) 를 역수 취하고 로그를 씌운 값이다.

보통 N이 매우 크기 때문에 로그를 씌워 값의 range를 좁혀준다.

(Document set이 1000000개의 Document들로 이루어져 있고, 그 중 검색하는 term이 나온 문서가 10개라면

로그를 씌우지 않았을 때는 값이 100000 이지만, 로그를 씌우면 5가 된다.)

 

 

 

제일 복잡해 보이는 식이다.

일단 tf(td) 는 말 그대로 Document d에서 t라는 term이 얼마나 나타났는지 그 count를 나타내는 것이고,

L(d) 는 현재 Target Document d의 길이,

L(avg) 는 전체 Document set에 있는 모든 Document 길이의 평균을 나타낸다.

(여기서 Document의 길이라 함은 term이 몇개인가? 라고 이해하면 되겠다.)

나머지 k1과 b는, tf와 L값을 어떻게 weight를 주어 계산을 해 줄건지 결정하는 parameter라고 보면 된다.

 

k1이 0이라면? 모든 텀은 다 지워지고 저 식이 통째로 1이 되겠다.

결국 tf고 L이고 뭐고 아무것도 고려를 안 하겠다는 말이 된다.

k1이 높아지면 높아질수록 tf에 많은 가중치를 두어 계산한다는 뜻이 된다.

 

그럼 b가 0이라면? 문서의 길이를 고려하지 않겠다는 말이 되고

b가 1에 가까워질수록 문서의 길이에 많은 가중치를 두어 계산한다는 뜻이 되겠다.

(k1과는 달리 b는 1을 넘을 수 없다.)

 

실험적으로, k1은 1.2와 2.0 사이, b는 0.75로 설정하는 것이 제일 올바른 스코어링을 하게 한다고 하지만

어떤 도메인에서 어떤 검색을 실행할 것인가에 따라 두 값을 조정하여 알고리즘을 튜닝할 수 있겠다.

 

어쨌든 보자면, score가 높아지려면 tf(td) 의 값은 높아져야 하고,

L(d) / L(avg) 의 값은 낮아져야 한다는 것을 알 수 있다.

여기서 tf는 그렇다 쳐도 문서의 길이는 왜 따지냐고 할 수 있는데, 이것도 간단하다.

100단어로 이루어진 문서 중 내가 날린 term이 한번 나오는 것과,

1000단어로 이루어진 문서 중 내가 날린 term이 한번 나오는 것은 매우 다르기 때문이다.

짧은 문서에서 내가 찾는 핵심 term만 딱! 나오는 게,

긴 문서에서 주저리주저리 하다가 어쩌다 내가 찾는 term이 한번 나오는 것보다는 훨씬 매칭이 잘 되는 문서일 것이다.

 

 

이제 총정리를 하면, 어떤 문서와 쿼리가 매칭이 잘 되어 높은 score를 얻기 위해서는 :

1. 내가 날린 query 안의 term이 적은 문서에만 있는, 즉 매우 희소하고 자주 쓰이지 않는 단어여야 하며,

2. 문서에서 해당 term이 많이 나와야 하며,

3. 해당 문서의 길이는 짧아야 한다.

로 요약할 수 있겠다!

 

근데 저 공식은 매우 기본적인 형태이고, 실질적으로 검색 서비스에 사용되는 랭킹 알고리즘은 훠어어어어어얼씬 더 많은 피쳐들을 알고리즘에 적용한다.



출처: https://jitwo.tistory.com/8 [jitwo]

반응형

'DB > .etc' 카테고리의 다른 글

SQL Injection 이란? (SQL 삽입 공격)  (0) 2020.04.27
[Postman] Mock Server / API Documentation 만들기  (0) 2020.04.17
반응형

1. SQL Injection

 1.1 개요

 

 

 

Ÿ   SQL Injection

SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위 입니다. 인젝션 공격은 OWASP Top10 중 첫 번째에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격입니다.

 

 

Ÿ   여기어때 해킹 사건

2017 3월에 일어난 여기어때 의 대규모 개인정보 유출 사건도 SQL Injection 으로 인해 피해가 발생하였습니다.

 1.2 공격 종류 및 방법

Error based SQL Injection

논리적 에러를 이용한 SQL Injection 

SQL 공격 기법은 여러 가지가 있는데 논리적 에러를 이용한 SQL Injection은 가장 많이 쓰이고, 대중적인 공격 기법입니다.

 

 

Ÿ   Error based SQL Injection

 

위의 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문입니다. 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입하였습니다. 주입된 내용은 ‘ OR 1=1 --   WHERE 절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와 OR 1=1 라는 구문을 이용해 WHERE 절을 모두 참으로 만들고, -- 를 넣어줌으로 뒤의 구문을 모두 주석 처리 해주었습니다.

  매우 간단한 구문이지만, 결론적으로 Users 테이블에 있는 모든 정보를 조회하게 됨으로 써 가장 먼저 만들어진 계정으로 로그인에 성공하게 됩니다. 보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인 할 수 있게 됩니다. 관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른 2차피해를 발생 시킬 수 있게 됩니다.

 

 

Union based SQL Injection

Union 명령어를 이용한 SQL Injection 

 SQL 에서 Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드 입니다. 정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 됩니다. Union Injection을 성공하기 위해서는 두 가지의 조건이 있습니다. 하나는 Union 하는 두 테이블의 컬럼 수가 같아야 하고, 데이터 형이 같아야 합니다. 

 

 

Ÿ   Union based SQL Injection

 

위의 사진에서 보이는 쿼리문은 Board 라는 테이블에서 게시글을 검색하는 쿼리문입니다. 입력값을 title  contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력합니다. 여기서 입력값으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐서서 하나의 테이블로 보여지게 됩니다. 현재 인젝션 한 구문은 사용자의 id passwd를 요청하는 쿼리문 입니다. 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 됩니다. 

 물론 패스워드를 평문으로 데이터베이스에 저장하지는 않겠지만 인젝션이 가능하다는 점에서 이미 그 이상의 보안위험에 노출되어 있습니다. 이 공격도 역시 입력값에 대한 검증이 없기 때문에 발생하게 되었습니다.

 

 

Blind SQL Injection

Boolean based SQL

Blind SQL Injection은 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용합니다. 로그인 폼에 SQL Injection이 가능하다고 가정 했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있습니다.

 

 

Ÿ   Blind SQL Injection – Boolean based

 

위의 그림은 Blind Injection을 이용하여 데이터베이스의 테이블 명을 알아내는 방법입니다. (MySQL) 인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한 abc123 이라는 아이디와 함께 abc123’ and ASCII(SUBSTR(SELECT name From information_schema.tables WHERE table_type=’base table’ limit 0,1)1,1)) > 100 -- 이라는 구문을 주입합니다.

 해당구문은 MySQL 에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해줍니다. 만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 됩니다.  거짓이면 로그인 실패가 될 것이고, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 하면 됩니다.  공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있습니다.

 

Blind SQL Injection

Time based SQL

Time Based SQL Injection 도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법입니다. 사용되는 함수는 MySQL 기준으로 SLEEP  BENCHMARK 입니다.

 

Ÿ   Blind SQL Injection - Time based

 

위의 그림은 Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법입니다. 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해 두었습니다. 악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) – 이라는 구문을 주입하였습니다. 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환합니다.

 주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않습니다. 이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아 낼 수 있습니다. 만약에 SLEEP 이라는 단어가 치환처리 되어있다면, 또 다른 방법으로 BENCHMARK  WAIT 함수를 사용 할 수 있습니다. BENCHMARK  BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')); 이런 식으로 사용이 가능합니다. 이 구문을 실행 하면 약 4.74초가 걸립니다.

 

 

Stored Procedure SQL Injection

저장된 프로시저 에서의 SQL Injection

저장 프로시저(Stored Procedure) 은 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것입니다. 공격에 사용되는 대표적인 저장 프로시저는 MS-SQL 에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 됩니다. , 공격자가 시스템 권한을 획득 해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격 입니다.

 

 

 

Mass SQL Injection

다량의 SQL Injection 공격

 2008년에 처음 발견된 공격기법으로 기존 SQL Injection 과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미합니다. 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩 하여 공격합니다. 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 합니다. 이렇게 감염된 좀비 PC들은 DDoS 공격에 사용됩니다.

 

 

1.3 대응방안

입력 값에 대한 검증

SQL Injection 에서 사용되는 기법과 키워드는 엄청나게 많습니다. 사용자의 입력 값에 대한 검증이 필요한데요. 서버 단에서 화이트리스트 기반으로 검증해야 합니다. 블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야 하고, 하나라도 빠지면 공격에 성공하게 되기 때문입니다. 공백으로 치환하는 방법도 많이 쓰이는데, 이 방법도 취약한 방법입니다. 예를 들어 공격자가 SESELECTLECT 라고 입력 시 중간의 SELECT가 공백으로 치환이 되면 SELECT 라는 키워드가 완성되게 됩니다. 공백 대신 공격 키워드와는 의미 없는 단어로 치환되어야 합니다.

 

 

Prepared Statement 구문사용

 Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기합니다. 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않습니다.

 

 

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요합니다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환헤 줍니다. 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 합니다.

 

웹 방화벽 사용

웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법입니다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법입니다.

 

출처 : https://noirstar.tistory.com/264

반응형
반응형

예전부터 postman을 사용하여 만든 api를 호출하고 테스트 해왔는데 생각보다 기능들이 많고 손쉽게 만들 수 있어서 아래와 같이 정리를 합니다. 여기서 설명할 내용은 mock server와 api 문서를 만드는 방법입니다. mock server를 만들면서 api 문서화를 같이 진행할 수 있고 그 반대의 경우도 가능하므로 개발자에게 아주 편리한 기능을 제공합니다.

1. Mock server 생성하기

이미지의 좌측 상단에 있는 New 버튼을 누르면 팝업이 뜨는데 여기서 Mock Server를 눌러줍니다. 

 

누르면 다음 화면이 위와 같이 나오는데 Request Path 부분에 경로를 입력하면 우측 하단의 Next가 활성화가 됩니다. 위에서 지정한 Request Path는 나중에 수정이 가능하므로 일단 test라는 경로로 지정하고 다음으로 넘어갑니다.

 

Mock server의 이름을 지정해주면 위 경우와 마찬가지로 우측 하단의 Create 버튼이 활성화가 됩니다. 이름은 역시 나중에 수정이 가능하므로 Test mock server로 임시 지정해 줍니다. 여기서는 설명하지 않지만 만약 이미 존재하는 Collection에 Mock Server를 추가하는 경우라면 Name 아래의 Use an environmnet에서 선택하면 됩니다. 없을 경우 위와 같이 아무 것도 선택하지 않으면 됩니다.

 

Create를 누르면 위처럼 Mock Server가 생성됩니다. 빨간색 박스로 가린 부분에 생성된 Mock Server URL이 발급됩니다.

 

 

 

위와 같이 Mock Server만 생성하면 Collection이 같이 만들어 집니다. 여기서 한 가지 확인해야 되는 부분은 {{url}}은 postman의 환경 변수를 타기 때문에 우측 상단에 있는 No Environment 상태에서 호출하면 호출이 되지 않습니다.

 

위처럼 생성한 Test mock server를 설정해야 위에서 생성된 mock server url이 {{url}} 변수에 연결됩니다.

2. mock api 반환 형태 설정하기

위의 /test/ api가 호출됐을 때 어떤 response를 줄지 구성해야 하기 때문에 우측 상단쪽에 있는 Examples에서 Default를 누릅니다.

 

위와 같이 아래쪽 EXAMPLE RESPONSE를 원하는 대로 꾸며줍니다. 

 

저장을 한 다음, 해당 API를 호출하면 설정한 대로 나오는 것을 확인할 수 있습니다.

3. API 문서 만들기

/test/ API의 request와 respoonse에 대한 설명 뿐만 아니라 해당 collection에 대한 설명을 작성할 수 있습니다. postman은 markdown 문법을 지원하므로 테이블 형태로 작성하는 것이 아니라면 손쉽게 꾸밀 수 있습니다.

 

문서를 추가하고자 하는 api 목록에서 오른쪽 마우스 또는 우측 ... 을 클릭하여 Edit을 눌러줍니다.

 

위와 같이 설명을 추가한 다음 Update를 누릅니다.

 

생성한 API 문서를 확인하기 위해 Test mock server 리스트에 마우스를 올려놓으면 화살표가 보이는데 해당 화살표를 누른 다음 View in web버튼을 누릅니다.

 

그러면 위와 같이 웹이 호출되고 위와 같이 작성한 API 문서를 확인할 수 있습니다.

요약

위와 같은 방법으로 손쉽게 API 문서와 Mock server를 생성하고 모니터링이나 변경로그 기능도 제공합니다. 또한 하나의 collection에 여러 mock server url을 가질 수 있고, 환경변수를 사용하여 mock server 별로 파라미터를 다르게 지정할 수도 있습니다. 무료 버전에서는 생성할 수 있는 collection과 request 등이 제한되어 있지만 유료 버전이 비싼 편에 속하지 않기 때문에 협업 도구로 충분히 고려할 만합니다.

장점

  • Mock Server를 위한 서버 구성이 필요가 없음
  • 특별한 코딩이 필요 없고 단순한 클릭 몇 번으로 손쉽게 생성 가능
  • 또한 API 문서도 쉽게 생성 가능
  • 환경 별로 변수의 값을 다르게 설정할 수 있음
  • CORS가 설정되어 있음

단점

  • 호출 횟수에 제한이 있음 (1분당 60회)
  • 특정 API의 Example에 Path, Header, Params, Body가 같은 것이 있으면 최근에 추가된 Example가 호출됨
    • 하지만 경로, 헤더 파라미터, 바디가 각각 다르게 설정할 수 있다는 장점이 있음

 

 

출처 : https://brownbears.tistory.com/448

반응형

+ Recent posts