Skip to content

Commit 7206cf6

Browse files
committed
feat(security): implement comprehensive security scanning and reporting tools
1 parent 747a1fe commit 7206cf6

File tree

12 files changed

+691
-7
lines changed

12 files changed

+691
-7
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
name: Security Vulnerability Report
3+
about: Report a security vulnerability (for non-sensitive issues only)
4+
title: '[SECURITY] '
5+
labels: security
6+
assignees: ''
7+
---
8+
9+
<!--
10+
⚠️ IMPORTANT: For sensitive security vulnerabilities, please DO NOT use this public issue tracker.
11+
Instead, email us at security@photostructure.com
12+
13+
This template is only for:
14+
- Non-sensitive security concerns
15+
- Security feature requests
16+
- Questions about security practices
17+
-->
18+
19+
## Description
20+
21+
A clear and concise description of the security concern.
22+
23+
## Impact
24+
25+
Describe the potential impact if this issue is not addressed.
26+
27+
## Steps to Reproduce (if applicable)
28+
29+
1. Step 1
30+
2. Step 2
31+
3. ...
32+
33+
## Suggested Fix
34+
35+
If you have suggestions on how to address this issue, please describe them here.
36+
37+
## Additional Context
38+
39+
Add any other context about the security concern here.

.github/workflows/security.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: Security Scanning
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
schedule:
9+
# Run security scan weekly on Monday at 9am UTC
10+
- cron: '0 9 * * 1'
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
security-events: write
16+
17+
jobs:
18+
npm-audit:
19+
name: NPM Audit
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: 20
28+
cache: 'npm'
29+
30+
- name: Run npm audit
31+
run: |
32+
npm audit --production --audit-level=moderate || true
33+
npm audit --audit-level=moderate
34+
35+
snyk:
36+
name: Snyk Security Scan
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Run Snyk to check for vulnerabilities
42+
uses: snyk/actions/node@master
43+
env:
44+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
45+
with:
46+
args: --severity-threshold=medium
47+
continue-on-error: true # Don't fail the build if vulnerabilities are found
48+
49+
- name: Upload Snyk results
50+
uses: github/codeql-action/upload-sarif@v3
51+
if: always()
52+
with:
53+
sarif_file: snyk.sarif
54+
55+
osv-scanner:
56+
name: OSV Scanner
57+
runs-on: ubuntu-latest
58+
steps:
59+
- uses: actions/checkout@v4
60+
61+
- name: Run OSV Scanner
62+
uses: google/osv-scanner-action@v1.8.3
63+
with:
64+
scan-args: |-
65+
--recursive
66+
.
67+
68+
codeql-javascript:
69+
name: CodeQL JavaScript/TypeScript Analysis
70+
runs-on: ubuntu-latest
71+
steps:
72+
- uses: actions/checkout@v4
73+
74+
- name: Initialize CodeQL
75+
uses: github/codeql-action/init@v3
76+
with:
77+
languages: javascript-typescript
78+
queries: security-and-quality
79+
80+
- name: Autobuild
81+
uses: github/codeql-action/autobuild@v3
82+
83+
- name: Perform CodeQL Analysis
84+
uses: github/codeql-action/analyze@v3
85+
86+
codeql-cpp:
87+
name: CodeQL C++ Analysis
88+
runs-on: ubuntu-latest
89+
steps:
90+
- uses: actions/checkout@v4
91+
with:
92+
submodules: recursive
93+
94+
- name: Setup build environment
95+
run: |
96+
sudo apt-get update
97+
sudo apt-get install -y python3 make g++ gcc
98+
99+
- name: Setup Node.js
100+
uses: actions/setup-node@v4
101+
with:
102+
node-version: 20
103+
cache: 'npm'
104+
105+
- name: Install dependencies
106+
run: npm ci
107+
108+
- name: Initialize CodeQL
109+
uses: github/codeql-action/init@v3
110+
with:
111+
languages: cpp
112+
queries: security-and-quality
113+
114+
- name: Build C++ code
115+
run: npm run node-gyp-rebuild
116+
117+
- name: Perform CodeQL Analysis
118+
uses: github/codeql-action/analyze@v3
119+
120+
121+
dependency-review:
122+
name: Dependency Review
123+
runs-on: ubuntu-latest
124+
if: github.event_name == 'pull_request'
125+
steps:
126+
- uses: actions/checkout@v4
127+
128+
- name: Dependency Review
129+
uses: actions/dependency-review-action@v4
130+
with:
131+
fail-on-severity: moderate
132+
deny-licenses: AGPL-3.0, GPL-3.0
133+
134+
secrets-scan:
135+
name: Secrets Scanning
136+
runs-on: ubuntu-latest
137+
steps:
138+
- uses: actions/checkout@v4
139+
with:
140+
fetch-depth: 0
141+
142+
- name: TruffleHog OSS
143+
uses: trufflesecurity/trufflehog@main
144+
with:
145+
path: ./
146+
base: ${{ github.event.repository.default_branch }}
147+
head: HEAD
148+
extra_args: --exclude-paths .trufflehog-exclude.txt --only-verified
149+
continue-on-error: true
150+
151+
summary:
152+
name: Security Summary
153+
runs-on: ubuntu-latest
154+
needs: [npm-audit, snyk, osv-scanner, codeql-javascript, codeql-cpp, secrets-scan]
155+
if: always()
156+
steps:
157+
- name: Summary
158+
run: |
159+
echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY
160+
echo "" >> $GITHUB_STEP_SUMMARY
161+
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
162+
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
163+
echo "| NPM Audit | ${{ needs.npm-audit.result }} |" >> $GITHUB_STEP_SUMMARY
164+
echo "| Snyk | ${{ needs.snyk.result }} |" >> $GITHUB_STEP_SUMMARY
165+
echo "| OSV Scanner | ${{ needs.osv-scanner.result }} |" >> $GITHUB_STEP_SUMMARY
166+
echo "| CodeQL JS/TS | ${{ needs.codeql-javascript.result }} |" >> $GITHUB_STEP_SUMMARY
167+
echo "| CodeQL C++ | ${{ needs.codeql-cpp.result }} |" >> $GITHUB_STEP_SUMMARY
168+
echo "| Secrets Scan | ${{ needs.secrets-scan.result }} |" >> $GITHUB_STEP_SUMMARY

