반응형

이번 강의에서는 C 언어의 핵심 요소 중 하나인 함수에 대해 배워보겠습니다.

이미 우리는 이전 글에서 변수, 자료형, 연산자, 조건문과 반복문에 대해 학습했으며,

이러한 지식을 바탕으로 더 체계적이고 효율적인 프로그램을 작성하는 방법을 배울 것입니다.

C 프로그래밍 언어 독학 시리즈의 전편을 아직 보지 못하신 분들은 아래 링크를 참고해 주세요!

C 언어 독학 #1 (기초, 쉬운 설명, Hello world)

C 언어 독학 시리즈 #2 (변수, 자료형, 연산자, 기본 입출력, 실습예제)

C언어 독학 완전 기초부터 마스터까지 #3 (조건문과 반복문, 조건문과 반복문을 이용한 실습 예제)

1. 함수란 무엇인가?

프로그래밍에서 함수는 특정 작업을 수행하는 코드 블록입니다. 함수는 코드를 재사용 가능하게 하고, 가독성을 높이며, 프로그램의 구조를 더 체계적으로 만듭니다.

C 언어에서 함수는 **입력(매개변수)**을 받아 **출력(반환값)**을 생성하며, 필요한 경우 아무 입력도 받지 않거나 아무 것도 반환하지 않을 수도 있습니다.

함수의 기본 구조

반환형 함수이름(매개변수) {
    // 실행될 코드
    return 반환값;
}

2. 기본 함수 사용해보기

C 언어에는 printf, scanf 같은 표준 라이브러리 함수가 있지만, 사용자 정의 함수를 직접 만들어 사용할 수도 있습니다.

예제: 간단한 덧셈 함수

#include <stdio.h>

// 함수 정의
int add(int a, int b) {
    return a + b; // 두 숫자의 합 반환
}

int main() {
    int x = 5, y = 10;
    int result = add(x, y); // 함수 호출
    printf("결과: %d\n", result);
    return 0;
}

실행 결과
결과: 15

3. 함수의 구성 요소

  1. 반환형(Return Type)
    함수가 반환하는 값의 데이터 타입입니다. 예를 들어, int, void, float 등이 있습니다.
    • int: 정수 반환
    • void: 반환값이 없음
  2. 함수 이름(Function Name)
    함수의 이름은 코드에서 호출될 때 사용됩니다. 변수 이름처럼 의미 있는 이름을 붙이는 것이 좋습니다.
  3. 매개변수(Parameter)
    함수가 입력으로 받을 데이터입니다. 여러 개의 매개변수를 쉼표(,)로 구분할 수 있습니다.
  4. 함수 본문(Body)
    함수가 실행하는 코드 블록입니다.
  5. 반환값(Return Value)
    함수가 작업을 끝내고 호출한 곳으로 돌려주는 값입니다. 반환값이 없을 경우 void를 사용합니다.

4. 함수의 종류

1. 반환값이 있고, 매개변수가 있는 함수

int multiply(int a, int b) {
    return a * b;
}


2. 반환값이 없고, 매개변수가 있는 함수

void printMessage(char message[]) {
    printf("%s\n", message);
}

3. 반환값이 있고, 매개변수가 없는 함수

int getRandomNumber() {
    return 42; // 임의의 숫자 반환
}

4. 반환값도 없고, 매개변수도 없는 함수

void greet() {
    printf("Hello, World!\n");
}

5. 함수 사용 시 주의사항

  • 함수 이름은 고유해야 합니다.
  • 매개변수와 반환값의 타입을 정확히 정의해야 합니다.
  • main 함수는 항상 프로그램의 시작점이며, 반드시 포함되어야 합니다.

6. 실습: 구구단 출력 함수 만들기

문제

사용자 정의 함수를 사용하여 입력받은 숫자의 구구단을 출력하세요.

코드

#include <stdio.h>

