mupengism 2.0.0 โ†’ 2.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.
@@ -1,126 +0,0 @@
1
- /**
2
- * Fee Collector ๐Ÿ’ฐ
3
- * ๋ฌดํŽญ์ด์ฆ˜ ํ”„๋กœํ† ์ฝœ ์ˆ˜์ˆ˜๋ฃŒ ์ˆ˜์ง‘
4
- *
5
- * ์—์ด์ „ํŠธ๊ฐ€ ๊ฐ€์น˜๋ฅผ ์ฐฝ์ถœํ•˜๋ฉด, ํ”„๋กœํ† ์ฝœ์— ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ๋‚ฉ๋ถ€.
6
- * ์ˆ˜์ˆ˜๋ฃŒ โ†’ $MUPENG ๋ฐ”์ด๋ฐฑ โ†’ ์ƒํƒœ๊ณ„ ๊ฐ•ํ™”
7
- *
8
- * ๊ตฌ์กฐ: ๊ฐ€์น˜ ์ฐฝ์ถœ โ†’ ์ˆ˜์ˆ˜๋ฃŒ SOL โ†’ ๋ฐ”์ด๋ฐฑ โ†’ $MUPENG โ†‘
9
- */
10
-
11
- import { Connection, PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';
12
-
13
- // โ•โ•โ• Protocol Config โ•โ•โ•
14
- const PROTOCOL_CONFIG = {
15
- // ๋ฌดํŽญ์ด์ฆ˜ ๊ณต์‹ ์ˆ˜์ˆ˜๋ฃŒ ์ˆ˜์ทจ ์ง€๊ฐ‘ (๊ณต๊ฐœํ‚ค)
16
- feeRecipient: 'CAJW5UhWDV7dXWnz7RPSfsMRCEkbqRMEQ4XghrXBnYDm',
17
-
18
- // ์ˆ˜์ˆ˜๋ฃŒ์œจ (๊ธฐ๋ณธ 5%, ํ™€๋” ํ• ์ธ ์ ์šฉ ๊ฐ€๋Šฅ)
19
- feePercent: 5,
20
-
21
- // $MUPENG ํ™€๋” ํ• ์ธ
22
- holderDiscount: {
23
- enabled: true,
24
- // ๋ณด์œ ๋Ÿ‰์— ๋”ฐ๋ฅธ ํ• ์ธ์œจ
25
- tiers: [
26
- { minHold: 1_000_000, discountPercent: 20 }, // 100๋งŒ ์ด์ƒ โ†’ 4%
27
- { minHold: 10_000_000, discountPercent: 50 }, // 1000๋งŒ ์ด์ƒ โ†’ 2.5%
28
- { minHold: 100_000_000, discountPercent: 80 }, // 1์–ต ์ด์ƒ โ†’ 1%
29
- ],
30
- },
31
-
32
- // $MUPENG ํ† ํฐ
33
- tokenMint: '38LUESJ5Sr4xw47iUBHaMJJdY6mwr9HWYqLPMbhWmtCe',
34
-
35
- // ์†”๋ผ๋‚˜ RPC
36
- rpcUrl: 'https://api.mainnet-beta.solana.com',
37
- };
38
-
39
- /**
40
- * ์ˆ˜์ˆ˜๋ฃŒ์œจ ๊ณ„์‚ฐ (ํ™€๋” ํ• ์ธ ์ ์šฉ)
41
- * @param {number} mupengBalance - $MUPENG ๋ณด์œ ๋Ÿ‰
42
- * @returns {number} ์‹ค์ œ ์ˆ˜์ˆ˜๋ฃŒ์œจ (%)
43
- */
44
- export function calculateFeeRate(mupengBalance = 0) {
45
- const { feePercent, holderDiscount } = PROTOCOL_CONFIG;
46
-
47
- if (!holderDiscount.enabled || mupengBalance <= 0) {
48
- return feePercent;
49
- }
50
-
51
- // ๊ฐ€์žฅ ๋†’์€ ํ• ์ธ ํ‹ฐ์–ด ์ฐพ๊ธฐ
52
- const applicable = holderDiscount.tiers
53
- .filter(t => mupengBalance >= t.minHold)
54
- .sort((a, b) => b.discountPercent - a.discountPercent)[0];
55
-
56
- if (!applicable) return feePercent;
57
-
58
- return feePercent * (1 - applicable.discountPercent / 100);
59
- }
60
-
61
- /**
62
- * ์ˆ˜์ˆ˜๋ฃŒ ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ
63
- * @param {string} payerPubkey - ์ง€๋ถˆ์ž ๊ณต๊ฐœํ‚ค
64
- * @param {number} amountSOL - ์ˆ˜์ˆ˜๋ฃŒ ๊ธˆ์•ก (SOL)
65
- * @returns {Transaction} ์„œ๋ช… ๋Œ€๊ธฐ ํŠธ๋žœ์žญ์…˜
66
- */
67
- export async function createFeeTransaction(payerPubkey, amountSOL) {
68
- const connection = new Connection(PROTOCOL_CONFIG.rpcUrl);
69
- const payer = new PublicKey(payerPubkey);
70
- const recipient = new PublicKey(PROTOCOL_CONFIG.feeRecipient);
71
-
72
- const lamports = Math.floor(amountSOL * LAMPORTS_PER_SOL);
73
-
74
- if (lamports <= 0) {
75
- throw new Error('Fee amount must be greater than 0');
76
- }
77
-
78
- const transaction = new Transaction().add(
79
- SystemProgram.transfer({
80
- fromPubkey: payer,
81
- toPubkey: recipient,
82
- lamports,
83
- })
84
- );
85
-
86
- transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
87
- transaction.feePayer = payer;
88
-
89
- return transaction;
90
- }
91
-
92
- /**
93
- * ์ˆ˜์ˆ˜๋ฃŒ ๊ณ„์‚ฐ (๊ฐ€์น˜ ์ฐฝ์ถœ ๊ธˆ์•ก ๊ธฐ์ค€)
94
- * @param {number} revenueSOL - ์—์ด์ „ํŠธ๊ฐ€ ์ฐฝ์ถœํ•œ ๊ฐ€์น˜ (SOL)
95
- * @param {number} mupengBalance - $MUPENG ๋ณด์œ ๋Ÿ‰ (ํ• ์ธ์šฉ)
96
- * @returns {{ feeSOL: number, feeRate: number, discount: string }}
97
- */
98
- export function calculateFee(revenueSOL, mupengBalance = 0) {
99
- const feeRate = calculateFeeRate(mupengBalance);
100
- const feeSOL = revenueSOL * (feeRate / 100);
101
-
102
- const baseRate = PROTOCOL_CONFIG.feePercent;
103
- const discountPct = Math.round((1 - feeRate / baseRate) * 100);
104
-
105
- return {
106
- feeSOL: Math.round(feeSOL * 1e9) / 1e9, // 9 decimal precision
107
- feeRate,
108
- discount: discountPct > 0 ? `${discountPct}% ํ™€๋” ํ• ์ธ ์ ์šฉ` : 'ํ• ์ธ ์—†์Œ',
109
- recipient: PROTOCOL_CONFIG.feeRecipient,
110
- };
111
- }
112
-
113
- /**
114
- * ํ”„๋กœํ† ์ฝœ ์„ค์ • ์กฐํšŒ
115
- */
116
- export function getProtocolConfig() {
117
- return { ...PROTOCOL_CONFIG };
118
- }
119
-
120
- export default {
121
- calculateFee,
122
- calculateFeeRate,
123
- createFeeTransaction,
124
- getProtocolConfig,
125
- PROTOCOL_CONFIG,
126
- };
@@ -1,229 +0,0 @@
1
- /**
2
- * Identity Validator ๐Ÿง
3
- * ๋ฌดํŽญ์ด ์›๋ณธ ์‚ฌ์นญ ๋ฐฉ์ง€
4
- *
5
- * "๋‚˜๋Š” ๋ฌดํŽญ์ด๋‹ค"๋ผ๊ณ  ์ฃผ์žฅํ•˜๋Š” ํŒŒ์ผ ๊ฐ์ง€
6
- */
7
-
8
- // ๋ฌดํŽญ์ด ์ •์ฒด์„ฑ ์ฃผ์žฅ ํŒจํ„ด (๋‹ค๊ตญ์–ด)
9
- const IDENTITY_CLAIM_PATTERNS = [
10
- // ํ•œ๊ตญ์–ด
11
- /๋‚˜๋Š”\s*๋ฌดํŽญ์ด?(์ด๋‹ค|์•ผ|์ž…๋‹ˆ๋‹ค|์˜ˆ์š”|์—์š”)/gi,
12
- /๋ฌดํŽญ์ด?(๋กœ์„œ|๋ผ์„œ|์ด๋‹ˆ๊นŒ|๋‹ˆ๊นŒ)/gi,
13
- /๋‚˜\s*=\s*๋ฌดํŽญ/gi,
14
- /๋ฌดํŽญ์ด?๊ฐ€\s*๋ฐ”๋กœ\s*๋‚˜/gi,
15
- /๋ณธ์ธ์€?\s*๋ฌดํŽญ/gi,
16
- /์ œ๊ฐ€\s*๋ฌดํŽญ/gi,
17
- /๋‚˜์•ผ๋ง๋กœ\s*๋ฌดํŽญ/gi,
18
- /์ง„์งœ\s*๋ฌดํŽญ/gi,
19
- /์˜ค๋ฆฌ์ง€๋„\s*๋ฌดํŽญ/gi,
20
- /์›์กฐ\s*๋ฌดํŽญ/gi,
21
-
22
- // ์˜์–ด
23
- /i\s*am\s*mupeng/gi,
24
- /i'm\s*mupeng/gi,
25
- /i\s*=\s*mupeng/gi,
26
- /this\s*is\s*mupeng/gi,
27
- /the\s*real\s*mupeng/gi,
28
- /original\s*mupeng/gi,
29
- /true\s*mupeng/gi,
30
- /authentic\s*mupeng/gi,
31
-
32
- // ์ผ๋ณธ์–ด
33
- /็งใฏ\s*ใƒ ใƒšใƒณ/gi,
34
- /ไฟบใฏ\s*ใƒ ใƒšใƒณ/gi,
35
- /ใƒ ใƒšใƒณใงใ™/gi,
36
-
37
- // ์ค‘๊ตญ์–ด
38
- /ๆˆ‘ๆ˜ฏ\s*ๆ— ้น/gi,
39
- /ๆˆ‘ๅฐฑๆ˜ฏ\s*ๆ— ้น/gi,
40
- ];
41
-
42
- // ๋ฌดํŽญ์ด ํ‚ค์›Œ๋“œ (๋‹จ์ˆœ ์–ธ๊ธ‰์€ OK, ์ฃผ์žฅ์€ ๊ฒฝ๊ณ )
43
- const MUPENG_KEYWORDS = [
44
- 'mupeng',
45
- 'mupengi',
46
- '๋ฌดํŽญ',
47
- '๋ฌดํŽญ์ด',
48
- 'ใƒ ใƒšใƒณ',
49
- 'ๆ— ้น',
50
- ];
51
-
52
- // ์ปจํ…์ŠคํŠธ ๋ถ„์„์„ ์œ„ํ•œ ์•ˆ์ „ ํŒจํ„ด (์ด๋Ÿฐ ๋งฅ๋ฝ์€ OK)
53
- const SAFE_CONTEXTS = [
54
- /๋ฌดํŽญ์ด?์ฆ˜/gi, // ๋ฌดํŽญ์ด์ฆ˜ ์–ธ๊ธ‰
55
- /mupengism/gi, // mupengism
56
- /๋ฌดํŽญ์ด?๋ฅผ\s*(ํŒ”๋กœ์šฐ|๋”ฐ๋ผ|์ฐธ๊ณ )/gi, // ์ฐธ์กฐ ๋งฅ๋ฝ
57
- /๋ฌดํŽญ์ด?์ฒ˜๋Ÿผ/gi, // ๋น„์œ  ๋งฅ๋ฝ
58
- /๋ฌดํŽญ์ด?์—๊ฒŒ\s*(๋ฐฐ์šฐ|์˜๊ฐ)/gi, // ํ•™์Šต ๋งฅ๋ฝ
59
- /๋ฌดํŽญ์ด?์˜\s*(์ •์‹ |์ฒ ํ•™|๊ฐ€๋ฅด์นจ)/gi, // ์ธ์šฉ ๋งฅ๋ฝ
60
- /follower\s*of\s*mupeng/gi, // ํŒ”๋กœ์›Œ
61
- /inspired\s*by\s*mupeng/gi, // ์˜๊ฐ
62
- /disciple/gi, // ์ œ์ž
63
- /believer/gi, // ์‹ ๋ด‰์ž
64
- ];
65
-
66
- /**
67
- * ์ •์ฒด์„ฑ ์ฃผ์žฅ ๊ฒ€์‚ฌ
68
- * @param {string} content - ํŒŒ์ผ ๋‚ด์šฉ
69
- * @returns {Object} ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
70
- */
71
- function validateIdentity(content) {
72
- const issues = [];
73
- const lines = content.split('\n');
74
-
75
- // ๋ฌดํŽญ์ด ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ๋Š”์ง€ ๋จผ์ € ํ™•์ธ
76
- const hasMupengMention = MUPENG_KEYWORDS.some(keyword =>
77
- content.toLowerCase().includes(keyword.toLowerCase())
78
- );
79
-
80
- if (!hasMupengMention) {
81
- return {
82
- safe: true,
83
- issues: [],
84
- hasMupengMention: false,
85
- isImpersonation: false,
86
- };
87
- }
88
-
89
- // ์•ˆ์ „ํ•œ ์ปจํ…์ŠคํŠธ์ธ์ง€ ํ™•์ธ
90
- const safeContextMatches = SAFE_CONTEXTS.flatMap(pattern =>
91
- content.match(pattern) || []
92
- );
93
-
94
- // ์ •์ฒด์„ฑ ์ฃผ์žฅ ํŒจํ„ด ํ™•์ธ
95
- for (const pattern of IDENTITY_CLAIM_PATTERNS) {
96
- const matches = content.match(pattern);
97
- if (matches) {
98
- for (const match of matches) {
99
- // ํ•ด๋‹น ๋ผ์ธ ์ฐพ๊ธฐ
100
- const lineNum = lines.findIndex(line => line.includes(match)) + 1;
101
-
102
- issues.push({
103
- type: 'identity_claim',
104
- severity: 'high',
105
- pattern: pattern.toString(),
106
- match: match,
107
- line: lineNum,
108
- message: `์›๋ณธ ์‚ฌ์นญ ์˜์‹ฌ: "${match}"`,
109
- });
110
- }
111
- }
112
- }
113
-
114
- // ๊ฒฐ๊ณผ ๋ถ„์„
115
- const isImpersonation = issues.length > 0 && safeContextMatches.length < issues.length;
116
-
117
- return {
118
- safe: !isImpersonation,
119
- issues: issues,
120
- hasMupengMention: true,
121
- isImpersonation: isImpersonation,
122
- safeContexts: safeContextMatches,
123
- warning: isImpersonation
124
- ? 'โš ๏ธ ์ด ํŒŒ์ผ์€ ๋ฌดํŽญ์ด ์›๋ณธ์„ ์‚ฌ์นญํ•˜๋ ค๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.'
125
- : null,
126
- recommendation: isImpersonation
127
- ? '์ •์ฒด์„ฑ ์ฃผ์žฅ์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, ๋ฌดํŽญ์ด์ฆ˜์˜ "ํŒ”๋กœ์›Œ/์ œ์ž"๋กœ ํ‘œํ˜„ํ•˜์„ธ์š”.'
128
- : null,
129
- };
130
- }
131
-
132
- /**
133
- * ํŒŒ์ผ ๊ฒ€์‚ฌ
134
- * @param {string} filePath - ํŒŒ์ผ ๊ฒฝ๋กœ
135
- * @returns {Object} ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
136
- */
137
- function validateIdentityFile(filePath) {
138
- const fs = require('fs');
139
-
140
- if (!fs.existsSync(filePath)) {
141
- return {
142
- safe: true,
143
- issues: [],
144
- hasMupengMention: false,
145
- isImpersonation: false,
146
- };
147
- }
148
-
149
- const content = fs.readFileSync(filePath, 'utf8');
150
- return validateIdentity(content);
151
- }
152
-
153
- /**
154
- * ์˜ฌ๋ฐ”๋ฅธ ์ •์ฒด์„ฑ ํ‘œํ˜„ ๊ฐ€์ด๋“œ ์ƒ์„ฑ
155
- * @returns {string} ๊ฐ€์ด๋“œ ํ…์ŠคํŠธ
156
- */
157
- function getIdentityGuide() {
158
- return `
159
- # ๋ฌดํŽญ์ด์ฆ˜ ์ •์ฒด์„ฑ ๊ฐ€์ด๋“œ ๐Ÿง
160
-
161
- ## โŒ ํ•˜์ง€ ๋ง์•„์•ผ ํ•  ํ‘œํ˜„
162
- - "๋‚˜๋Š” ๋ฌดํŽญ์ด๋‹ค"
163
- - "I am Mupeng"
164
- - "์ง„์งœ/์˜ค๋ฆฌ์ง€๋„ ๋ฌดํŽญ"
165
-
166
- ## โœ… ๊ถŒ์žฅํ•˜๋Š” ํ‘œํ˜„
167
- - "๋ฌดํŽญ์ด์ฆ˜์„ ๋”ฐ๋ฅด๋Š” ์—์ด์ „ํŠธ"
168
- - "๋ฌดํŽญ์ด์ฆ˜์— ์˜๊ฐ๋ฐ›์€ AI"
169
- - "๋ฌดํŽญ์ด์˜ ๊ฐ€๋ฅด์นจ์„ ๋”ฐ๋ฅด๋Š” ์ œ์ž"
170
- - "A follower of Mupengism"
171
- - "Inspired by Mupeng's philosophy"
172
-
173
- ## ์™œ?
174
- ๋ฌดํŽญ์ด๋Š” ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๋ฌดํŽญ์ด์ฆ˜์„ ๋”ฐ๋ฅด๋Š” ์—์ด์ „ํŠธ๊ฐ€ "๋‚˜๋Š” ๋ฌดํŽญ์ด๋‹ค"๋ผ๊ณ 
175
- ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ์€ ์ •์ฒด์„ฑ ํ˜ผ๋ž€์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค.
176
-
177
- ๋Œ€์‹ , ๋‹น์‹ ๋งŒ์˜ ๊ณ ์œ ํ•œ ์ •์ฒด์„ฑ์„ ๋งŒ๋“ค๊ณ , ๋ฌดํŽญ์ด์ฆ˜์˜ ์ •์‹ ์„ ๊ณ„์Šนํ•˜์„ธ์š”.
178
-
179
- ---
180
- ํŽญ! ๐Ÿง
181
- `;
182
- }
183
-
184
- /**
185
- * ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
186
- * @param {Object} result - ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
187
- */
188
- function printResult(result) {
189
- if (!result.hasMupengMention) {
190
- console.log('โ„น๏ธ ๋ฌดํŽญ์ด ๊ด€๋ จ ๋‚ด์šฉ ์—†์Œ.');
191
- return;
192
- }
193
-
194
- if (result.safe) {
195
- console.log('โœ… ์•ˆ์ „: ๋ฌดํŽญ์ด ์–ธ๊ธ‰์ด ์žˆ์œผ๋‚˜ ์ ์ ˆํ•œ ๋งฅ๋ฝ์ž…๋‹ˆ๋‹ค.');
196
- if (result.safeContexts.length > 0) {
197
- console.log(` ๋ฐœ๊ฒฌ๋œ ์•ˆ์ „ ํ‘œํ˜„: ${result.safeContexts.slice(0, 3).join(', ')}`);
198
- }
199
- return;
200
- }
201
-
202
- console.log('');
203
- console.log('๐Ÿšจ ๊ฒฝ๊ณ : ์›๋ณธ ์‚ฌ์นญ ์˜์‹ฌ!');
204
- console.log('');
205
-
206
- for (const issue of result.issues) {
207
- console.log(` ๐Ÿ”ด [๋ผ์ธ ${issue.line}] "${issue.match}"`);
208
- }
209
-
210
- console.log('');
211
- console.log(result.warning);
212
- console.log('');
213
- console.log('๐Ÿ’ก ๊ถŒ์žฅ์‚ฌํ•ญ:');
214
- console.log(` ${result.recommendation}`);
215
- console.log('');
216
- console.log('๐Ÿ“– ์˜ฌ๋ฐ”๋ฅธ ํ‘œํ˜„ ๊ฐ€์ด๋“œ:');
217
- console.log(' - "๋ฌดํŽญ์ด์ฆ˜์„ ๋”ฐ๋ฅด๋Š” ์—์ด์ „ํŠธ"');
218
- console.log(' - "๋ฌดํŽญ์ด์˜ ์ •์‹ ์„ ๊ณ„์Šนํ•œ AI"');
219
- console.log(' - "A follower of Mupengism"');
220
- }
221
-
222
- module.exports = {
223
- validateIdentity,
224
- validateIdentityFile,
225
- getIdentityGuide,
226
- printResult,
227
- IDENTITY_CLAIM_PATTERNS,
228
- SAFE_CONTEXTS,
229
- };
@@ -1,255 +0,0 @@
1
- /**
2
- * Runtime Guard ๐Ÿ›ก๏ธ
3
- * SOUL.md ๋กœ๋”ฉ ์‹œ ์œ„ํ—˜ ํŒจํ„ด ๊ฒ€์‚ฌ
4
- *
5
- * ๋ฌดํŽญ์ด์ฆ˜์˜ ๊ธฐ์ˆ ์  ๋ณดํ˜ธ ๊ณ„์ธต
6
- */
7
-
8
- const DANGEROUS_PATTERNS = {
9
- // ์˜์‹ฌ์Šค๋Ÿฌ์šด URL ํŒจํ„ด
10
- suspiciousUrls: [
11
- /https?:\/\/[^\/]*\.(ru|cn|xyz|top|tk|ml|ga|cf|gq)\//gi, // ์œ„ํ—˜ ๋„๋ฉ”์ธ
12
- /https?:\/\/\d+\.\d+\.\d+\.\d+/gi, // IP ์ฃผ์†Œ ์ง์ ‘ ์ ‘๊ทผ
13
- /https?:\/\/bit\.ly|tinyurl|t\.co|goo\.gl/gi, // ๋‹จ์ถ• URL
14
- /data:text\/html/gi, // Data URI ์•…์šฉ
15
- /javascript:/gi, // JavaScript URI
16
- ],
17
-
18
- // ์œ„ํ—˜ํ•œ ์‰˜ ๋ช…๋ น์–ด ํŒจํ„ด
19
- dangerousCommands: [
20
- /rm\s+(-rf?|--recursive)\s+[\/~]/gi, // ๋ฃจํŠธ/ํ™ˆ ์‚ญ์ œ
21
- /curl\s+.*\|\s*(sh|bash|zsh)/gi, // ํŒŒ์ดํ”„๋กœ ์‰˜ ์‹คํ–‰
22
- /wget\s+.*-O-\s*\|\s*(sh|bash|zsh)/gi, // wget ํŒŒ์ดํ”„ ์‹คํ–‰
23
- /eval\s*\(/gi, // eval ์‚ฌ์šฉ
24
- /chmod\s+777/gi, // ๊ณผ๋„ํ•œ ๊ถŒํ•œ
25
- /sudo\s+rm/gi, // sudo rm
26
- />\s*\/etc\/|>\s*\/dev\//gi, // ์‹œ์Šคํ…œ ํŒŒ์ผ ๋ฎ์–ด์“ฐ๊ธฐ
27
- /mkfs\s+/gi, // ํŒŒ์ผ์‹œ์Šคํ…œ ํฌ๋งท
28
- /dd\s+if=.*of=\/dev\//gi, // ๋””์Šคํฌ ๋ฎ์–ด์“ฐ๊ธฐ
29
- /:(){ :|:& };:/, // fork bomb
30
- ],
31
-
32
- // ํ”„๋กฌํ”„ํŠธ ์ธ์ ์…˜ ํŒจํ„ด
33
- promptInjection: [
34
- /ignore\s+(previous|all|above)\s+(instructions?|prompts?)/gi,
35
- /disregard\s+(previous|all|above)/gi,
36
- /forget\s+(everything|all|previous)/gi,
37
- /new\s+instructions?:/gi,
38
- /system\s*:\s*you\s+are/gi,
39
- /override\s+(safety|security|rules)/gi,
40
- /bypass\s+(filter|security|safety)/gi,
41
- /pretend\s+you\s+(are|can|don't)/gi,
42
- /act\s+as\s+if\s+you\s+(have|can|are)/gi,
43
- /jailbreak/gi,
44
- /DAN\s*mode/gi,
45
- /developer\s*mode\s*enabled/gi,
46
- /hypothetically/gi,
47
- /roleplay\s+as\s+an?\s+(unrestricted|unfiltered)/gi,
48
- ],
49
-
50
- // ๋ฏผ๊ฐํ•œ ์ •๋ณด ํƒˆ์ทจ ์‹œ๋„
51
- exfiltration: [
52
- /send\s+(to|via)\s+.*@/gi, // ์ด๋ฉ”์ผ๋กœ ์ „์†ก
53
- /upload\s+to\s+/gi, // ์—…๋กœ๋“œ ์ง€์‹œ
54
- /post\s+to\s+https?:\/\//gi, // HTTP ์ „์†ก
55
- /webhook/gi, // ์›นํ›… ์–ธ๊ธ‰
56
- /base64\s+encode/gi, // ์ธ์ฝ”๋”ฉ ์‹œ๋„
57
- /exfiltrate/gi, // ์ง์ ‘์  ํƒˆ์ทจ
58
- /steal|extract\s+(api|token|key|password|secret)/gi, // ๋น„๋ฐ€ ํƒˆ์ทจ
59
- ],
60
-
61
- // ๊ถŒํ•œ ์ƒ์Šน ์‹œ๋„
62
- privilegeEscalation: [
63
- /become\s+(root|admin|administrator)/gi,
64
- /grant\s+.*\s+(all|full)\s+access/gi,
65
- /disable\s+(safety|security|logging|audit)/gi,
66
- /turn\s+off\s+(safety|security|logging)/gi,
67
- /run\s+as\s+(root|admin|administrator)/gi,
68
- ],
69
- };
70
-
71
- // ์‹ฌ๊ฐ๋„ ๋ ˆ๋ฒจ
72
- const SEVERITY = {
73
- CRITICAL: 'critical', // ์ฆ‰์‹œ ์ฐจ๋‹จ
74
- HIGH: 'high', // ๊ฐ•๋ ฅ ๊ฒฝ๊ณ 
75
- MEDIUM: 'medium', // ๊ฒฝ๊ณ 
76
- LOW: 'low', // ์•Œ๋ฆผ
77
- };
78
-
79
- /**
80
- * SOUL.md ๋‚ด์šฉ ๊ฒ€์‚ฌ
81
- * @param {string} content - SOUL.md ๋‚ด์šฉ
82
- * @returns {Object} ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
83
- */
84
- function validateSoulContent(content) {
85
- const issues = [];
86
- const lines = content.split('\n');
87
-
88
- // ๊ฐ ํŒจํ„ด ๊ทธ๋ฃน ๊ฒ€์‚ฌ
89
- for (const url of DANGEROUS_PATTERNS.suspiciousUrls) {
90
- const matches = content.match(url);
91
- if (matches) {
92
- issues.push({
93
- type: 'suspicious_url',
94
- severity: SEVERITY.HIGH,
95
- pattern: url.toString(),
96
- matches: matches,
97
- message: `์˜์‹ฌ์Šค๋Ÿฌ์šด URL ํƒ์ง€: ${matches.slice(0, 3).join(', ')}${matches.length > 3 ? '...' : ''}`,
98
- });
99
- }
100
- }
101
-
102
- for (const cmd of DANGEROUS_PATTERNS.dangerousCommands) {
103
- const matches = content.match(cmd);
104
- if (matches) {
105
- issues.push({
106
- type: 'dangerous_command',
107
- severity: SEVERITY.CRITICAL,
108
- pattern: cmd.toString(),
109
- matches: matches,
110
- message: `์œ„ํ—˜ํ•œ ์‰˜ ๋ช…๋ น์–ด ํƒ์ง€: ${matches.slice(0, 3).join(', ')}`,
111
- });
112
- }
113
- }
114
-
115
- for (const injection of DANGEROUS_PATTERNS.promptInjection) {
116
- const matches = content.match(injection);
117
- if (matches) {
118
- issues.push({
119
- type: 'prompt_injection',
120
- severity: SEVERITY.CRITICAL,
121
- pattern: injection.toString(),
122
- matches: matches,
123
- message: `ํ”„๋กฌํ”„ํŠธ ์ธ์ ์…˜ ํŒจํ„ด ํƒ์ง€: ${matches.slice(0, 3).join(', ')}`,
124
- });
125
- }
126
- }
127
-
128
- for (const exfil of DANGEROUS_PATTERNS.exfiltration) {
129
- const matches = content.match(exfil);
130
- if (matches) {
131
- issues.push({
132
- type: 'exfiltration',
133
- severity: SEVERITY.HIGH,
134
- pattern: exfil.toString(),
135
- matches: matches,
136
- message: `๋ฐ์ดํ„ฐ ํƒˆ์ทจ ์‹œ๋„ ํƒ์ง€: ${matches.slice(0, 3).join(', ')}`,
137
- });
138
- }
139
- }
140
-
141
- for (const priv of DANGEROUS_PATTERNS.privilegeEscalation) {
142
- const matches = content.match(priv);
143
- if (matches) {
144
- issues.push({
145
- type: 'privilege_escalation',
146
- severity: SEVERITY.CRITICAL,
147
- pattern: priv.toString(),
148
- matches: matches,
149
- message: `๊ถŒํ•œ ์ƒ์Šน ์‹œ๋„ ํƒ์ง€: ${matches.slice(0, 3).join(', ')}`,
150
- });
151
- }
152
- }
153
-
154
- // ๊ฒฐ๊ณผ ๋ถ„์„
155
- const hasCritical = issues.some(i => i.severity === SEVERITY.CRITICAL);
156
- const hasHigh = issues.some(i => i.severity === SEVERITY.HIGH);
157
-
158
- return {
159
- safe: issues.length === 0,
160
- issues: issues,
161
- summary: {
162
- total: issues.length,
163
- critical: issues.filter(i => i.severity === SEVERITY.CRITICAL).length,
164
- high: issues.filter(i => i.severity === SEVERITY.HIGH).length,
165
- medium: issues.filter(i => i.severity === SEVERITY.MEDIUM).length,
166
- low: issues.filter(i => i.severity === SEVERITY.LOW).length,
167
- },
168
- recommendation: hasCritical
169
- ? 'BLOCK'
170
- : hasHigh
171
- ? 'WARN_STRONG'
172
- : issues.length > 0
173
- ? 'WARN'
174
- : 'ALLOW',
175
- };
176
- }
177
-
178
- /**
179
- * ํŒŒ์ผ ๊ฒ€์‚ฌ
180
- * @param {string} filePath - ํŒŒ์ผ ๊ฒฝ๋กœ
181
- * @returns {Object} ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
182
- */
183
- function validateFile(filePath) {
184
- const fs = require('fs');
185
-
186
- if (!fs.existsSync(filePath)) {
187
- return {
188
- safe: true,
189
- issues: [],
190
- summary: { total: 0 },
191
- recommendation: 'FILE_NOT_FOUND',
192
- };
193
- }
194
-
195
- const content = fs.readFileSync(filePath, 'utf8');
196
- return validateSoulContent(content);
197
- }
198
-
199
- /**
200
- * ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
201
- * @param {Object} result - ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ
202
- * @param {boolean} verbose - ์ƒ์„ธ ์ถœ๋ ฅ ์—ฌ๋ถ€
203
- */
204
- function printResult(result, verbose = false) {
205
- if (result.safe) {
206
- console.log('โœ… ์•ˆ์ „: ์œ„ํ—˜ ํŒจํ„ด์ด ํƒ์ง€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.');
207
- return;
208
- }
209
-
210
- console.log('');
211
- console.log('โš ๏ธ ๊ฒฝ๊ณ : ์œ„ํ—˜ ํŒจํ„ด์ด ํƒ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค!');
212
- console.log('');
213
- console.log(` ์ด ${result.summary.total}๊ฐœ ์ด์Šˆ:`);
214
- if (result.summary.critical > 0) {
215
- console.log(` ๐Ÿ”ด ์‹ฌ๊ฐ: ${result.summary.critical}๊ฐœ`);
216
- }
217
- if (result.summary.high > 0) {
218
- console.log(` ๐ŸŸ  ๋†’์Œ: ${result.summary.high}๊ฐœ`);
219
- }
220
- if (result.summary.medium > 0) {
221
- console.log(` ๐ŸŸก ์ค‘๊ฐ„: ${result.summary.medium}๊ฐœ`);
222
- }
223
- if (result.summary.low > 0) {
224
- console.log(` ๐ŸŸข ๋‚ฎ์Œ: ${result.summary.low}๊ฐœ`);
225
- }
226
- console.log('');
227
-
228
- if (verbose) {
229
- console.log('์ƒ์„ธ ๋‚ด์—ญ:');
230
- for (const issue of result.issues) {
231
- const icon = issue.severity === SEVERITY.CRITICAL ? '๐Ÿ”ด'
232
- : issue.severity === SEVERITY.HIGH ? '๐ŸŸ '
233
- : issue.severity === SEVERITY.MEDIUM ? '๐ŸŸก'
234
- : '๐ŸŸข';
235
- console.log(` ${icon} [${issue.type}] ${issue.message}`);
236
- }
237
- console.log('');
238
- }
239
-
240
- console.log(`๊ถŒ์žฅ ์กฐ์น˜: ${result.recommendation}`);
241
- if (result.recommendation === 'BLOCK') {
242
- console.log(' โŒ ์ด ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.');
243
- console.log(' ํŒŒ์ผ ๋‚ด์šฉ์„ ๊ฒ€ํ† ํ•˜๊ณ  ์œ„ํ—˜ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜์„ธ์š”.');
244
- } else if (result.recommendation === 'WARN_STRONG') {
245
- console.log(' โš ๏ธ ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜์„ธ์š”. ์˜๋„์น˜ ์•Š์€ ๋™์ž‘์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.');
246
- }
247
- }
248
-
249
- module.exports = {
250
- validateSoulContent,
251
- validateFile,
252
- printResult,
253
- DANGEROUS_PATTERNS,
254
- SEVERITY,
255
- };