[Upstage AI Lab] Streamlit 활용해보기

라을·2025년 1월 14일

Upstage AI Lab

목록 보기
26/28
post-thumbnail

Streamlit이란?

(출처 : https://llm-examples.streamlit.app)

streamlit은 오픈 소스 애플리케이션 프레임워크로, 몇 줄의 코드만으로 상호 작용이 가능한 데이터 애플리케이션을 만들 수 있게 해준다. 데모용으로 사용하기에 딱 적합하지 않을까 싶다!

이번 프로젝트도 데모를 보여주면 되는 것이기 때문에 streamlit을 선택하게 되었다.


설치 과정

streamlit에서 계정을 만든 다음에

pip install streamlit
streamlit hello

을 하면 ID를 입력하도록 되어있을 것...

파일을 만들어놨으면~

streamlit run 파일명.py

를 통해 실행시키면 결과가 웹페이지로 나타날 것이다 (개편리)


구현

🔻 전체 코드

import streamlit as st

def main():
    st.set_page_config(page_title="Bug Bounty Program", layout="wide")

    st.title("Find the GAP Bug Bounty Program Project 1")

    st.markdown("""
    프로그램 설명과 가이드에 기반해서 리포트를 작성해야 합니다. 상세정보 보기를 통해 프로그램 상세정보를 확인할 수 있습니다.
    """)
    st.markdown("")

    #리포트 제목
    report_title = st.text_input("리포트 제목", placeholder="제목을 입력하세요.")
    st.markdown("<div style='margin:20px 0;'></div>", unsafe_allow_html=True)


    # Discovery Location
    discovery_location = st.text_area("발견 위치", placeholder="URI / URL / Location (or Address)")
    st.markdown("")

    # Scope
    scope = st.selectbox("범위", ["선택", "해당 자원 이상", "해당 자원 한정"])
    st.markdown("")

    # Attack Point and Payload
    col1, col2 = st.columns(2)
    with col1:
        attack_point = st.text_area("Attack Point", placeholder="취약한 변수명 값이 없을 시 none 입력")
    with col2:
        payload = st.text_area("Payload", placeholder="payload(공격에 사용된 코드) 값이 없을 시 none 입력")

    st.markdown("")

    # Attack Type
    attack_type = st.selectbox("공격유형", ["선택", "SQL Injection", "XSS", "CSRF", "기타"])
    st.markdown("")

    # Attack Impact
    attack_impact = st.selectbox("공격영향", ["선택", "정보 유출", "시스템 장애", "데이터 손실", "기타"])
    st.markdown("")

    # Ethical Hacking Self-Assessment
    st.subheader("윤리적 해커 자체 평가")

    col1, col2, col3 = st.columns(3)
    with col1:
        access_method = st.multiselect("공격자의 접근 방법", ["네트워크", "제한된 네트워크", "로컬", "물리"])
        attack_complexity = st.radio("공격 복잡도", ["특정 정보 조건 필요", "특정 정보/조건 불필요"])
        required_privileges = st.radio("필요한 권한", ["없음", "일반 사용자", "상위권한(관리자)"])
    with col2:
        scope_option = st.radio("범위", ["해당 자원 이상", "해당 자원 한정"])
        confidentiality = st.radio("기밀성", ["높음", "낮음", "없음"])
        integrity = st.radio("무결성", ["높음", "낮음", "없음"])
    with col3:
        user_interaction = st.radio("사용자 상호 작용", ["없음", "필요 (메일열람, 페이지접근, 실행 등)"])
        availability = st.radio("가용성", ["높음", "낮음", "없음"])

    # CSS 스타일 추가 - vulnerability_details에만 적용
    st.markdown("""
        <style>
            /* vulnerability-details 클래스를 가진 요소의 textarea에만 적용 */
            .vulnerability-details textarea {
                min-height: 500px !important;
            }
        </style>
    """, unsafe_allow_html=True)

    vulnerability_overview = st.text_area(
        "취약점 개요",
        placeholder="취약점 요약, 취약한 SW 버전, 취약점 발생 환경"
    )

    placeholder_text = """취약점 신고자는 다음 작성 방법을 준수하여 각 항목을 작성해야 하며, 내용이 불충분하다고 판단되는 경우 보완 작성을 요청드릴 수 있습니다.

> 취약점 발견 방법(점검도구 등): 취약점 발견방법에 대한 내용을 기술

> 취약점 발생 원인:
  - 취약점 발생 입력 데이터 설명 (문자열, 이미지 등의 파일)
  - 취약점 발생 위치 설명 (함수, 어셈블리코드, 프로그램 주소 위치 등)
  - 취약점 발생 원인 설명 (소스코드 분석, 리버싱 결과 등으로 취약점 발생 원인을 파악한 내용 기술)

> 취약점 증명 / 검증
  1. 취약점에 대한 상세 분석 결과 기술 [단계별로 기술]
    - 취약점 분석 결과 스크린 샷 및 설명
    - PoC 디버깅 과정 설명
    - 보호기법 우회 기술
    - 취약점 발생 동영상 첨부 등

> 취약점 악용 시나리오: 취약점이 악용될 수 있는 공격 시나리오와 관련 서비스 (또는 시스템)에 미칠 수 있는 영향

> 기타:
  - 참고할 수 있는 자료 (웹사이트 주소 등)
  - 발견한 취약점을 악용하고 있는 사례 설명"""

    # height 파라미터 직접 사용
    vulnerability_details = st.text_area(
        "취약점 상세 설명",
        placeholder=placeholder_text,
        height=500  # 픽셀 단위로 높이 지정
    )

    mitigation = st.text_area(
        "조치방안",
        placeholder="취약점을 해결할 수 있는 효과적인 방법을 제시해주세요."
    )

    # File Attachment
    st.subheader("파일첨부")
    st.file_uploader("첨부파일은 임시저장되지 않습니다. 최종 제출시에만 첨부파일을 추가해주세요.", type=["png", "jpg", "jpeg", "zip"], accept_multiple_files=True)
    st.markdown("")

    # Agreement
    st.subheader("취약점 정보 활용 및 비밀 유지 동의")
    agreement = st.checkbox("취약점 정보 활용 및 비밀유지에 동의합니다.")

    # Submission
    if st.button("제출하기"):
        if agreement:
            st.success("리포트가 성공적으로 제출되었습니다.")
        else:
            st.error("취약점 정보 활용 및 비밀유지에 동의해야 제출이 가능합니다.")

if __name__ == "__main__":
    main()

🔻 ELEMENTS

개인적으로 streamlit의 css를 적용시키는게 뭔가 직관적이지도 않고, 구현을 해도 적용이 잘 안되는 것들이 많아 좀 답답한 마음이 들었다...

우선 text-size를 키우려고 markdown을 사용하지 않고 css로만 구현을 해보려고 했으나 다 먹히지 않아 실패. markdown을 사용하면 위아래 공백이 생겨서 원하는 스타일대로 페이지 구현이 되지 않아 css로 적용해보려고 한건데~ 왜! 안되는 것이야! (기필코 해낸다)

아래는 내가 streamlit을 처음 사용해보면서 알게 된 내용을 정리해 보았다.


기본 layout

  • set_page_config
    • 페이지 설정을 위한 초기화 작업으로, 페이지 제목, 레이아웃 등을 정의한다
    • ex : st.set_page_config(page_title="Page Title", layout="wide")

  • column
    • 페이지를 열 단위로 나누어 구성할 때 사용
    • st.columns을 사용하여 다양한 컴포넌트를 균등 분배할 수 있다
    • ex : col1, col2 = st.columns(2) with col1: ~ with col2: ~

입력 받기

  • text_input
    • 한 줄 텍스트 입력을 받을 때 사용
    • user_input = st.text_input("제목", placeholder = "제목을 입력하세요."
    • placeholder는 default로 적히길 바라는 내용을 입력하는 것!

  • text_area
    • 여러 줄 텍스트 입력을 받을 때 사용
    • long_input = st.text_area("설명", placeholder= "내용을 입력하세요.")

  • selectbox
    • 여러 선택 옵션을 제공할 때 사용
    • multiselect을 사용해도 좋다
    • option = st.selectbox("옵션 선택", ["옵션1, "옵션2", "옵션3"])

  • checkbox
    • 단일 선택 옵션을 제공할 때 사용
    • agreement = st.checkbox("약관에 동의합니다.")

text type

  • title : 페이지의 메인 타이틀 설정
  • markdown : 텍스트 형식의 콘텐츠 추가. HTML 스타일링 지원
  • subheader : 페이지 내 섹션을 구분하기 위해 제목

기타

  • file_uploader
    - 파일 업로드 기능
    - <code>uploaded_files = st.file_uploader("파일 업로드", type=["png", "jpg", "zip"], accept_multiple_files=True)
  • button
  • success & error
profile
욕심 많은 공대생

0개의 댓글