반응형

배경

계절학기에 들어가면서 1학점 짜리 웹 프로젝트 연구를 진행하게 되었다. 주제는 웹 보안을 위한 시큐어 코딩 학습 사이트다.

3주 동안 진행되는 계절학기 특성상 미리 준비하는게 정신건강에 좋기 때문에 미리 웹사이트를 구축해보기로 했다.

 

새로운 기술

우선, 평소에는 react, nodejs 로 웹을 구축했었는데 이번에는 nextjs 를 이용해 구축해보려고 한다. 새로운 기술에 대해 배우는고 공부하는데 도움이 될 것 같아 이렇게 진행하려고 한다.

 

취약점 조사

프로젝트에는 웹보안 하면 가장 기초가되는 4가지 공격을 제외한 공격을 다루라고 명시되어 있다. (sql injection, XSS, path traversal, desdrialization)

사실 내가 생각해도 위의 공격은 너무 소스도 많고 기본적인 문제들이라 날로 먹는 느낌이 들 것 같긴했다.

그렇기에 새로운 취약점을 찾아보았고, OWASP 에서 발표한 TOP10 취약점을 알게 되었다.

 

 

여기서 나는 1번 injection, 8번 CSRF 에 대해 진행해보려고 한다. injection 에도 file upload, os command 를 이용한 취약점에 집중하려고 한다.

 

웹 구현

 

next 프로젝트를 구축한 후 app 폴더의 트리 모습이다. layout.js 를 이용해 헤더와 네비게이션을 고정해놓고 page를 바꾸어가며 출력할 예정이다.

 

app
│ favicon.ico
│ globals.css
│ layout.js
│ page.js

├─components
│ Header.js
│ Nav.js

├─csrf
│ page.js

├─file
│ page.js

├─list
│ page.js

└─os

 

헤더와 네비게이션을 고정하기 위해 다음과 같은 코드를 작성했다.

 

layout.js

import Link from "next/link";
import "./globals.css";
import { Inter } from "next/font/google";
import Nav from "./components/Nav";
import Header from "./components/Header";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Header/>
        <Nav />
        {children}
      </body>
    </html>
  );
}

Header.js

'use client';
const { default: Link } = require("next/link");

const Header = () =>{
  const toggleDropdown = () => {
    setDropdownVisible(!isDropdownVisible);
  };
    return(
        <div className="header">
            <h3>Secure Coding Lecture</h3>
        </div>
    )
}

export default Header;

Nav.js

'use client';
import { useState } from "react";
const { default: Link } = require("next/link");

const Nav = () =>{
    const [isDropdownVisible, setDropdownVisible] = useState(false);

  const toggleDropdown = () => {
    setDropdownVisible(!isDropdownVisible);
  };
    return(
        <nav className="navbar">
          <ul className="navList">
            <li className="navItem">
              <Link href="/">홈</Link>
            </li>
            <li className="navItem">
              <div onClick={toggleDropdown}>강의
              {isDropdownVisible && (
                <ul className="subNavList">
                  <li className="navItem">
                    <Link href="/file">File Upload Attack</Link>
                  </li>
                  <li className="navItem">
                    <Link href="/os">OS Command Injection</Link>
                  </li>
                  <li className="navItem">
                    <Link href="/csrf">CSRF</Link>
                  </li>
                </ul>
              )}
              </div>
            </li>
            <li className="navItem">
              <Link href="/">설정</Link>
            </li>
          </ul>
        </nav>
    )
}

export default Nav;

위의 코드를 이용하면 다음과 같은 웹이 출력된다.

 

 

 

어려웠던점

  1. Layout.js 내에서 useState 사용불가
    • 이건 내가 next 에 대해 제대로 몰라 생겼던 문제다. next 는 기본적으로 서버 컴포넌트로 작동하는데 useState 는 클라이언트에서만 사용되기에 오류가 발생한다.
    • 따라서, use client 를 최상단에 적어 클라이언트 임을 선언하면 정상작동 된다.
반응형

+ Recent posts