현재 사용자 작업에 대한 논리적 보안

여보세요! 근황은 어떤가요!?

현재 사용자 정보에 기반한 논리적 보안 관련 작업을 하고 있습니다. 예를 들어, if this topic.creator.username to be equals to User.current().username 조건을 만족하면 사용자가 주제를 편집하거나 제외할 수 있도록 허용하는 방식이죠.

즉, 핵심은 사용자 세션에 기반한 특정 작업을 보장하는 것입니다. 그런데 몇 가지 테스트를 해보았고, 그래서 지금 여러분에게 질문을 드리게 되었습니다.

웹 브라우저의 JavaScript를 통해(프로덕션 모드에서도) Discourse.User.current().set('username', 'sometestename')을 실행할 수 있습니다. 이렇게 하면 제 시스템에서 특정 작업이 활성화될 수 있습니다. 이것이 99%의 사용자의 의도는 아닐 수 있지만, 이 경우를 넘어 사용자가 사용자 정보를 조작하지 못하도록 하는 방법이 있는지 아시는 분이 있을까요?

감사합니다.
Felipe

로컬 브라우저에서 정보를 변경하더라도 백엔드에서는 아무것도 변경되지 않습니다.

사용자는 인증 토큰을 통해 로그인되는 것으로 생각되므로, 백엔드에서 다른 사용자로 위장할 수 없습니다:

서버를 속일 수 없으므로, 다른 사용자로서 변경 사항을 수행할 수 없습니다.

브라우저를 새로고침하는 즉시 로컬 변경 사항은 아마도 삭제될 것입니다. 최악의 경우, 자바스크립트 앱 상태를 망가뜨려 캐시를 삭제해야 할 수도 있습니다.

요! 맞아요!

말씀하신 대로 가장 좋은 방법은 백엔드 서버에서 항상 현재 사용자 세션을 가져오는 것입니다.

이렇게 하면 브라우저의 캐시 변경이 영향을 미치지 못합니다. 로직적 보안이 PreloadStore가 아닌 백엔드 서버의 사용자 세션에 기반하고 있는지 확인할 수 있는 자료가 어딘가에 있는지 아시나요?

잘못된 방향으로 가고 있다면 알려주세요! 도움 주셔서 감사합니다, Robert님!

감사합니다,
Felipe

저는 보안 전문가가 아니라 그냥 앱 개발자일 뿐이지만, 모든 영속적 변경은 서버에서만 수행할 수 있습니다. EmberJS에서 브라우저에서 일어나는 일은 사용자의 편의성과 뛰어난 사용성 경험을 위한 것이지요. 예를 들어, 속도를 위한 캐싱이나 자동으로 앱처럼 동작하는 인터페이스 같은 것들이요. 결국 모든 영속적 변경은 Rails 서버와 협상해야 한다는 사실은 변하지 않으며, 이 과정에서 로그인된 사용자에 대해서만 권한이 부여됩니다.

모든 데이터 검색도 마찬가지입니다. Rails 서버는 로그인된 사용자에게 공개된 데이터만 전송할 뿐이죠.

이 부분에 대해 걱정할 필요 없다고 생각합니다. 누군가 이를 우회하려고 시도한다면 첫 번째 단계에서 막히기 때문입니다. API를 속이는 방법은 없으니까요.

혹시 어떤 점이 걱정되시나요?

특정 사용자가 주제 작성자인지, 게시물 작성자인지에 따라 해당 동작이 사용 가능할지 여부가 달라지는 몇 가지 접근 방식을 구현 중이라, 백엔드 사용자 세션 기반으로 유효성 검사를 해야 하는 상황입니다.

예를 들어, 게시물 작성자인 경우 해당 게시물을 수정할 수 있도록 하는 방식이죠.

수정: Discourse의 게시물 권한 설정처럼 확인하겠습니다.

감사합니다, Felipe

먼저 백엔드에서 모든 보안 조치를 개발해야 합니다.

Rails 시리얼라이저(serailizers)는 어떤 데이터가 전송되는지를 결정합니다.

Guardian은 어떤 작업이 허용되는지를 보호합니다.

이 모든 것은 Rails 컨트롤러에 의해 관리됩니다.

프론트엔드가 어떤 불필요한 데이터를 보내거나 무엇을 요청하든 상관없습니다. 이러한 요소들이 서버를 보호하기 때문입니다.

프론트엔드 동작에서도 이를 반영할 수 있지만, 프론트엔드는 게이트키퍼가 아닙니다.

몇몇 대규모 플러그인을 살펴보면 시리얼라이저와 Guardian 사용의 예시를 볼 수 있습니다.

로버트 씨, 감사합니다! 이 피드백이 정말 필요했어요!

반드시 확인해 보겠습니다!

감사합니다,

요, 로버트!

포스트 제어(액션) 관련 플러그인 코드와 코드베이스를 분석해 왔습니다. 보안 측면에서 제가 가장 많이 개선할 수 있는 부분을 확인하기 위해서였죠.

분석 결과! 프론트엔드에서는 사용자가 포스트를 편집할 수 있는지 여부를 확인하는 몇 가지 단계가 있습니다. 예를 들어:

  • 1단계: SiteSetting.post_menu_hidden_items
  • 2단계: attrs.canEdit
  • 3단계: editPost() - !post.can_edit - controllers/topic

하지만 프론트엔드에서 조작되더라도 posts_controller.rb의 백엔드 서버로 한 번만 전송되면, Rails가 최종 확인을 위해 포스트를 다시 요청합니다:

  • !guardian.public_send(“can_edit?”, post)
  • guardian.ensure_can_edit!(post)
  • PostRevisor

귀한 통찰을 공유해 주셔서 감사합니다!
정말 훌륭합니다.

잘했어요. 포기하지 않고 더 깊이 파고든 점이 정말 마음에 들어요 :+1:t2: