Skip to content

Commit 4282bd9

Browse files
committed
Privacy Violation: Heap Inspection from secret manager
1 parent 1bc6de5 commit 4282bd9

File tree

7 files changed

+202
-4
lines changed

7 files changed

+202
-4
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ target/
2121
*.ear
2222
*.iml
2323
.gradle/
24-
.mvn/
25-
.mvn/wrapper/
2624

2725
# Logs and temp files
2826
*.log

Path Manipulation/while File Read/java/fileread.pathmanipulation/src/main/java/securecodingexamples/fileread/pathmanipulation/DownloadController.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ private static boolean isValidName(String filename) {
110110
private static String validFilename(String filename) {
111111
int dotIndex = filename.lastIndexOf(".");
112112
String name = filename.substring(0, dotIndex);
113-
String extension = filename.substring(dotIndex + 1);
113+
name = name.replaceAll("[^a-zA-Z0-9-_]", "_");
114+
String extension = filename.substring(dotIndex + 1).toLowerCase();
115+
extension = extension.replaceAll("[^a-zA-Z0-9]", "");
114116
return name + "." + extension;
115117
}
116118
}

Path Manipulation/while File Read/python/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ python run.py
3838
2. Open in Browser:
3939
```
4040
http://127.0.0.1:5000
41-
```
41+
```

Path Manipulation/while File Upload/java/fileupload.pathmanipulation/src/main/java/securecodingexamples/fileupload/pathmanipulation/UploadController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ private static boolean isValidName(String filename) {
100100
private static String validFilename(String filename) {
101101
int dotIndex = filename.lastIndexOf(".");
102102
String name = filename.substring(0, dotIndex);
103+
name = name.replaceAll("[^a-zA-Z0-9-_]", "_");
103104
String extension = filename.substring(dotIndex + 1).toLowerCase();
105+
extension = extension.replaceAll("[^a-zA-Z0-9]", "");
104106
return name + "." + extension;
105107
}
106108

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using System.IO;
3+
using System.Runtime.InteropServices;
4+
using System.Text.Json;
5+
using System.Security;
6+
using Amazon;
7+
using Amazon.SecretsManager;
8+
using Amazon.SecretsManager.Model;
9+
10+
public class HeapInspectionSecureStringExample
11+
{
12+
public static SecureString GetPasswordFromSecretsManager(string secretName)
13+
{
14+
using (var client = new AmazonSecretsManagerClient(RegionEndpoint.USEast1)) // Change to your AWS region
15+
{
16+
var request = new GetSecretValueRequest { SecretId = secretName };
17+
GetSecretValueResponse result = client.GetSecretValueAsync(request).Result;
18+
19+
SecureString securePassword = new SecureString();
20+
21+
if (result.SecretBinary != null)
22+
{
23+
// Handling binary secrets
24+
byte[] decodedBinarySecret = Convert.FromBase64String(result.SecretBinary.ToString());
25+
string secretString = System.Text.Encoding.UTF8.GetString(decodedBinarySecret);
26+
ExtractPasswordToSecureString(secretString, securePassword);
27+
}
28+
else
29+
{
30+
// Handling JSON or plaintext secrets
31+
ExtractPasswordToSecureString(result.SecretString, securePassword);
32+
}
33+
34+
// Overwrite the original string immediately
35+
OverwriteString(result.SecretString);
36+
37+
return securePassword;
38+
}
39+
}
40+
41+
private static void ExtractPasswordToSecureString(string secret, SecureString securePassword)
42+
{
43+
if (!string.IsNullOrEmpty(secret))
44+
{
45+
try
46+
{
47+
var secretJson = JsonSerializer.Deserialize<JsonElement>(secret);
48+
if (secretJson.TryGetProperty("password", out JsonElement passwordElement))
49+
{
50+
string password = passwordElement.GetString();
51+
foreach (char c in password)
52+
{
53+
securePassword.AppendChar(c);
54+
}
55+
securePassword.MakeReadOnly(); // Secure the SecureString
56+
}
57+
}
58+
catch (Exception ex)
59+
{
60+
Console.WriteLine("Error parsing secret JSON: " + ex.Message);
61+
}
62+
}
63+
}
64+
65+
private static void OverwriteString(string str)
66+
{
67+
if (!string.IsNullOrEmpty(str))
68+
{
69+
char[] chars = str.ToCharArray();
70+
for (int i = 0; i < chars.Length; i++)
71+
{
72+
chars[i] = '\0'; // Overwrite memory
73+
}
74+
}
75+
}
76+
77+
public static void UseSecureString(SecureString securePassword)
78+
{
79+
IntPtr ptr = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
80+
try
81+
{
82+
string password = Marshal.PtrToStringUni(ptr); // Extract password safely
83+
84+
// Construct connection string
85+
StringBuilder connectionString = new StringBuilder("jdbc:sqlserver://localhost:1433;encrypt=true;user=sa;password=")
86+
.Append(password)
87+
.Append(";columnEncryptionSetting=Enabled;");
88+
89+
Console.WriteLine("Connection String: " + connectionString);
90+
91+
// Overwrite password in memory
92+
OverwriteString(password);
93+
}
94+
finally
95+
{
96+
Marshal.ZeroFreeGlobalAllocUnicode(ptr); // Clears memory securely
97+
}
98+
}
99+
100+
public static void Main(string[] args)
101+
{
102+
SecureString securePassword = GetPasswordFromSecretsManager("MyDatabaseSecret");
103+
104+
try
105+
{
106+
UseSecureString(securePassword);
107+
}
108+
finally
109+
{
110+
securePassword.Dispose(); // Clears memory securely
111+
}
112+
}
113+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import com.amazonaws.regions.Regions;
2+
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
3+
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
4+
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
5+
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
6+
import org.identityconnectors.common.security.GuardedString;
7+
8+
import java.nio.charset.StandardCharsets;
9+
import java.nio.ByteBuffer;
10+
11+
public class HeapInspectionGuardedStringExample {
12+
13+
public static GuardedString getPasswordFromSecretsManager(String secretName) {
14+
AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard()
15+
.withRegion(Regions.US_EAST_1) // Change to your AWS region
16+
.build();
17+
18+
GetSecretValueRequest request = new GetSecretValueRequest()
19+
.withSecretId(secretName);
20+
21+
GetSecretValueResult result = client.getSecretValue(request);
22+
23+
char[] passwordChars;
24+
if (result.getSecretBinary() != null) {
25+
// Convert binary secret to char array
26+
ByteBuffer secretBinary = result.getSecretBinary();
27+
byte[] secretBytes = new byte[secretBinary.remaining()];
28+
secretBinary.get(secretBytes);
29+
passwordChars = new String(secretBytes, StandardCharsets.UTF_8).toCharArray();
30+
31+
// Overwrite the original byte array immediately
32+
overwriteByteArray(secretBytes);
33+
} else {
34+
// Fallback to getSecretString() (only use if necessary)
35+
passwordChars = result.getSecretString().toCharArray();
36+
37+
// Overwrite the original string immediately
38+
overwriteString(result.getSecretString());
39+
}
40+
41+
return new GuardedString(passwordChars);
42+
}
43+
44+
private static void overwriteByteArray(byte[] bytes) {
45+
if (bytes != null) {
46+
java.util.Arrays.fill(bytes, (byte) 0); // Overwrite memory
47+
}
48+
}
49+
50+
private static void overwriteString(String str) {
51+
if (str != null) {
52+
char[] chars = str.toCharArray();
53+
java.util.Arrays.fill(chars, '\0'); // Overwrite memory
54+
}
55+
}
56+
57+
public static void usePasswordSecurely(GuardedString guardedPassword) {
58+
// Securely access the password value
59+
guardedPassword.access(chars -> {
60+
// Construct the connection string securely
61+
StringBuffer connectionString = new StringBuffer("jdbc:sqlserver://localhost:1433;encrypt=true;user=sa;password=")
62+
.append(chars)
63+
.append(";columnEncryptionSetting=Enabled;");
64+
65+
System.out.println("Connection String: " + connectionString);
66+
67+
// Overwrite the password in memory after use
68+
overwriteCharArray(chars);
69+
});
70+
}
71+
72+
public static void main(String[] args) {
73+
GuardedString password = getPasswordFromSecretsManager("myDatabasePassword");
74+
75+
try {
76+
usePasswordSecurely(password);
77+
} finally {
78+
password.dispose(); // Clears memory securely
79+
}
80+
}
81+
}

Unrestriced File Upload/java/src/main/java/securecodingexamples/unrestricted/fileupload/UploadController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ private static boolean isValidName(String filename) {
131131
private static String validFilename(String filename) {
132132
int dotIndex = filename.lastIndexOf(".");
133133
String name = filename.substring(0, dotIndex);
134+
name = name.replaceAll("[^a-zA-Z0-9-_]", "_");
134135
String extension = filename.substring(dotIndex + 1).toLowerCase();
136+
extension = extension.replaceAll("[^a-zA-Z0-9]", "");
135137
return name + "." + extension;
136138
}
137139

0 commit comments

Comments
 (0)