.osv-scanner.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# OSV Scanner Configuration
2+
# https://google.github.io/osv-scanner/configuration/
3+
4+
[[IgnoredVulns]]
5+
# Add any false positives or accepted risks here
6+
# id = "GHSA-xxx"
7+
# reason = "This vulnerability doesn't affect our usage"
8+
9+
[PackageOverrides]
10+
# Override package information if needed
11+
# [[PackageOverrides.entry]]
12+
# name = "package-name"
13+
# ecosystem = "npm"
14+
# ignore = true
15+
# reason = "Dev dependency only"

.snyk

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Snyk (https://snyk.io) policy file
2+
version: v1.25.0
3+
4+
# Ignore specific vulnerabilities
5+
ignore: {}
6+
7+
# Patches to apply
8+
patch: {}
9+
10+
# Language settings
11+
language-settings:
12+
node-js:
13+
enableLicensesScan: true
14+
15+
# Project settings
16+
exclude:
17+
global:
18+
- "benchmark/**"
19+
- "vendored/**"
20+
- "dist/**"
21+
- "test/**"
22+
- "scripts/**"
23+
- "*.test.ts"
24+
- "*.test.js"

.trufflehog-exclude.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
node_modules/
2+
dist/
3+
build/
4+
vendored/
5+
prebuilds/
6+
\.min\.js$
7+
\.map$
8+
package-lock\.json
9+
benchmark/node_modules/
10+
coverage/
11+
\.git/
12+
\.(jpg|jpeg|png|gif|ico|svg|webp)$
13+
\.(woff|woff2|ttf|eot)$

README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ await db.backup("./other-backup.db", {
138138

139139
### Session-based Change Tracking
140140

141+
SQLite's session extension allows you to record changes and apply them to other databases - perfect for synchronization, replication, or undo/redo functionality. This feature is available in both `node:sqlite` and `@photostructure/sqlite`, but not in better-sqlite3.
142+
141143
```typescript
142144
// Create a session to track changes
143145
const session = db.createSession({ table: "users" });
@@ -149,7 +151,7 @@ db.prepare("INSERT INTO users (name, email) VALUES (?, ?)").run(
149151
"bob@example.com",
150152
);
151153

152-
// Get the changes
154+
// Get the changes as a changeset
153155
const changeset = session.changeset();
154156
session.close();
155157

@@ -201,7 +203,7 @@ This package provides performance comparable to Node.js's built-in SQLite and be
201203

202204
- **Synchronous operations** - No async/await overhead
203205
- **Direct C library access** - Minimal JavaScript ↔ native boundary crossings
204-
- **Full SQLite features** - FTS5, JSON functions, R\*Tree indexes, math functions, session extension
206+
- **Full SQLite features** - FTS5, JSON functions, R\*Tree indexes, math functions, session extension (including changesets)
205207

206208
Performance is quite similar to node:sqlite and better-sqlite3, while significantly faster than async sqlite3 due to synchronous operations.
207209

@@ -236,7 +238,7 @@ _The official SQLite module included with Node.js 22.5.0+ (experimental)_
236238
- **Zero dependencies** — Built directly into Node.js
237239
- **Official support** — Maintained by the Node.js core team
238240
- **Clean synchronous API** — Simple, predictable blocking operations
239-
- **Full SQLite power** — FTS5, JSON functions, R\*Tree, and more
241+
- **Full SQLite power** — FTS5, JSON functions, R\*Tree, sessions/changesets, and more
240242

241243
**⚠️ Cons:**
242244

@@ -259,13 +261,15 @@ _The most popular high-performance synchronous SQLite library_
259261
- **Blazing fast** — 2-15x faster than async alternatives
260262
- **Rock-solid stability** — Battle-tested in thousands of production apps
261263
- **Rich feature set** — User functions, aggregates, virtual tables, extensions
264+
- **Extensive community** — Large ecosystem with many resources
262265

263266
**⚠️ Cons:**
264267

265268
- **Different API** — Not compatible with Node.js built-in SQLite
266269
- **V8-specific** — Requires separate builds for each Node.js version
267270
- **Synchronous only** — No async operations (usually a feature, not a bug)
268271
- **Migration effort** — Switching from other libraries requires code changes
272+
- **No session support** — Doesn't expose SQLite's session/changeset functionality
269273

270274
**🎯 Best for:** High-performance applications where you want maximum speed and control over the API.
271275

@@ -306,6 +310,7 @@ _The original asynchronous SQLite binding for Node.js_
306310
-**Synchronous performance** with a clean, official API
307311
-**Node-API stability** — one build works across Node.js versions
308312
-**Zero migration path** when `node:sqlite` becomes stable
313+
-**Session/changeset support** for replication and synchronization
309314

310315
### Choose **`better-sqlite3`** when you want:
311316

@@ -352,6 +357,31 @@ See [TODO.md](./TODO.md) for the complete feature list and future enhancements.
352357
- 📋 Additional platform-specific optimizations
353358
- 📋 Enhanced debugging and profiling tools
354359

360+
## Security
361+
362+
This project takes security seriously and employs multiple layers of protection:
363+
364+
- **Automated scanning**: npm audit, Snyk, OSV Scanner, CodeQL (JS/TS and C++), and TruffleHog
365+
- **Weekly security scans**: Automated checks for new vulnerabilities
366+
- **Rapid patching**: Security fixes are prioritized and released quickly
367+
- **Memory safety**: Validated through ASAN, valgrind, and comprehensive testing
368+
369+
### Running Security Scans Locally
370+
371+
```bash
372+
# Install security tools (OSV Scanner, better-npm-audit, etc.)
373+
npm run security:setup
374+
375+
# Run all security scans
376+
npm run security
377+
378+
# Run individual scans
379+
npm run security:audit # npm audit
380+
npm run security:osv # OSV Scanner (requires Go)
381+
```
382+
383+
For details, see our [Security Policy](./SECURITY.md). To report vulnerabilities, please email security@photostructure.com.
384+
355385
## License
356386

357387
MIT License - see [LICENSE](./LICENSE) for details.

0 commit comments

Comments
 (0)