2020년 3월 25일 보안정보 스크래핑

2020년 3월 25일 보안정보 스크래핑 3월 25일 보안정보 스크래핑 ==================================================================== + 주요 취약점 - 메일전송 프로토콜을 이용한 원격 명령어 실행 주의 권고 외 1건 1. 메일전송 프로토콜을 이용한 원격 명령어 실행 주의 권고 최근 OpenSMTPD* 취약점이 발견되는 등 메일전송 프로토콜에서 원격 명령어 실행이 가능하여 주의를 권고함 공격자는 취약점을 악용하여 피해를 발생시킬 수 있으므로, 해결방안을 참고하여 조치 필요 - https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35302 2. Django 제품 SQL Injection 취약점 보안 업데이트 권고 최근 Django*에서 SQL Injection취약점(CVE-2020-9402)을 악용할 수 있는 개념증명코드(Proof of concept, PoC)가 인터넷상에 공개되어 사용자의 보안 업데이트 필요 - https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35301 ==================================================================== + 취약점 - Apple Safari 취약점 1. Apple Safari 취약점 Apple Safari security bypass CVE-2020-3885 - https://exchange.xforce.ibmcloud.com/vulnerabilities/178339 Apple Safari security bypass CVE-2020-3887 - https://exchange.xforce.ibmcloud.com/vulnerabilities/178338 Apple Safari inform...

django에서 object queryset을 여러 기준으로 ordering하기 + object...

django에서 object queryset을 여러 기준으로 ordering하기 + object...

django에서 object queryset을 여러 기준으로 ordering하기 + object filter의 order_by 기준을 동적으로 구성하기.

이런 저런 작업을 하다가 Big aha moment를 만나서 적어두려 한다. 다른 부분은 거두절미 하겠다.

이러한 모델이 만들어져있다는 가정 하에 시작할 것이다.

class Post(models.Model): title = models.CharField() #제목 content = models.TextFiled() #내용 timestamp = models.DateTimeField(default=timezone.now) #만들어진 시간 like_count = models.IntegerField() #좋아요 눌린 횟수 view_count = models.IntegerField() #뷰 횟수

보통 이런 게시물류의 객체는 만들어진 시간을 기준으로 정렬하기 마련이다. 그래서 views.py단에서 이런 식으로 정리해서 뿌려주게 된다.

post = Post.objects.all().order_by('-timestamp') # 만들어진시간을 기준으로 내림차순 -> 가장 최근의 게시물이 위에오게

(오름차순으로 하고 싶다면 -timestamp 앞의 - 를 없애주면 된다.)

만약에 게시판에 정렬기능을 추가해서 좋아요가 많이 눌리게 된 순으로 정렬하고 싶다면? 답은 간단하다.

post = Post.objects.all().order_by('-like_count') # 좋아요 갯수의 내림차순 -> 가장 많은 좋아요 갯수가 달린 게시물이 위에오게

로 정렬하면 된다.

그렇다면 복합적으로, 좋아요가 가장 많이 눌린 순서대로 정렬하되, 같은 갯수의 좋아요가 눌린 게시물이 있다면 더 예전에 써진 글부터 위에 노출하고 싶다. 하면 어떻게 해야할까. 이것 역시 간단하다.

post = Post.objects.all().order_by('-like_count', '-timestamp') # 좋아요 갯수의 내림차순으로 먼저

이런식으로 하면 된다.

들어오는 요청값에 따라 order_by 안에 들어가는 문자열을 컨버팅해준다면 이정도의 처리는 어렵지 않을 것이다. 하지만 문제는 "상식적인 사이트가 작동하는 방식"을 구현하는 데에서 튀어나온다.

자, 한 유저가 게시판에 들어왔다고 치자. 가장 익숙한 모습인 시간의 내림차순으로 정렬돼있을 것이며 쿼리는

post = Post.objects.all().order_by('-timestamp')

이런 식으로 구성이 돼있을 것이다. (페이지 네이션과 같은 요소는 제하였다.)

이 유저는 이 게시판에 어떤 게시물이 제일 인기있었는지 궁금해서 좋아요의 내림차순으로 게시물들을 조회하려 한다. 그러면

