Claude/cpu guard script dn d8u - #123
Conversation
… main
Combines all changes from this PR into a single clean commit:
- backend.js: store raw buffer on req.rawBody before express.json() runs
so HMAC verification uses the original bytes (not JSON.stringify output);
guard log stream creation in try-catch with .on('error') fallback to
console so filesystem failures never crash the process
- package.json: broaden engine range from >=20 <22 to >=20 (Node v24 compat)
- package-lock.json: regenerate with express@4.x and all transitive deps
(was missing, causing npm ci to fail on VPS)
- runewager-endpoint.service: User/Group → root (VPS runs as root)
- runewager.service: User/Group → root (VPS runs as root)
https://claude.ai/code/session_01WpEqAiDbpqnBywMjYXJHf4
- Pin express to 4.22.1 (remove ^ semver range) to match the explicitly installed version and prevent future version drift that caused the missing-dependency failure on Node 21. - Add ExecStartPre to runewager-endpoint.service: kills any stale process holding port 3001 before each systemd start, eliminating the EADDRINUSE → instant-crash → restart loop. Also tightened StartLimitBurst=4 / RestartSec=10 / StartLimitIntervalSec=120 to reduce CPU spike if the service still fails repeatedly. - Add section 9d to prod-run.sh: installs/refreshes the endpoint service unit from the repo copy, clears port 3001 before restart, restarts via systemd with a nohup fallback — so a full prod-run now brings both services up cleanly without manual intervention. https://claude.ai/code/session_01WpEqAiDbpqnBywMjYXJHf4
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Reviewer's GuideThis PR adds a managed systemd-based deployment path (with nohup fallback) for the runewager backend endpoint, hardens backend logging so failures to open log files don’t crash logging, fixes raw-body handling for the /autofix webhook HMAC verification, and updates Node/Express versions. Sequence diagram for /autofix webhook raw-body capture and HMAC verificationsequenceDiagram
actor AutofixClient
participant ExpressApp
participant RawAutofixMiddleware
participant JsonBodyParser
participant WebhookHandler
participant SignatureVerifier
AutofixClient->>ExpressApp: POST /autofix/webhook
ExpressApp->>RawAutofixMiddleware: invoke for /autofix
RawAutofixMiddleware->>RawAutofixMiddleware: express.raw() parse body
RawAutofixMiddleware-->>ExpressApp: set req.rawBody (Buffer)
ExpressApp->>JsonBodyParser: apply express.json()
JsonBodyParser-->>ExpressApp: set req.body (parsed JSON)
ExpressApp->>WebhookHandler: call /autofix/webhook handler
WebhookHandler->>WebhookHandler: read headers x-autofix-signature
WebhookHandler->>WebhookHandler: const rawBody = req.rawBody || Buffer.alloc(0)
WebhookHandler->>SignatureVerifier: verifySignature(rawBody, signature)
SignatureVerifier-->>WebhookHandler: valid/invalid
alt signature valid and AUTOFIX_SECRET set
WebhookHandler-->>AutofixClient: 200 OK
else signature invalid or secret missing
WebhookHandler-->>AutofixClient: 401 Unauthorized
end
Class diagram for backend logger and /autofix webhook handlingclassDiagram
class Logger {
-WritableStream _logStream
-WritableStream _errStream
+_entry(level, eventType, msg, extra) Object
+_write(streams, obj) void
+info(eventType, msg, extra) void
+warn(eventType, msg, extra) void
+error(eventType, msg, extra) void
}
class BackendLogInit {
+LOG_DIR String
+LOG_FILE String
+ERR_FILE String
+_logStream WritableStream
+_errStream WritableStream
+initialize() void
}
class RawAutofixMiddleware {
+handle(req, res, next) void
+captureRawBody(req, res, next) void
+setReqRawBody(req) void
}
class JsonBodyParserMiddleware {
+handle(req, res, next) void
}
class WebhookHandler {
+postAutofixWebhook(req, res) Promise~void~
-getSignature(req) String
-getRawBody(req) Buffer
-handleInvalidSignature(res, reason) void
}
class SignatureVerifier {
+verifySignature(body, signature) Boolean
}
class ExpressApp {
+use(middleware) void
+post(path, handler) void
}
BackendLogInit --> Logger : configures
ExpressApp --> RawAutofixMiddleware : uses on path /autofix
ExpressApp --> JsonBodyParserMiddleware : uses globally
ExpressApp --> WebhookHandler : route /autofix/webhook
WebhookHandler --> SignatureVerifier : calls
RawAutofixMiddleware --> WebhookHandler : sets req.rawBody
Logger <.. WebhookHandler : logging usage
Logger <.. RawAutofixMiddleware : logging usage
Logger <.. BackendLogInit : logging usage
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR introduces resilience improvements to the backend logging system with lazy-created log streams and error fallback, implements secure raw request body capture for webhook signature verification, adds a new systemd-managed endpoint service on port 3001 with automated deployment integration, updates Node engine and Express versions, and elevates service process privileges from the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="prod-run.sh" line_range="427" />
<code_context>
+ say "runewager-endpoint restarted via systemd"
+ else
+ warn "systemctl restart runewager-endpoint failed — falling back to nohup"
+ pkill -f "node .*backend\.js" 2>/dev/null || true
+ sleep 1
+ nohup node "$PROJECT_DIR/backend.js" \
+ >> "$ENDPOINT_LOG" 2>> "$ENDPOINT_ERR" < /dev/null &
+ disown || true
+ say "runewager-endpoint started via nohup fallback"
+ fi
+else
+ # No systemd — direct nohup
+ pkill -f "node .*backend\.js" 2>/dev/null || true
+ sleep 1
+ if is_port_listening "$ENDPOINT_PORT"; then
</code_context>
<issue_to_address>
**issue (bug_risk):** The pkill pattern for backend.js may kill unrelated node processes
`pkill -f "node .*backend\.js"` will terminate any Node process whose command line contains `backend.js`, including ones from other apps on the same host. In multi-app or shared environments this risks killing unrelated services. Please either narrow the match (e.g., include `$PROJECT_DIR` in the pattern) or track the specific PID you start and kill only that process.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| say "runewager-endpoint restarted via systemd" | ||
| else | ||
| warn "systemctl restart runewager-endpoint failed — falling back to nohup" | ||
| pkill -f "node .*backend\.js" 2>/dev/null || true |
There was a problem hiding this comment.
issue (bug_risk): The pkill pattern for backend.js may kill unrelated node processes
pkill -f "node .*backend\.js" will terminate any Node process whose command line contains backend.js, including ones from other apps on the same host. In multi-app or shared environments this risks killing unrelated services. Please either narrow the match (e.g., include $PROJECT_DIR in the pattern) or track the specific PID you start and kill only that process.
Nitpicks 🔍
|
| User=root | ||
| Group=root |
There was a problem hiding this comment.
Suggestion: Running the Node.js service as the root user is a security vulnerability: if the process or any dependency is compromised, an attacker gains full system control, so this should instead run under a dedicated unprivileged service account (with appropriate filesystem permissions configured) to follow the principle of least privilege. [security]
Severity Level: Critical 🚨
- ❌ Telegram bot backend always runs as root on deployed hosts.
- ❌ Any RCE in `index.js` grants full system control.
- ⚠️ Undermines `ProtectSystem`/`NoNewPrivileges` hardening in unit file.| User=root | |
| Group=root | |
| User=runewager | |
| Group=runewager |
Steps of Reproduction ✅
1. Inspect the systemd unit template at `/workspace/Runewager/runewager.service` lines
24–31, where the `[Service]` section is defined, including:
- `ExecStart=/usr/bin/node /var/www/html/Runewager/index.js` (line 27)
- `User=root` (line 28)
- `Group=root` (line 29).
2. Follow the documented deployment instructions in the same file at lines 11–14 (`cp
runewager.service /etc/systemd/system/runewager.service`, `systemctl daemon-reload`,
`systemctl enable --now runewager`) to install and start the service on a VPS.
3. On the deployed host, run `systemctl status runewager` (referencing the service name
from `runewager.service`) and observe that systemd reports the main Node.js process
(`/var/www/html/Runewager/index.js`) running under `User=root`/`Group=root`, as dictated
by the unit file configuration.
4. Recognize that all application code and dependencies loaded by `index.js` (the bot's
entrypoint) now execute with full root privileges, so any remote code execution
vulnerability or path traversal in the Node/Express stack would immediately execute as
root rather than an unprivileged account, significantly increasing the impact of a
compromise compared to running under a dedicated `runewager` user.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** runewager.service
**Line:** 28:29
**Comment:**
*Security: Running the Node.js service as the root user is a security vulnerability: if the process or any dependency is compromised, an attacker gains full system control, so this should instead run under a dedicated unprivileged service account (with appropriate filesystem permissions configured) to follow the principle of least privilege.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished reviewing your PR. |
User description
Summary by Sourcery
Manage the backend endpoint process as a systemd service (with nohup fallback), harden backend logging and webhook body handling, and update runtime dependencies.
New Features:
Bug Fixes:
Enhancements:
Build:
Deployment:
CodeAnt-AI Description
Restart and harden backend endpoint startup and webhook verification
What Changed
Impact
✅ Fewer webhook signature failures✅ Fewer endpoint restart crash-loops✅ Logs still visible when disk logging fails💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
New Features
Improvements
Chores