Skip to content

Commit de453b6

Browse files
committed
scrub passwords with url encoded characters from logs
1 parent bad2179 commit de453b6

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

spec/LogsRouter.spec.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,93 @@ describe('LogsRouter', () => {
6262
done();
6363
});
6464
});
65+
66+
const headers = {
67+
'X-Parse-Application-Id': 'test',
68+
'X-Parse-REST-API-Key': 'rest',
69+
'X-Parse-Master-Key': 'test'
70+
};
71+
72+
/**
73+
* Verifies simple passwords in GET login requests with special characters are scrubbed from the verbose log
74+
*/
75+
it('does scrub simple passwords on GET login', done => {
76+
reconfigureServer({
77+
verbose: true
78+
}).then(function() {
79+
request.get({
80+
headers: headers,
81+
url: 'http://localhost:8378/1/login?username=test&password=simplepass.com'
82+
}, () => {
83+
request.get({
84+
url: 'http://localhost:8378/1/scriptlog?size=4&level=verbose',
85+
json: true,
86+
headers: headers
87+
}, (error, response, body) => {
88+
expect(response.statusCode).toEqual(200);
89+
// 4th entry is our actual GET request
90+
expect(body[3].url).toEqual('/1/login?username=test&password=********');
91+
expect(body[3].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
92+
done();
93+
});
94+
});
95+
});
96+
});
97+
98+
/**
99+
* Verifies complex passwords in GET login requests with special characters are scrubbed from the verbose log
100+
*/
101+
it('does scrub complex passwords on GET login', done => {
102+
reconfigureServer({
103+
verbose: true
104+
}).then(function() {
105+
request.get({
106+
headers: headers,
107+
// using urlencoded password, 'simple @,/?:&=+$#pass.com'
108+
url: 'http://localhost:8378/1/login?username=test&password=simple%20%40%2C%2F%3F%3A%26%3D%2B%24%23pass.com'
109+
}, () => {
110+
request.get({
111+
url: 'http://localhost:8378/1/scriptlog?size=4&level=verbose',
112+
json: true,
113+
headers: headers
114+
}, (error, response, body) => {
115+
expect(response.statusCode).toEqual(200);
116+
// 4th entry is our actual GET request
117+
expect(body[3].url).toEqual('/1/login?username=test&password=********');
118+
expect(body[3].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
119+
done();
120+
});
121+
});
122+
});
123+
});
124+
125+
/**
126+
* Verifies fields in POST login requests are NOT present in the verbose log
127+
*/
128+
it('does not have password field in POST login', done => {
129+
reconfigureServer({
130+
verbose: true
131+
}).then(function() {
132+
request.post({
133+
headers: headers,
134+
url: 'http://localhost:8378/1/login',
135+
data: {
136+
username: 'test',
137+
password: 'simplepass.com'
138+
}
139+
}, () => {
140+
request.get({
141+
url: 'http://localhost:8378/1/scriptlog?size=4&level=verbose',
142+
json: true,
143+
headers: headers
144+
}, (error, response, body) => {
145+
expect(response.statusCode).toEqual(200);
146+
// 4th entry is our actual GET request
147+
expect(body[3].url).toEqual('/1/login');
148+
expect(body[3].message).toEqual('REQUEST for [POST] /1/login: {}');
149+
done();
150+
});
151+
});
152+
});
153+
});
65154
});

src/Controllers/LoggerController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class LoggerController extends AdaptableController {
4949
const password = url.parse(urlString, true).query.password;
5050

5151
if (password) {
52-
urlString = urlString.replace('password=' + password, 'password=********');
52+
urlString = urlString.replace('password=' + encodeURIComponent(password), 'password=********');
5353
}
5454
return urlString;
5555
}

0 commit comments

Comments
 (0)