// 구구단 출력 함수
void printMultiplicationTable(int n) {
    for (int i = 1; i <= 9; i++) {
        printf("%d x %d = %d\n", n, i, n * i);
    }
}

int main() {
    int number;
    printf("구구단을 출력할 숫자를 입력하세요: ");
    scanf("%d", &number);
    printMultiplicationTable(number); // 함수 호출
    return 0;
}

실행 결과

구구단을 출력할 숫자를 입력하세요: 7
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
...
7 x 9 = 63

이번 강의에서는 C 언어에서 함수를 정의하고 사용하는 방법을 배웠습니다.

다음 강의에서는 **배열(Array)**과 함수의 연계를 통해 더욱 복잡한 프로그램을 작성해 보겠습니다.

지금까지 배운 내용을 활용하여 간단한 프로그램을 작성해 보세요! 독학의 핵심은 직접 실행해 보는 것입니다. 😊


궁금하신 사항은 댓글에 남겨주세요

댓글에 남겨주신 내용

추후 정리해서 올려드리겠습니다

구독 신청하시면 업로드 시 알려드릴게요!

-

조금이라도 도움이 되셨다면

공감&댓글 부탁드리겠습니다

감사합니다!

 

반응형
반응형

로그인 기능은 웹 애플리케이션에서
사용자 인증을 담당하는 중요한 부분입니다.
보안을 강화하지 않으면 사용자의 계정이 탈취되거나
시스템에 무단 접근이 발생할 수 있습니다.
이번 글에서는 안전한 로그인 기능을 구현하기 위해
필수적으로 적용해야 할 보안 설정과
방법을 세세하게 살펴보겠습니다.
 
오늘은 프로그래밍 언어
파이썬(python)을 사용하겠습니다.


1. 비밀번호 보호

1.1 비밀번호 해싱 및 솔팅
비밀번호를 안전하게 저장하기 위해
해싱과 솔팅 기법을 사용합니다.

  • 해싱: 비밀번호를 해시 함수(bcrypt, Argon2 등)를 사용하여 해시된 값으로 변환합니다. 해시는 단방향 함수이므로 원본 비밀번호를 추출할 수 없습니다.
  • 솔팅: 각 비밀번호에 무작위 솔트 값을 추가하여 해시합니다. 동일한 비밀번호라도 솔트가 다르면 해시 값이 달라져서 무차별 대입 공격을 방지할 수 있습니다.
# bcrypt 설치
# pip install bcrypt

import bcrypt

def hash_password(password):
    salt = bcrypt.gensalt()
    hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed_password

def check_password(hashed_password, user_password):
    return bcrypt.checkpw(user_password.encode('utf-8'), hashed_password)

1.2 비밀번호 복잡성 규칙
강력한 비밀번호를 설정하도록 유도합니다.
최소 길이, 대문자, 소문자, 숫자, 특수문자를
포함하는 규칙을 설정합니다.

  • 예시: 최소 8자 이상, 대문자 1자, 소문자 1자, 숫자 1자, 특수문자 1자 포함
import re

def is_password_strong(password):
    if (len(password) < 8 or 
        not re.search(r"[A-Z]", password) or 
        not re.search(r"[a-z]", password) or 
        not re.search(r"\d", password) or 
        not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password)):
        return False
    return True

password = "Example1!"
if is_password_strong(password):
    print("Password is strong.")
else:
    print("Password is weak.")

2. 로그인 시도 제한

2.1 로그인 시도 제한
사용자가 일정 횟수 이상 잘못된 비밀번호를 입력하면
계정을 일시적으로 잠금 처리합니다.

  • 예시: 5회 실패 시 15분 동안 계정을 잠금
from datetime import datetime, timedelta

login_attempts = {}

