ReDoS attacks

테스트

example.js
1
2
3
console.time(0);
/^(([a-z])+.)+[A-Z]([a-z])+$/g.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!');
console.timeEnd(0);
  • a가 많아질수록 급격하게 평가하는데 오래 걸리는 모습이다
  • 복잡한 정규식을 짤 때 성능 테스트가 동반되어야 할 것 같다
  • 인풋의 길이 등 사전에 필터링해줄 수 있는 것들은 필터링해주면 좋을 것 같다

참고

ORM

  • 전통?의 데이터베이스 사용은 ERD를 작성(식별부터 정규화까지)하고,
  • DDL로 테이블 생성 등 데이터베이스 사용을 위한 초기화를 하고,
  • DML로 조회 쿼리를 작성하는 등 과정을 거쳐 사용했다
  • 그런데 ORM, Object Relational Mapping 이 뭘까..?
  • 위 영상을 보고 정리한 내용

ORM

  • 오브젝트 기반의 ~
  • 객체(클래스)를 만들면 테이블을 생성해주는 마법

장점

  • data model을 한 곳에서 작성한다
  • 백엔드에서 데이터베이스 테이블과 매핑되는 타입을 정의하는데, ORM을 쓰면 내가 정의한 모델 자체가 타이핑이 된다
  • sql을 작성하지 않아도 된다 ; 모델을 정의하면 DDL을 알아서 생성한다. DML 작성 대신 메서드를 사용한다
  • 데이터베이스 추상화 ; 보통의 ORM 라이브러리들은 여러 데이터베이스를 지원한다
  • 오라클을 사용하다가 mysql로 데이터베이스를 바꿔도 전혀 문제가 없다
  • OOP를 활용한다 ; OOP를 알고 있으면 친숙하다

단점

  • ORM을 따로 배워야 한다
  • ORM을 통해 데이터베이스를 다룬다는 것에서 레이어가 나뉘었다는 장점?이 있지만, 데이터베이스를 커스텀하기 힘들다 (성능)

ORM 예

  • 자바에서는 hibernate,
  • 노드에서는 sequelize, typeorm, prisma 등이 있다

참고

SSG, static site generator

  • 정적 사이트 생성기
  • react와 같은 spa 라이브러리/프레임워크로 생성한 spa를 여러 html로 쪼개 준다
  • SSR 도구 예 ; nextjs, hexo,…

같이 보기

js coercion

  • 서로 다른 타입끼리 연산을 할 때, 타입 캐스팅이 일어난다
  • js에서는 이를 coercion 이라고 부르는 것 같다
  • 조금 더 정확히는, 타입 캐스팅을 암시적으로(implicitly) 해주는 것
  • js에서 서로 다른 타입 간의 연산을 하더라도 웬만하면 에러가 안 뜬다
  • 어느 한쪽을 기준으로 자동 캐스팅되어서 js를 처음 배울 때 너무 편했다
  • 이런 강제 형변환이 직관적이라고 생각할 때도 있지만, 가끔 실수할 때가 있다
  • 나는 처음 js를 배울 때 var보다는 const, let
  • ==보다는 ===를 사용하라고 배워서 그냥 그런가 보다 하고 따랐었는데,
  • 특히 조건문에서 강제 형변환은 예상하지 못한 동작들을 많이 만들어내는 것 같다
  • ===, !==를 사용함으로써 강제 형변환 없이 비교해 볼 수 있다

참고

js hoisting 호이스팅

javascript에서는 선언 전에 변수를 사용할 수 있는 경우가 있는데, 호이스팅 때문이다
근데 호이스팅은 나쁜거다

var
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function f() {
console.trace(A); // undefined
{
console.trace(A); // undefined
{
console.trace(A); // undefined
var A = 1;
}
console.trace(A); // 1
}
console.trace(A); // 1
}
f();
// console.trace(A) // not work
  • var 키워드를 사용하면 함수 최상위 스코프로 간다
  • 변수 A는 선언도 안되었는데 잘 실행되는 이유이다
함수 호이스팅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
f();
// g(); // not work
// h(); // not work

function f() {
let a = 1;
console.log(a);
}

const g = function () {
console.log(2);
};

const h = () => {
console.log(3);
};
  • 특히 함수는 함수 선언식? 일 때 호이스팅 된다
  • 나는 처음 js를 배울 때, varconst, let으로 대체해라고 해서
  • 일단은 var을 안 쓰면서 공부를 해왔었는데,
  • 그래선지 호이스팅 관련해서 골머리 아픈 적이 없었던 것 같다

참고

script태그 defer, async

  • 처음 웹 프로그래밍을 배울 때 스크립트 태그는 body 최하단에 위치시키라고 배웠다
  • 스크립트 로드 타이밍을 뒤로 미뤄서 돔을 조작하는 스크립트가 잘 동작한다
  • 근데 요즘에는 스크립트 태그를 head 안에 선언하는 경우가 많다
  • defer를 사용하면 위에서 말한 효과를 볼 수 있다
  • 근데 defer 말고도 async라는 속성을 줄 수 있다
  • 둘이 차이는 뭘까?

default (blocking further parsing)

  • 스크립트 태그를 만나면 파싱을 멈추고 스크립트를 로드하고 실행한다
  • 이 때 HTML 파싱을 멈춘다
  • 스크립트가 로드 다 끝나면 이어서 남은 파싱을 진행한다
  • 스크립트가 헤비 하면 화면이 안 그려지고 사용자가 떠날 확률도 높아지겠다

defer, async 공통

  • 스크립트는 스크립트대로 로드하고 HTML 파싱은 계속된다
  • 비동기적이다

defer

  • 스크립트 로드가 완료되었다고 바로 실행되지 않는다
  • HTML 파싱이 모두 끝나면 실행된다
  • 주로 돔을 조작하는 스크립트를 로드할 때 사용하면 된다

async

  • 스크립트가 로드되고 바로 실행된다
  • 돔을 조작하는 스크립트가 없을 때 사용하는 것이 좋다

참고

디바운스와 스로틀

  • 스크롤 이벤트가 발생하면 1을 출력하는 함수를 실행시킨다고 하자

기본

  • 아날로그 신호처럼 콘솔창에 1이 찍힌다

throttle

  • 설정한 주기를 간격으로 1이 찍힌다
  • 쓰로틀은 연속된 이벤트를 설정한 시간 간격
  • 예) 스크롤중 300ms 마다 함수 실행
  • 예) 네이버 검색창 자동완성

debounce

  • 스크롤 이벤트 도중에는 아무것도 일어나지 않는다
  • 이벤트가 끝나고 설정한 1이 찍힌다
  • 디바운스는 연속된 이벤트가 멈추고, 한번 실행한다
  • 마지막 이벤트로부터 설정한 시간만큼 이벤트가 발생하지 않으면 실행한다
  • 예) 스크롤이 멈추고 300ms 뒤에 함수 실행
  • 예) 버튼을 연속적으로 여러 번 눌러도 한 번만 실행되는… (광클 방지)

쓰는 이유

  • 디바운스와 쓰로틀은 부하를 줄이기 위해 사용한다
  • 매 이벤트마다 비싼 API를 호출하는 것을 방지할 수 있다