[Javascript] 전역에서 객체를 선언하면 안되는 이유

 

이번에 우테코 2주차 코드 리뷰에서 정말 중요한 피드백을 하나 받았습니다! 바로 전역에서 객체를 선언하지 말라는 것! 그렇다면 왜 객체를 전역에서 선언하는 것이 위험할까요?

❓객체의 특성

이번 우테코 2주차 미션에서 제가 작성한 코드 하나를 예로 보면서 어떤 상황인지 설명드리겠습니다.

const carHandler = {
  readCarsInput: async () => {
    const INPUT = await readInput(CAR_MESSAGES.INPUT);
    validateCarsInput(INPUT);
    return INPUT;
  },

  handleCarConvertedToClass: (cars) => {
    const carClasses = cars.map((car) => {
      const carClass = new Car(car);
      return carClass;
    });
    return carClasses;
  },
};

export default carHandler;

저는 carHandler.js 파일에 저렇게 코드를 작성하였습니다. 의도는 carHandler라는 객체를 만들고, 내부 메서드를 carHandler 객체를 통해 접근하도록 만든 것이죠. 하지만 여기에는 정말 취약한 문제가 있다는 것을 알았습니다.

일단 객체의 특성을 보겠습니다.

const myObject = { name: "lurgi" }
myObject.name = "jeong woo" // 이 작업은 성공합니다.
myObject = { name : "jeong woo park"} // 이 작업은 실패합니다.

객체의 특성이 보이시나요? 객체는 key값으로 내부에 접근이 가능하다는 특성이 있습니다.

그러니 value값이 보안에 중요한 값이라면, key값으로 접근할 수 있으니 객체로 만들면 안된다는 것입니다.

이 특성 때문에 전역에서 객체를 선언하는 것이 정말 위험해 집니다.

전역에서 객체를 선언하는 순간, 모든 곳에서 접근이 가능하기 때문입니다. 자바스크립트에서는 전역에서 선언된 객체는 전역 객체인 window 혹은 global 속성에 추가됩니다. 그렇기 때문에 해당 객체는 모든 곳에서 접근이 가능하다는 것을 의미하죠.

그렇게 되면 key값을 알고 있다면, 어디서든 변경할 수 있게되고, 이는 보안 문제를 야기할 수 있게 됩니다.

❓해결 방법

일단 전역에서 객체를 최대한 활용하지 않는 것이 중요합니다. 혹은 캡슐화를 통해 객체를 숨기는 것도 방법이겠죠.

하지만 어쩔 수 없이 전역에서 객체를 사용할 수 밖에 없는 상황이라면 어떨까요? 이 상황에서는 Object.freeze() ****메서드를 사용할 수 있습니다.

다음 예시를 보시죠

const myObject = { name: "lurgi" }
Object.freeze(myObject)
myObject.name = "jeong woo" // 속성은 변경되지 않습니다.
myObject = { name : "jeong woo park"} // 작업은 실패합니다.

Object.freeze() 메서드 덕분에 myObject는 보호를 받게 됩니다.

혹은 맨 처음 예시를 고쳐본다면,

export async function readCarsInput () {
    const INPUT = await readInput(CAR_MESSAGES.INPUT);
    validateCarsInput(INPUT);
    return INPUT;
 }

export async handleCarConvertedToClass (cars) {
    const carClasses = cars.map((car) => {
      const carClass = new Car(car);
      return carClass;
    });
    return carClasses;
}

이런식으로 고쳐볼 수 있겠네요! 객체를 만드는 것이 아닌 모듈로 바로 export 해주는 것이죠.

❗결론

전역에서 보호 받아야할 객체를 사용하지 말자!! 굳이 사용해야 한다면 보호해주자!