def record_login_attempt(username, success):
    if username not in login_attempts:
        login_attempts[username] = {'attempts': 0, 'last_attempt': None, 'lock_until': None}
    
    # 계정이 잠겨있는지 확인
    if login_attempts[username]['lock_until'] and datetime.now() < login_attempts[username]['lock_until']:
        return "Account is locked. Try again later."
    
    # 로그인 성공 시 시도 횟수 초기화
    if success:
        login_attempts[username]['attempts'] = 0
    else:
        login_attempts[username]['attempts'] += 1
        login_attempts[username]['last_attempt'] = datetime.now()
        # 5회 실패 시 계정 잠금
        if login_attempts[username]['attempts'] >= 5:
            login_attempts[username]['lock_until'] = datetime.now() + timedelta(minutes=15)
            return "Account is locked due to too many failed attempts."
    
    return "Login attempt recorded."

2.2 캡차(CAPTCHA)
여러 번 로그인 실패 후 캡차를 요구하여 봇에 의한
자동화된 공격을 방지합니다.
캡차는 reCAPTCHA 등 서비스를 이용할 수 있습니다.

<form action="/login" method="post">
    <!-- Other login fields -->
    <div class="g-recaptcha" data-sitekey="your_site_key"></div>
    <button type="submit">Login</button>
</form>
<script src="https://www.google.com/recaptcha/api.js"></script>

3. CSRF(Cross-Site Request Forgery) 토큰

3.1 CSRF 토큰 사용
로그인 폼에 CSRF 토큰을 포함하여,
서버가 해당 요청이 신뢰할 수 있는 출처에서 왔는지
확인합니다.
이를 통해 CSRF 공격을 방지할 수 있습니다.

from flask import Flask, request, session, render_template_string
import os

app = Flask(__name__)
app.secret_key = os.urandom(24)

def generate_csrf_token():
    if 'csrf_token' not in session:
        session['csrf_token'] = os.urandom(24).hex()
    return session['csrf_token']

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        token = request.form.get('csrf_token')
        if not token or token != session['csrf_token']:
            return "CSRF token mismatch", 400
        # Process login
    return render_template_string("""
        <form method="POST">
            <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
            <!-- Other login fields -->
            <button type="submit">Login</button>
        </form>
    """, csrf_token=generate_csrf_token())

4. 2단계 인증(Two-Factor Authentication, 2FA)

4.1 2단계 인증 도입
비밀번호 외에도 추가 인증 요소를 요구합니다.
예를 들어, SMS, 이메일로 전송된 인증 코드,
인증 앱(Google Authenticator 등)을 사용한 코드를 입력하도록 요구할 수 있습니다.

import random

def send_otp_via_sms(phone_number):
    otp = random.randint(100000, 999999)
    # Code to send SMS
    return otp

def verify_otp(user_input, actual_otp):
    return user_input == actual_otp

# 예시 사용법
otp = send_otp_via_sms("+1234567890")
user_input = input("Enter the OTP sent to your phone: ")
if verify_otp(user_input, otp):
    print("OTP verified successfully.")
else:
    print("Invalid OTP.")

5. 세션 관리

5.1 세션 타임아웃
일정 시간 동안 사용자의 활동이 없으면
자동으로 로그아웃 시킵니다.

from flask import Flask, session
from datetime import timedelta

app = Flask(__name__)
app.secret_key = os.urandom(24)

@app.before_request
def make_session_permanent():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=30)

5.2 세션 고정 공격 방지

로그인 시 새로운 세션 ID를 할당하여 세션 고정 공격을 방지합니다. 

from flask import Flask, session

app = Flask(__name__)
app.secret_key = os.urandom(24)

@app.route('/login', methods=['POST'])
def login():
    # Authenticate user
    user = authenticate_user() # 가정한 함수
    if user:
        session.clear()
        session['user_id'] = user.id
        return "Login successful"
    return "Invalid credentials"

6. SSL/TLS를 통한 데이터 암호화

