본문 바로가기
프로젝트/구글개인정보노출점검 프로그램

파이썬을 활용한 구글 개인정보노출점검 프로그램 제작(1)

by AFD 2024. 6. 3.

제작 전 업무 처리 프로세스

 

현재 보안관련된 회사에 재직중이여서, 회사 정기업무 중 회사에서 관리하는 홈페이지 내의 개인정보 노출건이 있는지 구글검색으로 찾아내는 업무가 있다.

 

구글 고급 검색식을 이용하여 찾아내는데 우리 회사가 관리하는 홈페이지 갯수만 해도 250개가 넘기 때문이 이를 일일히 구글에 검색하는것은 아주 비효율적이고 시간적인 면에서 손실이 많다.

구글 고급 검색식을 이용한 개인정보 노출 검색법
브라우저를 이용한 다중 검색 시 구글 보안정책인 캡챠가 실행됨.

 

또한 결과를 수기로 찾아야 하기 때문에 점검자가 놓치는 부분이 있다. 이를 방지하기 위해 파이썬을 이용해 구글개인정보노출점검 프로그램을 만들고자 한다. 해당 프로그램 작성을 위해 필요로 하는 구현 기능을 정리하면 아래와 같다.

 

외부 구현기능

  • 파이썬의 Tkinter를 이용한 GUI 기반 프로그램 작성
  • pandas를 이용, 홈페이지 정보가 들어있는 엑셀파일 로드 기능 구현
  • json을 이용하여 생성된 python 객체를 json 형식으로 변환, 저장 및 데이터 로드 기능 구현

내부 구현기능

  • 검색 결과를 데이터화 하기 위해 Google Custom Search API 사용
  • 로지스틱 회귀(Logistic Regression) 알고리즘을 이용, 검색 결과로 나온 텍스트 데이터의 정,오탐률 판별

Main.py [기본 UI 구축]

 

import tkinter as tk # GUI 어플리케이션 구축을 위한 tkinter 라이브러리
from tkinter import ttk, filedialog, messagebox, simpledialog
import pandas as pd # 엑셀 로드를 위한 pandas 라이브러리
import webbrowser # 어플리케이션 내에서 웹브라우저 로드를 위한 모듈
import requests # http 웹사이트 요청을 위한 requests 모듈
from data_manager import DataManager
from classifier import Classifier

class SiteManager:
    def __init__(self, root):
        self.root = root # 객체 생성
        self.root.title("기가응지v3")

        self.top_frame = tk.Frame(root) # 프레임 생성
        self.top_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)

        self.load_button = tk.Button(self.top_frame, text="Load Excel", command=self.load_excel)
        self.load_button.pack(side=tk.LEFT, padx=5, pady=5) # 엑셀 로드버튼 생성

        self.save_button = tk.Button(self.top_frame, text="Save Data", command=self.save_data)
        self.save_button.pack(side=tk.LEFT, padx=5, pady=5) # 데이터 세이브 버튼 생성
 
        self.search_button = tk.Button(self.top_frame, text="Search", command=self.perform_search)
        self.search_button.pack(side=tk.RIGHT, padx=5, pady=5) # 검색 버튼 생성

        self.paned_window = ttk.PanedWindow(root, orient=tk.HORIZONTAL)
        self.paned_window.pack(fill=tk.BOTH, expand=True)

        self.tree_frame = tk.Frame(self.paned_window)
        self.results_frame = tk.Frame(self.paned_window)

        self.paned_window.add(self.tree_frame, weight=1)
        self.paned_window.add(self.results_frame, weight=3)

        self.tree = ttk.Treeview(self.tree_frame, columns=("URL"), show='tree') # 검색결과 url 표기하는 트리뷰 생성
        self.tree.heading("#0", text="Name")
        self.tree.heading("URL", text="URL")
        self.tree.column("#0", width=200, anchor="w")
        self.tree.column("URL", width=300, anchor="w")
        self.tree.pack(fill=tk.BOTH, expand=True)

        self.tree_scrollbar = ttk.Scrollbar(self.tree_frame, orient="vertical", command=self.tree.yview) # 스크롤바 생성
        self.tree.configure(yscrollcommand=self.tree_scrollbar.set)
        self.tree_scrollbar.pack(side="right", fill="y")

        self.tree.bind("<Button-3>", self.show_context_menu)

        self.context_menu = tk.Menu(self.tree, tearoff=0)  # 컨텍스트 메뉴 생성
        self.context_menu.add_command(label="Add", command=self.add_item)
        self.context_menu.add_command(label="Edit", command=self.edit_item)
        self.context_menu.add_command(label="Delete", command=self.delete_item)
        self.context_menu.add_command(label="Add URL", command=self.add_url)

        self.results_canvas = tk.Canvas(self.results_frame) # 검색결과창 프레임 생성
        self.results_scrollbar = ttk.Scrollbar(self.results_frame, orient="vertical", command=self.results_canvas.yview)
        self.results_container = ttk.Frame(self.results_canvas)

        self.results_container.bind(
            "<Configure>",
            lambda e: self.results_canvas.configure(
                scrollregion=self.results_canvas.bbox("all")
            )
        )

        self.results_canvas.create_window((0, 0), window=self.results_container, anchor="nw")
        self.results_canvas.configure(yscrollcommand=self.results_scrollbar.set)

        self.results_canvas.pack(side="left", fill="both", expand=True)
        self.results_scrollbar.pack(side="right", fill="y")

        self.results_container.bind_all("<MouseWheel>", self._on_mousewheel) # 마우스 휠 스크롤 이벤트 연결

        self.search_patterns = [ # 검색 패턴 목록 초기화
            "(주민등록|주민번호)",
            "(이력서|소개서)",
            "(면허증|자격증|등록증|계약서)",
            "01(0|1|6|7|8|9)-0..9999-0..9999"  
        ]

        self.data_manager.load_saved_data(self.tree) # 저장된 데이터 트리뷰에 로드

 

이어서 엑셀을 로드하는 함수도 작성

 def load_excel(self):
        file_path = filedialog.askopenfilename()
        if file_path:
            df = pd.read_excel(file_path)
            df = df.ffill()  #비어있는 값을 앞선 값으로 채움
            self.populate_tree_from_df(df)

 

해당 코드를 기반으로 그래픽 프레임과 UI 설정 후 실행화면

실행 결과
엑셀을 로드 했을때 엑셀 서식에 맞게 트리 구조로 UI 표시