Skip to content

Commit f5ef1fd

Browse files
committed
security(git): fix command injection vulnerability 🔒
1 parent bc9e9a0 commit f5ef1fd

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

src/utils/git.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { execSync } = require('child_process')
1+
const { execSync, spawnSync } = require('child_process')
22

33
class GitUtils {
44
static isGitRepository() {
@@ -62,8 +62,31 @@ class GitUtils {
6262
}
6363

6464
static commit(message) {
65+
// Input validation
66+
if (!message || typeof message !== 'string') {
67+
throw new Error('Commit message must be a non-empty string')
68+
}
69+
70+
// Sanitize message length (git has practical limits)
71+
if (message.length > 72 * 50) { // ~50 lines of 72 chars
72+
throw new Error('Commit message too long (max 3600 characters)')
73+
}
74+
6575
try {
66-
execSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, { encoding: 'utf8' })
76+
// Use spawnSync with argument array to prevent command injection
77+
const result = spawnSync('git', ['commit', '-m', message], {
78+
encoding: 'utf8',
79+
stdio: ['ignore', 'pipe', 'pipe']
80+
})
81+
82+
if (result.error) {
83+
throw new Error('Git command failed: ' + result.error.message)
84+
}
85+
86+
if (result.status !== 0) {
87+
throw new Error('Git commit failed: ' + (result.stderr || 'Unknown error'))
88+
}
89+
6790
return true
6891
} catch (error) {
6992
throw new Error('Failed to commit: ' + error.message)

0 commit comments

Comments
 (0)