はじめに
本記事は生成AIによる情報が含まれています。参考程度にお願いします。
Create React App(以下CRA)で作成したプロジェクトに簡単なTODO機能を実装し、脆弱性診断を行ってみました。
実装したコードは以下のようにシンプルなものです。
コード
import React, { useState } from 'react';
import './App.css';
import { Box, Button, Card, CardBody, Checkbox, HStack, Heading, Input, VStack } from '@chakra-ui/react';
type Todo = {
id: number;
content: string;
completed: boolean;
}
function App() {
const [todo, setTodo] = useState('')
const [todos, setTodos] = useState<Todo[]>([])
const addTodo = () => {
const newId = todos && todos[todos.length - 1]? todos[todos.length - 1].id + 1 : 1;
const newTodo: Todo = {
id: newId,
content: todo,
completed: false,
};
setTodos([...todos, newTodo]);
setTodo('')
}
const inputTodo = (e: React.ChangeEvent<HTMLInputElement>) => {
setTodo(e.target.value)
}
const deleteTodo = () => {
const newTodos = todos.filter(todo =>!todo.completed);
setTodos(newTodos);
};
const completed = (id: number) => {
const updatedTodos = [...todos];
const todoIndex = updatedTodos.findIndex(todo => todo.id === id);
updatedTodos[todoIndex].completed = !updatedTodos[todoIndex].completed;
setTodos(updatedTodos);
};
return (
<>
<VStack w='100%'>
<Heading>TODOアプリ</Heading>
<HStack w='80%'>
<Input placeholder='タスクを入力' value={todo} onChange={inputTodo} ></Input>
<Button onClick={addTodo}>追加</Button>
</HStack>
<Box maxHeight={`${600 + todos.length * 50}px`} w='80%'>
{todos.map((task) => (
<Card key={task.id} mb={2} bg='blue.200'>
<CardBody>
<Checkbox
id={task.id.toString()}
colorScheme='red'
isChecked={task.completed}
onChange={() => completed(task.id)}
>
{task.content}
</Checkbox>
{task.id}
</CardBody>
</Card>
))}
</Box>
<Box display='flex' alignItems='center' justifyContent='center' mt={4}>
<Button onClick={deleteTodo}>チェックしたTODOを削除</Button>
</Box>
</VStack>
</>
);
}
export default App;
脆弱性診断の結果
中レベルと低レベルが数件という結果でした。
それぞれの脆弱性について調べていくと、基本的な解決策としてはAPIサーバまたは静的ファイルをホストするサーバ側(ミドルウェア)で設定を行うのが主でした。
CRAで作成したプロジェクトにミドルウェアは含まれていないので別途導入が必要になります。
そのため、今回自身で作成したコードとは無関係の脆弱性でした。
具体的には、
・レスポンスヘッダーを指定
・CORS設定
などです。
Content Security Policy (CSP) Header Not Set
こちらはウェブサイトが安全なコンテンツを許可するためのルール設定がされていないですよ、という脆弱性のようです。
以下の通りに実装し、再び脆弱性診断をするとアラートが消えました!
npm install --save-dev react-app-rewired customize-cra
module.exports = function override(config, env) {
config.devServer.headers["Content-Security-Policy"] =
"default-src 'self'; img-src https://*; child-src 'none';";
return config;
};
Missing Anti-clickjacking Header
ミドルウェアのレスポンスに指定のヘッダーを含めてね、ということらしいです。
クロスドメインの設定ミス
こういうことらしいです。
package.jsonにプロキシ設定することでCORS問題を回避できますが、開発環境においてのみになります。
Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s)
HTTPレスポンスヘッダー内の「X-Powered-By」というフィールドに使用しているWebアプリケーションフレームワークやそのバージョンが表示されてるよ、ということらしいです。
脆弱性が確認されているフレームワークを使用していると、攻撃対象にされかねないという理由で脆弱性に上がっているようです。
こちらに関しては、CRAで作成したプロジェクトをWebサーバでホストしていないため、自身でどうにかできるようなことでは無さそうです。
X-Content-Type-Options Header Missing
こちらもミドルウェアのレスポンスにヘッダーをつけましょう、という内容でした。
今回の脆弱性については内容がよく分からなかったので詳しく聞いてみました。
おわりに
引き続き脆弱性について知見を深めていきたいです。