post = Post.objects.all().order_by('-like_count', '-timestamp')

이런 모습의 쿼리가 돼야한다.

그렇다. 들어오는 요청에 맞춰서 유저가 원하는 방식의 게시물 정렬을 위해선 order_by() 안에 들어가는 인수의 형태나 갯수, 순서마저 바뀌어야한다. 물론

post = Post.objects.all().order_by(like_count_order, timestamp_order)

같은 식으로 변수만 받아서 뿌려주면서 빈 변수는 생략되는 식이라면 얼마나 편할까, 하지만 order_by() 는 그런식으로 작동하지 않는다. 빈 칸이 있거나 이상한 정렬값이 들어오면 여지없이 Invalid order_by arguments 에러를 내뿜는다. 그리고 심지어 이런식이면 timestamp와 like_count의 우선순위가 뒤바뀌었을 때의 처리는 거의 불가능에 가깝다.

물론 조건에 따라 모든 경우의 수에 맞춰 if문으로 일일히 작성하면 되겠지만... 프로그래머는 그런식의 프로그래밍은 유지보수와 디버깅, 기능확장에 커다란 장애가 된다는 점 모두 잘 알고 있을 것이다.

예를 들어 정렬기준이 이 두가지라면 그래도 또 if문으로 해결이 가능하겠지만 만약에 view_count까지 정렬 기준에 합세하고 거기에 오름차순 내림차순 기능까지 추가된다면 말이다.

아무튼 이러한 요소들을 수월하게 해결하려면 결국엔 if문으로 가지를 치는 게 아니라 oder_by안에 들어가는 요소들을 동적으로 바꿔줘야 한다는 결론에 이른다. 실제 내가 작업하고 있는 플랫폼의 코드를 빌려오자면 이렇다. (내가 만들고 있는 내 플랫폼이니 문제가 될 소지는 없을 것이다.)

# order는 오름차순인지 내림차순인지 정의하는 변수이고 # sort는 그 기준이 어떤 컬럼인지 정의하는 변수이다. ordering_priority = [] # 이곳에서 오름차순인지 내림차순인지 알아낸 뒤에 명령어를 변수에 입력해둔다. order = '' if request.GET.get('order') == 'asc' else '-' # 종합해서 ordering query를 생성한다. if request.GET.get('sort') and request.GET.get('sort') != 'timestamp': # 정렬 기준이 시간이 아닐 때만 해당 값을 ordering_priority에 추가한다. # 시나리오대로라면 이곳에 like_count라는 값이 들어갔을 것이다. # 다른 기준으로 정렬하면 무조건 시간의 내림차순으로 정렬하기 때문에 이런식으로 구성이 된다. sort = request.GET.get('sort') ordering_priority.append(order + sort) ordering_priority.append('-timestamp') else: sort = 'timestamp' ordering_priority.append(order + sort) posts = Post.objects.all().order_by(*ordering_priority)

이런식으로 하면 어떤 정렬기준을 들이밀어도 수월하게 해낼 수 있을 것이다.

p.s: 사실 동적으로 ordering query를 뱉어주는 로직은 다 만들어놓고 order_by의 뒤어 들어가는 인수의 자료형 이리저리 해봐도(list, tuple, set, dict등...) 제대로 실행도 안되고 오류만 내뱉길래 골치아팠는데 갑자기 옛날에 알고리즘 문제를 풀다가 *iterable 식으로 하면 안의 요소가 전부 풀려서 쓰여진다는 사실이 기억나서 해봤더니 잘 돼서 기쁜 마음에 글까지 남긴다. 이렇게 하면 수많은 컬럼이 덕지덕지 달려서 엑셀처럼 수많은 정렬기준과 오름차순 내림차순의 우선순위까지 요구하는 어플을 만든다고 할지라도 수월하게 작성할 수 있을 것이다.

from http://this-programmer.com/286 by ccl(S) rewrite - 2020-03-11 06:20:23

댓글

이 블로그의 인기 게시물

엑스브레인(XBrain) 기업 정보

django 설치 방법

[aws] deploy Angular app with s3 | AWS S3로 angular 앱 배포하기