Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "vite",
"clean": "rm -rf dist",
"prebuild": "bun run clean",
"build": "vite build && bun build.js",
"build": "vite build && bun post.config.js",
"lint": "eslint .",
"preview": "vite preview"
},
Expand Down
30 changes: 17 additions & 13 deletions build.js → post.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@ import fs from 'fs';
import path from 'path';

const postsDir = './public/posts';
const distDir = './dist';
const distDir = './dist';
const allPosts = [];
const years = fs.readdirSync(postsDir);
const years = fs.readdirSync(postsDir);

years.forEach(year => {
const yearPath = path.join(postsDir, year);

if (fs.lstatSync(yearPath).isDirectory()) {
const files = fs.readdirSync(yearPath);

files.forEach(file => {
if (file.endsWith('.md')) {
const fileName = file.replace('.md', '');
const parts = fileName.split('-');
const parts = fileName.split('-');

const y = parts[0];
const m = parts[1];
const d = parts[2];
const y = parts[0];
const m = parts[1];
const d = parts[2];
const slug = parts.slice(3).join('-');
Comment on lines +20 to 23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

A path traversal vulnerability was identified here. The build script parses filenames in the public/posts directory to determine the output path for generated HTML files. By using a specially crafted filename (e.g., ..-..-..-tmp-evil.md), an attacker who can commit files to the repository can cause the build script to write files outside the intended dist directory. This could be used to overwrite sensitive files on the build server or CI/CD runner. To remediate this, validate that the year, month, day, and slug components derived from the filename do not contain path traversal sequences like .. or /. Additionally, the vertical alignment of assignments and property definitions, specifically for slug on line 23, appears to be inconsistent. This style can be difficult to maintain, and it's recommended to use a single space around operators and avoid manual vertical alignment for better consistency.

        const y    = parts[0];
        const m    = parts[1];
        const d    = parts[2];
        const slug = parts.slice(3).join('-');

        if ([y, m, d, slug].some(p => !p || p.includes('..') || p.includes('/') || p.includes('\\'))) {
          return;
        }


allPosts.push({
year: y,
month: m,
day: d,
year : y,
month : m,
day : d,
slug,
originalName: fileName,
title: slug.replace(/-/g, ' '),
date: `${y}-${m}-${d}`
originalName : fileName,
title : slug.replace(/-/g, ' '),
date : `${y}-${m}-${d}`
});
}
});
Expand All @@ -51,11 +53,13 @@ if (fs.existsSync(path.join(distDir, 'index.html'))) {

allPosts.forEach(post => {
const targetDir = path.join(distDir, post.year, post.month, post.day);

if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}

fs.copyFileSync(
path.join(distDir, 'index.html'),
path.join(distDir , 'index.html'),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Aligning a variable with spaces within a function call is unconventional and harms readability and maintainability. Please use a single space for consistency.

      path.join(distDir, 'index.html'),

path.join(targetDir, `${post.slug}.html`)
);
});
Expand Down
8 changes: 4 additions & 4 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
import Analytics from './Analytics';
import NotFound from './NotFound';
import Home from './Home';
import './App.css';
import Analytics from './components/Analytics';
import NotFound from './pages/NotFound/NotFound';
import Home from './pages/Home/Home';
import './styles/App.css';

export default function App() {
const [content, setContent] = useState('');
Expand Down
2 changes: 1 addition & 1 deletion src/Analytics.jsx → src/components/Analytics.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import siteConfig from './config.json';
import siteConfig from '../data/config.json';

export default function Analytics() {
const trackingId = siteConfig.analytics.trackingId;
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import './styles/index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 0 additions & 2 deletions src/NotFound.jsx → src/pages/NotFound/NotFound.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import Analytics from './Analytics';
import './NotFound.css';

export default function NotFound() {
return (
<>
<Analytics />
<div className="not-found-container">
<h1 className="not-found-code">404</h1>
<h2 className="not-found-title">Page Not Found</h2>
Expand Down
File renamed without changes.
File renamed without changes.
Loading