6.1 SSL/TLS 사용
로그인 페이지 및 API 통신에 SSL/TLS를 사용하여 전송되는 데이터를 암호화합니다.
이를 통해 중간자 공격(MITM)을 방지할 수 있습니다.

  • SSL 인증서를 설치하고 HTTPS를 적용합니다.
server {
    listen 443 ssl;
    server_name your_domain.com;

    ssl_certificate /path/to/your_certificate.crt;
    ssl_certificate_key /path/to/your_private.key;

    location / {
        proxy_pass http://localhost:5000;
        # Other configurations
    }
}

7. 계정 잠금 및 경고

7.1 계정 잠금
여러 번 로그인 실패 시 계정을 잠그고,
사용자가 등록한 이메일로 경고 메시지를 보냅니다.

def send_account_lock_email(user_email):
    # Code to send email
    pass

def lock_account(username):
    # Lock account logic
    send_account_lock_email(username)

7.2 로그인 알림
새로운 디바이스나 IP 주소에서 로그인 시 사용자가 알림을 받도록 설정할 수 있습니다.

def send_new_login_alert(user_email, ip_address):
    # Code to send email alert
    pass

8. 입력 데이터 유효성 검사

8.1 입력 데이터 검증
모든 사용자 입력 데이터에 대해 유효성 검사를 수행하여 SQL 인젝션, XSS 등의 공격을 방지합니다.

from flask import escape

@app.route('/login', methods=['POST'])
def login():
    username = escape(request.form.get('username'))
    password = escape(request.form.get('password'))
    # Process login

9. 보안 감사 및 로그

9.1 보안 로그
로그인 시도, 실패, 비밀번호 변경 등의 보안 관련 이벤트를 로깅하여 나중에 분석할 수 있도록 합니다.

import logging

logging.basicConfig(filename='security.log', level=logging.INFO)

def log_security_event(event):
    logging.info(event)

# 예시 사용법
log_security_event("User login attempt")

9.2 감사 로그
의심스러운 활동을 감지하고 대응할 수 있도록 보안 감사 로그를 유지합니다.

def log_suspicious_activity(user_id, activity):
    logging.warning(f"Suspicious activity detected for user {user_id}: {activity}")

# 예시 사용법
log_suspicious_activity(123, "Multiple failed login attempts")

오늘은 안전한 로그인 기능을 위한 보안 설정을 알아봤습니다.
오늘 설정한 내용 아래에서 한번 더 볼까요?

  1. 비밀번호 보호: 비밀번호를 해시 함수와 솔트를 사용하여 안전하게 저장하고, 비밀번호 복잡성 규칙을 설정하여 강력한 비밀번호를 요구합니다.
  2. 로그인 시도 제한: 일정 횟수 이상 잘못된 비밀번호 입력 시 계정을 잠금 처리하고, 봇 공격을 방지하기 위해 캡차(CAPTCHA)를 도입합니다.
  3. CSRF 토큰 사용: CSRF 토큰을 로그인 폼에 포함시켜 CSRF 공격을 방지합니다.
  4. 2단계 인증(2FA): 비밀번호 외에도 SMS, 이메일, 인증 앱을 통한 추가 인증 요소를 요구하여 보안을 강화합니다.
  5. 세션 관리: 세션 타임아웃 설정과 세션 고정 공격 방지 등을 통해 세션을 안전하게 관리합니다.
  6. SSL/TLS를 통한 데이터 암호화: SSL/TLS를 사용하여 전송되는 데이터를 암호화하여 중간자 공격(MITM)을 방지합니다.
  7. 계정 잠금 및 경고: 여러 번 로그인 실패 시 계정을 잠그고, 이메일로 경고 메시지를 발송하며, 새로운 디바이스나 IP 주소에서 로그인 시 알림을 보냅니다.
  8. 입력 데이터 유효성 검사: 모든 사용자 입력 데이터에 대해 유효성 검사를 수행하여 SQL 인젝션, XSS 등의 공격을 방지합니다.
  9. 보안 감사 및 로그: 로그인 시도, 실패, 비밀번호 변경 등의 보안 관련 이벤트를 로깅하고, 의심스러운 활동을 감지하여 대응합니다.

