mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-06-29 05:39:31 +00:00
fix: Add security validation and sanitization for session titles
- Validate session ID format to prevent injection attacks - Sanitize title input: limit to 256 chars, filter control characters - Prevent potential security issues with malformed session titles
This commit is contained in:
parent
98795cbb71
commit
646b478075
2 changed files with 37 additions and 2 deletions
|
|
@ -143,6 +143,15 @@ export async function startVibeTunnelForward(args: string[]) {
|
|||
const controlPath = path.join(os.homedir(), '.vibetunnel', 'control');
|
||||
const sessionManager = new SessionManager(controlPath);
|
||||
|
||||
// Validate session ID format for security
|
||||
if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) {
|
||||
logger.error(
|
||||
'Invalid session ID format. Only alphanumeric characters, hyphens, and underscores are allowed.'
|
||||
);
|
||||
closeLogger();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Load existing session info
|
||||
const sessionInfo = sessionManager.loadSessionInfo(sessionId);
|
||||
|
|
@ -152,11 +161,22 @@ export async function startVibeTunnelForward(args: string[]) {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
// Sanitize the title - limit length and filter out problematic characters
|
||||
const sanitizedTitle = updateTitle
|
||||
.substring(0, 256) // Limit length
|
||||
.split('')
|
||||
.filter((char) => {
|
||||
const code = char.charCodeAt(0);
|
||||
// Allow printable characters (space to ~) and extended ASCII/Unicode
|
||||
return code >= 32 && code !== 127 && (code < 128 || code > 159);
|
||||
})
|
||||
.join('');
|
||||
|
||||
// Update the title
|
||||
sessionInfo.name = updateTitle;
|
||||
sessionInfo.name = sanitizedTitle;
|
||||
sessionManager.saveSessionInfo(sessionId, sessionInfo);
|
||||
|
||||
logger.log(`Session title updated to: ${updateTitle}`);
|
||||
logger.log(`Session title updated to: ${sanitizedTitle}`);
|
||||
closeLogger();
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const logger = createLogger('session-manager');
|
|||
|
||||
export class SessionManager {
|
||||
private controlPath: string;
|
||||
private static readonly SESSION_ID_REGEX = /^[a-zA-Z0-9_-]+$/;
|
||||
|
||||
constructor(controlPath?: string) {
|
||||
this.controlPath = controlPath || path.join(os.homedir(), '.vibetunnel', 'control');
|
||||
|
|
@ -26,6 +27,18 @@ export class SessionManager {
|
|||
this.ensureControlDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate session ID format for security
|
||||
*/
|
||||
private validateSessionId(sessionId: string): void {
|
||||
if (!SessionManager.SESSION_ID_REGEX.test(sessionId)) {
|
||||
throw new PtyError(
|
||||
'Invalid session ID format. Only alphanumeric characters, hyphens, and underscores are allowed.',
|
||||
'INVALID_SESSION_ID'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the control directory exists
|
||||
*/
|
||||
|
|
@ -45,6 +58,7 @@ export class SessionManager {
|
|||
stdinPath: string;
|
||||
sessionJsonPath: string;
|
||||
} {
|
||||
this.validateSessionId(sessionId);
|
||||
const controlDir = path.join(this.controlPath, sessionId);
|
||||
|
||||
// Create session directory
|
||||
|
|
@ -96,6 +110,7 @@ export class SessionManager {
|
|||
* Save session info to JSON file
|
||||
*/
|
||||
saveSessionInfo(sessionId: string, sessionInfo: SessionInfo): void {
|
||||
this.validateSessionId(sessionId);
|
||||
try {
|
||||
const sessionInfoStr = JSON.stringify(sessionInfo, null, 2);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue