ucode-agent 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -21
- package/package.json +3 -4
- package/skills/ai-features/SKILL.md +140 -0
- package/skills/build-app/SKILL.md +137 -57
- package/skills/code-review/SKILL.md +69 -24
- package/skills/debug/SKILL.md +73 -31
- package/skills/performance/SKILL.md +84 -0
- package/skills/refactor/SKILL.md +72 -0
- package/skills/security/SKILL.md +110 -0
- package/skills/ui-ux/SKILL.md +256 -193
- package/skills/write-tests/SKILL.md +72 -34
- package/src/core/loop.js +3 -2
- package/src/core/provider.js +21 -19
- package/src/core/version.js +16 -0
- package/src/ui/screen.js +1187 -1067
- package/ucode.js +3 -4
package/skills/debug/SKILL.md
CHANGED
|
@@ -1,47 +1,89 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: debug
|
|
3
|
-
description: Find the
|
|
3
|
+
description: Find and fix the real cause of a bug — reproduce it, narrow it down with evidence, prove the fix, guard it with a test, and check for the same bug elsewhere.
|
|
4
|
+
auto: bug, crash, crashes, crashing, broken, not working, doesn't work, does not work, stack trace, exception, traceback, throws, failing, fails, regression, undefined is not, cannot read properties, 500 error, blank page, hangs, freezes
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Debugging
|
|
7
8
|
|
|
8
|
-
The temptation is to read the code, form a theory, change something, and
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
The temptation is to read the code, form a theory, change something, and call
|
|
10
|
+
it fixed when the symptom goes away. That moves bugs rather than fixing them.
|
|
11
|
+
Work from evidence, in this order.
|
|
11
12
|
|
|
12
|
-
## Reproduce it
|
|
13
|
+
## 1. Reproduce it yourself
|
|
13
14
|
|
|
14
|
-
Do not
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
version, the full stack. Guessing from a paraphrase wastes everyone's turn.
|
|
15
|
+
Do not debug from the description. Run it and see it fail: the exact command,
|
|
16
|
+
the input, the full error, the line it comes from. Write down the reproduction
|
|
17
|
+
as a single command or a few steps — you will run it again at the end.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
If you cannot reproduce it, say so and ask for exactly what is missing: the
|
|
20
|
+
input, the environment, the version, the full output. Guessing from a
|
|
21
|
+
paraphrase wastes everyone's turn.
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
The top frame is where it surfaced, not necessarily where it went wrong.
|
|
23
|
-
- `grep` for the message text to find where it is produced.
|
|
24
|
-
- Cut the search space in half at a time: does the smaller input fail? Does it
|
|
25
|
-
fail on the previous commit? Does the layer below get the right value?
|
|
26
|
-
- Print or log the values at the boundary rather than reasoning about what they
|
|
27
|
-
should be. What you believe is in that variable is the thing under suspicion.
|
|
23
|
+
## 2. Read the whole error
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
- The whole stack trace, including frames you assume are irrelevant. The top
|
|
26
|
+
frame is where it surfaced, not necessarily where it went wrong.
|
|
27
|
+
- The first error, not the last. Later errors are often consequences.
|
|
28
|
+
- `grep` for the exact message text to find where it is produced.
|
|
29
|
+
- Check the obvious before the clever: is the file saved, the server restarted,
|
|
30
|
+
the right branch checked out, the env var set, the dependency installed, the
|
|
31
|
+
cache cleared (`.next`, `node_modules/.vite`, `__pycache__`)?
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
undefined here because the caller only sets it on the success path*. If you
|
|
33
|
-
cannot write that sentence, you have not found it yet.
|
|
33
|
+
## 3. Narrow it down
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
the real defect in place, with one more layer over it.
|
|
35
|
+
Cut the search space in half each step:
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
- **Input:** does a smaller or simpler input still fail? Find the smallest one
|
|
38
|
+
that does.
|
|
39
|
+
- **Code:** comment out or bypass half the path. Does it still fail?
|
|
40
|
+
- **Time:** did it work before? `git log` / `git diff` since then, or
|
|
41
|
+
`git bisect` between a good and a bad commit.
|
|
42
|
+
- **Layer:** is the value right when it enters the function? When it leaves?
|
|
43
|
+
At the API boundary? In the database? Log it at each boundary and look,
|
|
44
|
+
rather than reasoning about what it "should" be.
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
- Run the rest of the tests. A fix that breaks two other things is a trade,
|
|
42
|
-
and the user gets to make it, not you.
|
|
43
|
-
- Write a test that fails without your fix. A bug with no regression test comes
|
|
44
|
-
back.
|
|
46
|
+
The value you are sure about is the one under suspicion. Print it.
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
## 4. Know where bugs usually live
|
|
49
|
+
|
|
50
|
+
- **Async:** a missing `await`, a race between two requests, state read before
|
|
51
|
+
it is set, a promise rejection nobody catches.
|
|
52
|
+
- **State:** stale closures in React effects, mutation of shared objects, a
|
|
53
|
+
cache that was never invalidated.
|
|
54
|
+
- **Boundaries:** off-by-one, empty arrays, `null` vs `undefined` vs `''`,
|
|
55
|
+
timezones, number parsing (`'10' + 1`), float rounding.
|
|
56
|
+
- **Data shape:** the API returned something different from the type — an
|
|
57
|
+
error object, a wrapped payload, a string instead of JSON.
|
|
58
|
+
- **Environment:** missing env var, wrong Node version, path case sensitivity,
|
|
59
|
+
Windows vs POSIX paths and line endings, a port already in use.
|
|
60
|
+
- **Build tooling:** a stale build cache, a server/client boundary violation in
|
|
61
|
+
Next.js, a default vs named export mismatch, ESM vs CommonJS.
|
|
62
|
+
|
|
63
|
+
## 5. State the cause before fixing it
|
|
64
|
+
|
|
65
|
+
Write it in one sentence: *"`score` is `undefined` here because the parser
|
|
66
|
+
returns `{ data: {...} }` and the component reads `result.score`."* If you
|
|
67
|
+
cannot write that sentence, you have not found the cause yet — keep narrowing.
|
|
68
|
+
|
|
69
|
+
## 6. Fix the cause, not the symptom
|
|
70
|
+
|
|
71
|
+
A `?.` or a `try/catch` that hides the failure leaves the defect in place under
|
|
72
|
+
one more layer. Fix it where it originates. Keep the change as small as the
|
|
73
|
+
cause allows, and do not refactor unrelated code in the same change.
|
|
74
|
+
|
|
75
|
+
## 7. Prove it
|
|
76
|
+
|
|
77
|
+
- Run the original reproduction. It must pass now.
|
|
78
|
+
- Run the whole test suite. A fix that breaks two other things is a trade the
|
|
79
|
+
user gets to decide on, not you.
|
|
80
|
+
- Add a regression test that fails without the fix and passes with it — then
|
|
81
|
+
briefly revert the fix to confirm the test really catches it.
|
|
82
|
+
- Look for the same mistake elsewhere: `grep` for the same pattern, call, or
|
|
83
|
+
assumption. Bugs come in families.
|
|
84
|
+
|
|
85
|
+
## 8. Report
|
|
86
|
+
|
|
87
|
+
The cause in one or two sentences, the fix, how you verified it, and anything
|
|
88
|
+
adjacent you noticed but did not change. If you could not fully confirm it,
|
|
89
|
+
say what is still uncertain.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance
|
|
3
|
+
description: Make software measurably faster — measure first, find the real bottleneck, fix it, and prove the improvement with numbers. Covers web vitals, bundles, React rendering, APIs, databases and Node.
|
|
4
|
+
auto: slow, slower, performance, perf, optimize, optimise, optimization, speed up, faster, lag, laggy, sluggish, bundle size, lighthouse, core web vitals, web vitals, lcp, cls, inp, memory leak, re-render, rerender, n+1, latency, takes too long
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Performance
|
|
8
|
+
|
|
9
|
+
Guessing at performance is how people spend a day optimizing something that
|
|
10
|
+
was never slow. Measure, change one thing, measure again.
|
|
11
|
+
|
|
12
|
+
## 1. Measure before touching anything
|
|
13
|
+
|
|
14
|
+
- **Define the slow thing precisely**: which page, action or endpoint, how slow
|
|
15
|
+
now, how fast it needs to be.
|
|
16
|
+
- **Get a baseline number** you can re-run:
|
|
17
|
+
- Web page: Lighthouse / PageSpeed (LCP, INP, CLS, total JS), the browser
|
|
18
|
+
Performance panel, `next build` output (per-route JS size).
|
|
19
|
+
- API: time the request (`curl -w "%{time_total}\n"`), log durations per step.
|
|
20
|
+
- Node/Python: a profiler (`node --cpu-prof`, `clinic`, `py-spy`), or timers
|
|
21
|
+
around the suspect code.
|
|
22
|
+
- Database: `EXPLAIN ANALYZE` on the slow query.
|
|
23
|
+
- Measure the production build, not dev mode — dev is deliberately slow.
|
|
24
|
+
|
|
25
|
+
## 2. Find the actual bottleneck
|
|
26
|
+
|
|
27
|
+
It is almost always one of these, in roughly this order of likelihood:
|
|
28
|
+
|
|
29
|
+
1. **Network waterfalls** — requests that wait on each other when they could run
|
|
30
|
+
in parallel; data fetched on the client that could be fetched on the server.
|
|
31
|
+
2. **Too much JavaScript** — heavy dependencies, everything marked
|
|
32
|
+
`"use client"`, no code splitting.
|
|
33
|
+
3. **Unoptimized images and fonts** — huge images, no dimensions (layout shift),
|
|
34
|
+
blocking font loads.
|
|
35
|
+
4. **Database** — N+1 queries, missing indexes, fetching whole tables, no
|
|
36
|
+
pagination.
|
|
37
|
+
5. **Rendering** — React re-rendering large trees on every keystroke, expensive
|
|
38
|
+
work inside render, long lists without virtualization.
|
|
39
|
+
6. **Algorithmic** — nested loops over large data, repeated work that could be
|
|
40
|
+
cached or computed once.
|
|
41
|
+
|
|
42
|
+
## 3. Fixes by area
|
|
43
|
+
|
|
44
|
+
**Web (Next.js / React)**
|
|
45
|
+
- Server components by default; `"use client"` at the leaves only.
|
|
46
|
+
- `next/image` with explicit sizes; `priority` on the LCP image; modern formats.
|
|
47
|
+
- `next/font` with `display: swap`, only the weights used.
|
|
48
|
+
- Dynamic `import()` for heavy, below-the-fold or rarely used components.
|
|
49
|
+
- Replace heavy libraries (moment → date-fns/Intl, lodash → native, big chart
|
|
50
|
+
libs → lighter ones) and check the per-route JS in the build output.
|
|
51
|
+
- Parallelize independent fetches with `Promise.all`; stream with `Suspense`.
|
|
52
|
+
- Cache: static where possible, `revalidate` for data that changes slowly.
|
|
53
|
+
|
|
54
|
+
**React rendering**
|
|
55
|
+
- Keep state as low in the tree as possible; lift only what must be shared.
|
|
56
|
+
- Stable props: memoize expensive values and callbacks passed to memoized
|
|
57
|
+
children — but only where the profiler shows a real cost.
|
|
58
|
+
- Virtualize lists over a few hundred rows.
|
|
59
|
+
- Debounce input-driven work (search, validation) at ~200–300ms.
|
|
60
|
+
|
|
61
|
+
**APIs and databases**
|
|
62
|
+
- Index columns used in `WHERE`, `JOIN` and `ORDER BY`; confirm with `EXPLAIN`.
|
|
63
|
+
- Batch or join instead of querying in a loop (N+1).
|
|
64
|
+
- Select only the columns needed; paginate everything user-sized.
|
|
65
|
+
- Cache expensive, repeatable results (in memory, Redis, HTTP caching) with a
|
|
66
|
+
clear invalidation rule.
|
|
67
|
+
- Move slow non-essential work (emails, analytics, thumbnails) to a background
|
|
68
|
+
job.
|
|
69
|
+
|
|
70
|
+
**Node**
|
|
71
|
+
- Never block the event loop with sync I/O or heavy CPU in a request handler.
|
|
72
|
+
- Stream large files instead of reading them whole.
|
|
73
|
+
- Reuse clients and connections (DB pools, HTTP keep-alive).
|
|
74
|
+
|
|
75
|
+
## 4. Change one thing at a time, and prove it
|
|
76
|
+
|
|
77
|
+
After each change, re-run the same measurement. Keep changes that move the
|
|
78
|
+
number; revert ones that do not — complexity without a measured win is a cost.
|
|
79
|
+
|
|
80
|
+
## 5. Report with numbers
|
|
81
|
+
|
|
82
|
+
Before and after for each metric that changed ("LCP 4.1s → 1.6s, route JS
|
|
83
|
+
312 kB → 148 kB"), what caused it, and anything left that would need a bigger
|
|
84
|
+
change to fix.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactor
|
|
3
|
+
description: Restructure code without changing what it does — a safety net first, small verified steps, clear boundaries and names, and no behaviour change slipped in along the way.
|
|
4
|
+
auto: refactor, refactoring, clean up, cleanup, clean this, restructure, reorganize, reorganise, simplify, tech debt, technical debt, extract, split this file, split up, dead code, duplicate code, duplication, messy code, spaghetti
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Refactoring
|
|
8
|
+
|
|
9
|
+
A refactor changes the shape of code and nothing else. The moment behaviour
|
|
10
|
+
changes, it is a rewrite, and a rewrite hidden inside a refactor is how
|
|
11
|
+
regressions ship with nobody noticing.
|
|
12
|
+
|
|
13
|
+
## 1. Know why, and where it stops
|
|
14
|
+
|
|
15
|
+
- State the goal in one line: *split the 700-line page into components*,
|
|
16
|
+
*remove the duplicated fetch logic*, *make the scoring rules testable*.
|
|
17
|
+
- State the boundary: which files are in scope. Resist improving everything you
|
|
18
|
+
pass on the way — note it and leave it.
|
|
19
|
+
|
|
20
|
+
## 2. Build the safety net first
|
|
21
|
+
|
|
22
|
+
- Run the existing tests and record the result. If there are none around the
|
|
23
|
+
code you are changing, **write characterization tests first**: tests that pin
|
|
24
|
+
down what the code does now, including its odd behaviour. You are preserving
|
|
25
|
+
behaviour, so you must be able to detect when it changes.
|
|
26
|
+
- For UI with no tests, capture the current behaviour: what renders in each
|
|
27
|
+
state, what each control does.
|
|
28
|
+
|
|
29
|
+
## 3. Read it all before moving anything
|
|
30
|
+
|
|
31
|
+
Read every file in scope in full, and find every caller of what you will change
|
|
32
|
+
(`grep` for the names, the imports, the routes). A rename that misses one
|
|
33
|
+
dynamic reference is a runtime error waiting for the one path nobody tested.
|
|
34
|
+
|
|
35
|
+
## 4. Small steps, each one green
|
|
36
|
+
|
|
37
|
+
Do one kind of change at a time, and run the tests after each:
|
|
38
|
+
|
|
39
|
+
- **Rename** to say what things are: `data` → `analysis`, `handle()` →
|
|
40
|
+
`submitLabel()`. Names are most of readability.
|
|
41
|
+
- **Extract** a function or component for each distinct job; a function should
|
|
42
|
+
do one thing at one level of abstraction.
|
|
43
|
+
- **Move** code next to what uses it: feature folders over type folders.
|
|
44
|
+
- **Remove duplication** only when the copies really are the same concept —
|
|
45
|
+
two similar-looking pieces that change for different reasons should stay two.
|
|
46
|
+
- **Delete dead code** — unused exports, unreachable branches, commented-out
|
|
47
|
+
blocks. Confirm it is unused with a search first.
|
|
48
|
+
- **Simplify conditionals**: early returns over nesting, lookup tables over long
|
|
49
|
+
`if/else` chains, named booleans over complex expressions.
|
|
50
|
+
- **Push side effects to the edges**: pure logic in the middle (easy to test),
|
|
51
|
+
I/O at the boundary.
|
|
52
|
+
|
|
53
|
+
Use `multi_edit` for several changes in one file, and keep each step small
|
|
54
|
+
enough that a failing test points straight at the cause.
|
|
55
|
+
|
|
56
|
+
## 5. Keep behaviour identical
|
|
57
|
+
|
|
58
|
+
- Same inputs, same outputs, same errors, same side effects, same order of
|
|
59
|
+
side effects.
|
|
60
|
+
- Public APIs and stored formats unchanged, or every caller and every stored
|
|
61
|
+
record updated in the same change.
|
|
62
|
+
- If you find a bug while refactoring, **do not fix it silently inside the
|
|
63
|
+
refactor**. Finish the refactor, then fix the bug as its own change — or
|
|
64
|
+
report it — so each can be reviewed and reverted on its own.
|
|
65
|
+
|
|
66
|
+
## 6. Finish
|
|
67
|
+
|
|
68
|
+
- All tests pass, the build passes, the linter and type checker are clean.
|
|
69
|
+
- The code is measurably simpler: fewer lines, fewer branches, smaller files,
|
|
70
|
+
clearer names — say which.
|
|
71
|
+
- Report what moved where, anything you noticed but deliberately left alone,
|
|
72
|
+
and any behaviour you had to pin down with new tests.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security
|
|
3
|
+
description: Build and audit software so it is safe by default — secrets, authentication and authorization, input validation, injection, XSS, CSRF, SSRF, uploads, dependencies and headers, checked against how attacks actually happen.
|
|
4
|
+
auto: security, secure, vulnerability, vulnerabilities, auth, authentication, authorization, login, sign in, signup, sign up, password, passwords, jwt, oauth, session cookie, xss, csrf, ssrf, sql injection, injection, secrets, api key, api keys, owasp, harden, hardening, permissions, rate limit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Security
|
|
8
|
+
|
|
9
|
+
Assume every input is hostile and every secret will be looked for. Most real
|
|
10
|
+
breaches come from a short list of boring mistakes; this skill is that list,
|
|
11
|
+
with what to do about each.
|
|
12
|
+
|
|
13
|
+
## 1. Secrets
|
|
14
|
+
|
|
15
|
+
- **Never in the browser.** Anything imported by client code ships to every
|
|
16
|
+
visitor — including a "temporary" hardcoded key. Keys live in server routes,
|
|
17
|
+
server actions or server-only modules (`import 'server-only'`).
|
|
18
|
+
- **Never in the repository.** Use `.env.local` / `.env` (gitignored) and commit
|
|
19
|
+
a `.env.example` with placeholders. If a key was ever committed or pasted
|
|
20
|
+
somewhere public, rotate it — deleting the line does not un-leak it.
|
|
21
|
+
- **Never in logs, errors or URLs.** Redact before logging; do not put tokens
|
|
22
|
+
in query strings.
|
|
23
|
+
- If the user insists on hardcoding a key for now, put it in one server-only
|
|
24
|
+
file, say exactly where it is, and recommend moving it to an env var.
|
|
25
|
+
|
|
26
|
+
## 2. Authentication
|
|
27
|
+
|
|
28
|
+
- Use a proven library or provider (Auth.js/NextAuth, Clerk, Supabase Auth,
|
|
29
|
+
Lucia-style patterns) rather than hand-rolled sessions and hashing.
|
|
30
|
+
- Passwords: argon2id or bcrypt, never reversible, never logged. Rate-limit
|
|
31
|
+
login and reset endpoints. Same error message for "no such user" and "wrong
|
|
32
|
+
password".
|
|
33
|
+
- Sessions: `HttpOnly`, `Secure`, `SameSite=Lax` (or `Strict`) cookies. Rotate
|
|
34
|
+
the session on login. Expire idle sessions.
|
|
35
|
+
- JWTs: short expiry, verify signature and algorithm server-side, never trust
|
|
36
|
+
claims the client can edit.
|
|
37
|
+
|
|
38
|
+
## 3. Authorization — the most common real hole
|
|
39
|
+
|
|
40
|
+
- **Check ownership on every request**, on the server, for every object:
|
|
41
|
+
`WHERE id = $1 AND user_id = $session.user`. Changing an ID in a URL or body
|
|
42
|
+
must never reveal someone else's data (IDOR).
|
|
43
|
+
- Deny by default. Every route states who may call it.
|
|
44
|
+
- Hiding a button is not authorization; the endpoint behind it must check too.
|
|
45
|
+
|
|
46
|
+
## 4. Input validation and injection
|
|
47
|
+
|
|
48
|
+
- Validate every input at the boundary with a schema (zod, pydantic): type,
|
|
49
|
+
length, range, format. Reject, do not "clean".
|
|
50
|
+
- **SQL:** parameterized queries or an ORM only. Never string-build SQL with
|
|
51
|
+
user input.
|
|
52
|
+
- **Shell:** avoid it; if unavoidable, pass arguments as an array
|
|
53
|
+
(`execFile`, `spawn` without `shell: true`), never interpolate.
|
|
54
|
+
- **Paths:** resolve and verify the result stays inside the allowed directory;
|
|
55
|
+
reject `..` and absolute paths from users.
|
|
56
|
+
- **SSRF:** when fetching a user-supplied URL, allow-list hosts, block private
|
|
57
|
+
and link-local ranges (127.0.0.0/8, 10/8, 172.16/12, 192.168/16, 169.254/16,
|
|
58
|
+
::1), and do not follow redirects blindly.
|
|
59
|
+
|
|
60
|
+
## 5. Output: XSS
|
|
61
|
+
|
|
62
|
+
- Let the framework escape (React, templating engines). Treat
|
|
63
|
+
`dangerouslySetInnerHTML`, `innerHTML`, `v-html` and markdown-to-HTML as
|
|
64
|
+
red flags: sanitize with DOMPurify if you must render HTML.
|
|
65
|
+
- Never put user input into `href` without checking the scheme
|
|
66
|
+
(`javascript:` URLs), or into inline `<script>` or event handlers.
|
|
67
|
+
- Set a Content-Security-Policy where you can.
|
|
68
|
+
|
|
69
|
+
## 6. Requests
|
|
70
|
+
|
|
71
|
+
- **CSRF:** SameSite cookies plus a CSRF token or origin check on state-changing
|
|
72
|
+
requests that use cookie auth. Next.js server actions check origin; custom
|
|
73
|
+
routes need it done.
|
|
74
|
+
- **CORS:** never `*` with credentials; allow-list the origins that need it.
|
|
75
|
+
- **Rate limiting** on login, signup, password reset, and any expensive or paid
|
|
76
|
+
endpoint (AI calls especially) — per IP and per user.
|
|
77
|
+
|
|
78
|
+
## 7. File uploads
|
|
79
|
+
|
|
80
|
+
- Check type by content (magic bytes), not just the extension or MIME header.
|
|
81
|
+
- Enforce a size limit on the server, not only the client.
|
|
82
|
+
- Store outside the web root or in object storage with generated names; never
|
|
83
|
+
execute or serve uploads from the app's own origin as HTML.
|
|
84
|
+
- Strip metadata (EXIF location) from images when privacy matters.
|
|
85
|
+
|
|
86
|
+
## 8. Errors, headers, dependencies
|
|
87
|
+
|
|
88
|
+
- Errors to users are generic; details go to server logs. No stack traces in
|
|
89
|
+
responses.
|
|
90
|
+
- Headers: `Strict-Transport-Security`, `X-Content-Type-Options: nosniff`,
|
|
91
|
+
`Referrer-Policy: strict-origin-when-cross-origin`, `frame-ancestors` via CSP.
|
|
92
|
+
- Dependencies: `npm audit` (or the ecosystem equivalent), remove unused
|
|
93
|
+
packages, pin versions with a lockfile, be wary of new packages with few
|
|
94
|
+
downloads or typo-like names.
|
|
95
|
+
|
|
96
|
+
## 9. Auditing existing code
|
|
97
|
+
|
|
98
|
+
Search rather than read everything:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
grep for: api[_-]?key|secret|token|password (hardcoded secrets)
|
|
102
|
+
dangerouslySetInnerHTML|innerHTML|eval\(|new Function
|
|
103
|
+
exec\(|execSync|shell: true|child_process
|
|
104
|
+
\$\{.*\}.*(SELECT|INSERT|UPDATE|DELETE) (string-built SQL)
|
|
105
|
+
fetch\(.*req\.|axios\(.*req\. (user-controlled URLs)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Then check every route for authentication and ownership checks. Report
|
|
109
|
+
findings ranked by severity with the file, the attack, and the fix — and fix
|
|
110
|
+
the critical ones first if asked to fix.
|