이러한 보안 설정을 통해 로그인 기능의 보안을 강화하고,
사용자 계정 및 시스템을 보다 안전하게 보호할 수 있습니다.
최신 보안 권고사항을 참고하고,
자동화된 보안 도구를 적극 활용하여 시스템의 안전성을 높여주세요
 
보안은 한 번에 완성되는 것이 아니라 지속적으로 관리하고 업데이트해야 하는 부분입니다.
따라서 정기적인 보안 점검과 최신 보안 패치 적용을 통해 안전한 웹 애플리케이션을 유지하시기 바랍니다.
이 글이 안전한 로그인 기능을 구현하는 데 도움이 되었기를 바랍니다.
추가적인 질문이나 도움이 필요하다면 언제든지 댓글로 남겨주세요.
감사합니다!


궁금하신 사항은 댓글에 남겨주세요

댓글에 남겨주신 내용

추후 정리해서 올려드리겠습니다

구독 신청하시면 업로드 시 알려드릴게요!

-

조금이라도 도움이 되셨다면

공감&댓글 부탁드리겠습니다

감사합니다!

반응형
반응형

최근 소프트웨어 개발 도구의 보안에 대한 관심이 증가하고 있습니다.

특히, 오픈소스 컴포넌트를 사용하는 도구들이 많아지면서

이러한 컴포넌트들에서 발견되는 취약점에 대한 우려도 함께 커지고 있습니다.

 

이 글은 유명한 코드 에디터의 오픈소스 컴포넌트에서 발견된 취약점에 대해 이야기합니다.

이 코드 에디터는 전 세계 개발자들 사이에서 널리 사용되고 있으며,

특히 그중 하나의 컴포넌트가 포함하고 있는 오래된 브라우저의 버전에서 발견된

여러 보안 취약점이 아직까지 해결되지 않은 채 업데이트되고 있습니다.

러한 취약점들은 실제 공격에서 이미 이용된 바 있으며,

이를 통해 원격 코드 실행, 정보 유출, 서비스 거부 등 다양한 보안 위협이 가능해집니다.

이는 사용자의 시스템 보안을 심각하게 위협할 수 있습니다.

 

처음 확인이 된 (글쓴이는 해당 버전에서 처음 식별했습니다.) 1.85.2 버전부터

2024년 4월 4일 현재 사이트에서 배포 중인 1.87.2 버전에 이르기까지,

exten****. js 파일에 포함된 Fire*** 71.0 오픈소스 컴포넌트에서

5 가지 치명적인 오픈소스 취약점이 여전히 해결되지 않은 채 업데이트되고 있습니다.

 

5가지의 취약점 코드와 내용은 아래와 같으며,

CISA가 관리하는 알려진 이용된 취약점(KEV) 카탈로그에서 발췌하였습니다.

 

KEV는 미국 CiSA가 실제 공격에서 이용된 취약점들을 나열한 권위 있는 자료입니다.

이 카탈로그는 조직들이 취약점 관리를 우선순위에 두고 사이버 보안 조치를 강화하는 데 중요한 입력 정보를 제공합니다.

자세한 정보는 CISA 공식 웹사이트에서 확인할 수 있습니다​ (CISA)​.

https://www.cisa.gov/known-exploited-vulnerabilities-catalog

 

Known Exploited Vulnerabilities Catalog | CISA

For the benefit of the cybersecurity community and network defenders—and to help every organization better manage vulnerabilities and keep pace with threat activity—CISA maintains the authoritative source of vulnerabilities that have been exploited in

www.cisa.gov

