Skip to content

Commit 65860ab

Browse files
fix(security): replace passwords whereever they could be used for output
1 parent 9dfe033 commit 65860ab

File tree

4 files changed

+57
-7
lines changed

4 files changed

+57
-7
lines changed

src/main/java/net/hexonet/apiconnector/APIClient.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,31 @@ public APIClient disableDebugMode() {
8484
return this;
8585
}
8686

87+
/**
88+
* Method to use to encode data before sending it to the API Server
89+
*
90+
* @param cmd The command to request
91+
* @return
92+
*/
93+
public String getPOSTData(Map<String, String> cmd) {
94+
return this.getPOSTData(cmd, false);
95+
}
8796

8897
/**
8998
* Method to use to encode data before sending it to the API server
9099
*
91-
* @param cmd The command to request
100+
* @param cmd The command to request
101+
* @param secured if password data shall be secured for output purposes
92102
* @return the ready to use, encoded request payload
93103
*/
94-
public String getPOSTData(Map<String, String> cmd) {
95-
StringBuilder data = new StringBuilder(this.socketConfig.getPOSTData());
104+
public String getPOSTData(Map<String, String> cmd, boolean secured) {
105+
String pd;
106+
if (secured) {
107+
pd = this.socketConfig.getPOSTData().replaceAll("s_pw=[^&]+", "s_pw=***");
108+
} else {
109+
pd = this.socketConfig.getPOSTData();
110+
}
111+
StringBuilder data = new StringBuilder(pd);
96112
try {
97113
StringBuilder tmp = new StringBuilder("");
98114
Iterator<Map.Entry<String, String>> it = cmd.entrySet().iterator();
@@ -113,9 +129,10 @@ public String getPOSTData(Map<String, String> cmd) {
113129
}
114130
}
115131
}
132+
pd = tmp.toString().replaceAll("PASSWORD=[^\n]+", "PASSWORD=***");
116133
data.append(URLEncoder.encode("s_command", "UTF-8"));
117134
data.append("=");
118-
data.append(URLEncoder.encode(tmp.toString(), "UTF-8").replace("*", "%2A"));
135+
data.append(URLEncoder.encode(pd, "UTF-8").replace("*", "%2A"));
119136
return data.toString();
120137
} catch (UnsupportedEncodingException e) {
121138
return "";
@@ -431,6 +448,7 @@ public Response request(Map<String, Object> cmd) {
431448

432449
// request command to API
433450
String data = this.getPOSTData(newcmd);
451+
String secured = this.getPOSTData(newcmd, true);
434452

435453
StringBuilder response;
436454
try {
@@ -480,7 +498,7 @@ public Response request(Map<String, Object> cmd) {
480498
}
481499
Response r = new Response(response.toString(), newcmd);
482500
if (this.debugMode) {
483-
System.out.println(data);
501+
System.out.println(secured);
484502
System.out.println(newcmd);
485503
System.out.println(r.getPlain());
486504
}

src/main/java/net/hexonet/apiconnector/Response.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class Response extends ResponseTemplate {
4545
public Response(String raw, Map<String, String> cmd) {
4646
super(raw);
4747
this.command = new HashMap<String, String>(cmd);
48+
if (this.command.containsKey("PASSWORD")) { // make password no longer accessible
49+
this.command.replace("PASSWORD", "***");
50+
}
4851
this.columnkeys = new ArrayList<String>();
4952
this.columns = new ArrayList<Column>();
5053
this.recordIndex = 0;

src/test/java/net/hexonet/apiconnector/APIClientTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ public void getPOSTData2() {
4343
assertEquals(validate, enc);
4444
}
4545

46+
/**
47+
* Test getPOSTData method #3
48+
*/
49+
@Test
50+
public void getPOSTDataSecured() {
51+
APIClient cl = new APIClient();
52+
cl.setCredentials("test.user", "test.passw0rd");
53+
Map<String, String> cmd = new HashMap<String, String>();
54+
cmd.put("COMMAND", "CheckAuthentication");
55+
cmd.put("SUBUSER", "test.user");
56+
cmd.put("PASSWORD", "test.passw0rd");
57+
String enc = cl.getPOSTData(cmd, true);
58+
String str =
59+
"s_entity=54cd&s_login=test.user&s_pw=***&s_command=SUBUSER%3Dtest.user%0APASSWORD%3D%2A%2A%2A%0ACOMMAND%3DCheckAuthentication";
60+
assertEquals(str, enc);
61+
}
62+
4663
/**
4764
* Test enableDebugMode method
4865
*/

src/test/java/net/hexonet/apiconnector/ResponseTest.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public class ResponseTest {
2121
*/
2222
@Test
2323
public void getCommandPlain() {
24-
// ensure no vars are returned in response, just in case no place holder replacements are
25-
// provided
2624
Map<String, String> cmd = new HashMap<String, String>();
2725
cmd.put("COMMAND", "QueryDomainOptions");
2826
cmd.put("DOMAIN0", "example.com");
@@ -32,6 +30,20 @@ public void getCommandPlain() {
3230
assertEquals(str, r.getCommandPlain());
3331
}
3432

33+
/**
34+
* Test getCommandPlain method: secured passwords
35+
*/
36+
@Test
37+
public void getCommandPlainSecure() {
38+
Map<String, String> cmd = new HashMap<String, String>();
39+
cmd.put("COMMAND", "CheckAuthentication");
40+
cmd.put("SUBUSER", "test.user");
41+
cmd.put("PASSWORD", "test.passw0rd");
42+
Response r = new Response("", cmd);
43+
String str = "SUBUSER = test.user\nCOMMAND = CheckAuthentication\nPASSWORD = ***\n";
44+
assertEquals(str, r.getCommandPlain());
45+
}
46+
3547
/**
3648
* Test getCurrentPageNumber method #1
3749
*/

0 commit comments

Comments
 (0)