CVE-2022-26486 2022년 3월 7일 웹GPU IPC 프레임워크에서 예기치 않은 메시지로 인해 발생하는 사용 후 해제(use-after-free) 취약점. 원격 공격자가 샌드박스 탈출을 시도할 수 있음.
CVE-2022-26485 2022년 3월 7일 웹GPU IPC 프레임워크에서 비정상적인 메시지 처리로 인한 사용 후 해제(use-after-free) 취약점. 원격 코드 실행 가능성을 내포함.
CVE-2020-6820 - 메모리 안전성 문제로 인해 발생할 수 있는 취약점. 악의적인 웹 페이지를 통해 사용자 시스템에서 임의 코드 실행을 시도할 수 있음.
CVE-20206819 - CVE-2020-6819는 특정 조건 하에서 nsDocShell destructor 실행 중 경쟁 상태로 인해 사용 후 해제(use-after-free)가 발생할 수 있는 취약점입니다. 이는 Thunderbird, Firefox, 및 Firefox ESR의 특정 버전에 영향을 미칩니다. 이 취약점은 실제 공격에서 이용되었습니다.
CVE-2019-17026 - IonMonkey JIT 컴파일러의 타입 혼동 취약점. 악의적인 JavaScript 실행을 통한 임의 코드 실행이 가능.

 

자세한 취약점에 대한 정보는 아래 링크를 통해 확인해 주세요

https://nvd.nist.gov/vuln

 

NVD - Vulnerabilities

All vulnerabilities in the NVD have been assigned a CVE identifier and thus, abide by the definition below. CVE defines a vulnerability as: "A weakness in the computational logic (e.g., code) found in software and hardware components that, when exploited,

nvd.nist.gov

 

해당 취약점 5가지는 코드 에디터에 포함된 exten****. js 파일에

오픈소스 컴포넌트인 Fire*** 71.0에 포함되어 있으며,

이미 해커에게 공격당하여 빠르게 패치를 하라고 권고한 취약점입니다.

 

아래는 exten****. js 파일이 해당 코드 에디터에서 어떤 역할을 하는지 인공지능 챗 지피티에게 문의해 봤습니다.

 

추가적으로 ChatGPT는 해당 이슈에 대해 이렇게 이야기하고 있습니다.

해당 컴포넌트에서 발견된 취약점을 통해 공격자는 원격 코드 실행, 정보 유출, 서비스 거부(DoS) 공격 등 다양한 위협을 가할 수 있습니다. 이는 사용자 시스템의 보안을 심각하게 위협하며, 공격자에게 시스템 제어권을 부여할 수도 있습니다.

 

현재 제 주변에 있는 모든 개발자가 해당 소프트웨어를 사용 중에 있습니다.

이는 엄청난 취약점이며, 고쳐져야 하는 사안으로

제 지인에게는 다른 개발 도구를 추천드리고 있습니다.

 

소프트웨어의 보안은 그 어느 때보다 중요하며,

특히 오픈소스 컴포넌트의 취약점은 개발자와 사용자 모두에게 심각한 위협이 될 수 있습니다.

오픈소스 컴포넌트의 취약점을 주의 깊게 관리하는 것은 소프트웨어 개발의 중요한 부분입니다.

주변 친구들이 해당 소프트웨어를 사용 중이라면 해당 내용을 공유해 주시길 바랍니다.

사용 중인 도구들이 최신 상태로 유지되고 보안 위협으로부터 보호되도록,

적극적으로 패치 적용과 보안 권장 사항을 따르는 것이 필수적입니다.

이런 실천을 통해 우리는 더 안전한 디지털 환경을 조성할 수 있습니다.

 

해당 이슈에 대해서는 고객센터 팀에게 위와 같이 메일을 보내 놓은 상태입니다.


궁금하신 사항은 댓글에 남겨주세요

댓글에 남겨주신 내용

추후 정리해서 올려드리겠습니다

구독 신청하시면 업로드 시 알려드릴게요!

-

조금이라도 도움이 되셨다면

공감&댓글 부탁드리겠습니다

감사합니다!

 

반응형

+ Recent posts