-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from US-ELRR/elrr-improve-request-validation
Add try/catch, enhance error nmessages and remove unneeded dependencies.
- Loading branch information
Showing
10 changed files
with
244 additions
and
232 deletions.
There are no files selected for viewing
50 changes: 18 additions & 32 deletions
50
src/main/java/com/deloitte/elrr/datasync/DatasyncApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,36 @@ | ||
/** | ||
* | ||
*/ | ||
|
||
package com.deloitte.elrr.datasync; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.boot.web.client.RestTemplateBuilder; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.core.env.Environment; | ||
import org.springframework.scheduling.annotation.EnableScheduling; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
|
||
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; | ||
|
||
@SpringBootApplication | ||
@EnableScheduling | ||
@ComponentScan({ "com.deloitte.elrr" }) | ||
@ComponentScan({"com.deloitte.elrr"}) | ||
@EnableEncryptableProperties | ||
public class DatasyncApplication { | ||
|
||
/** | ||
* | ||
*/ | ||
@Autowired | ||
private Environment env; | ||
|
||
/** | ||
* | ||
* @param args | ||
*/ | ||
public static void main(final String[] args) { | ||
SpringApplication.run(DatasyncApplication.class, args); | ||
} | ||
|
||
/** | ||
* This for returning the Rest Template. | ||
* | ||
* @param builder | ||
* @return RestTemplate | ||
*/ | ||
@Bean | ||
public RestTemplate restTemplate(final RestTemplateBuilder builder) { | ||
return builder.build(); | ||
} | ||
/** | ||
* @param args | ||
*/ | ||
public static void main(final String[] args) { | ||
SpringApplication.run(DatasyncApplication.class, args); | ||
} | ||
|
||
/** | ||
* This for returning the Rest Template. | ||
* | ||
* @param builder | ||
* @return RestTemplate | ||
*/ | ||
@Bean | ||
public RestTemplate restTemplate(final RestTemplateBuilder builder) { | ||
return builder.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
178 changes: 102 additions & 76 deletions
178
src/main/java/com/deloitte/elrr/datasync/SanatizingFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,123 @@ | ||
package com.deloitte.elrr.datasync; | ||
|
||
import fr.spacefox.confusablehomoglyphs.Confusables; | ||
import jakarta.servlet.*; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
import java.io.IOException; | ||
import java.util.Iterator; | ||
|
||
import org.json.JSONException; | ||
import org.json.JSONObject; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.StringUtils; | ||
|
||
import java.io.IOException; | ||
import java.util.Iterator; | ||
|
||
import fr.spacefox.confusablehomoglyphs.Confusables; | ||
import jakarta.servlet.Filter; | ||
import jakarta.servlet.FilterChain; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.ServletRequest; | ||
import jakarta.servlet.ServletResponse; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Component | ||
@Slf4j | ||
public class SanatizingFilter implements Filter { | ||
|
||
|
||
private boolean invalidParam; | ||
private boolean invalidParam; | ||
|
||
@Override | ||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | ||
throws IOException, ServletException { | ||
|
||
HttpServletResponse httpResponse = (HttpServletResponse) response; | ||
WrappedHttp httpRequest; | ||
invalidParam = false; | ||
|
||
StringBuilder body = new StringBuilder(); | ||
for(String line : request.getReader().lines().toList()) { | ||
if(InputSanatizer.isValidInput(line)) { | ||
body.append(line); | ||
body.append('\n'); | ||
|
||
} | ||
else { | ||
log.error("Illegal line in request body: " + line); | ||
httpResponse.sendError(HttpStatus.BAD_REQUEST.value(), "Illegal line in request body: " + line); | ||
} | ||
} | ||
if(httpResponse.isCommitted()) | ||
return; | ||
|
||
@Override | ||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | ||
throws IOException, ServletException { | ||
|
||
httpRequest = new WrappedHttp((HttpServletRequest) request, body.toString()); | ||
httpRequest.getParameterMap(); //might help to cache parameters for future filter chain | ||
HttpServletResponse httpResponse = (HttpServletResponse) response; | ||
WrappedHttp httpRequest; | ||
invalidParam = false; | ||
|
||
//below we check each parameter string for any invalid values | ||
httpRequest.getParameterNames().asIterator().forEachRemaining((param) -> { | ||
String paramVal = request.getParameter(param); | ||
if(!InputSanatizer.isValidInput(paramVal)) { | ||
invalidParam = true; | ||
} | ||
}); | ||
|
||
if(invalidParam) { | ||
log.error("Illegal Parameter Value"); | ||
httpResponse.sendError(HttpStatus.BAD_REQUEST.value(), "Illegal Parameter Value"); | ||
return; | ||
} | ||
StringBuilder body = new StringBuilder(); | ||
try { | ||
for (String line : request.getReader().lines().toList()) { | ||
if (InputSanatizer.isValidInput(line)) { | ||
body.append(line); | ||
body.append('\n'); | ||
} else { | ||
log.error("Illegal line in request body: " + line); | ||
httpResponse.sendError( | ||
HttpStatus.BAD_REQUEST.value(), "Illegal line in request body: " + line); | ||
} | ||
} | ||
} catch (IOException e) { | ||
log.error("Error: " + e.getMessage()); | ||
e.printStackTrace(); | ||
return; | ||
} | ||
|
||
if (hasHomoGlyphs(httpRequest)) | ||
{ | ||
log.error("Request body contains homoglyphs."); | ||
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request body contains homoglyphs."); | ||
return; | ||
} | ||
if (httpResponse.isCommitted()) return; | ||
|
||
chain.doFilter(httpRequest, response); | ||
} | ||
httpRequest = new WrappedHttp((HttpServletRequest) request, body.toString()); | ||
httpRequest.getParameterMap(); // might help to cache parameters for future filter chain | ||
|
||
private static boolean hasHomoGlyphs(WrappedHttp httpRequest) { | ||
if(!StringUtils.hasLength(httpRequest.getBody())) | ||
{ | ||
return false; | ||
} | ||
Confusables confusables = Confusables.fromInternal(); | ||
JSONObject jsonObject = new JSONObject(httpRequest.getBody()); | ||
Iterator keys = jsonObject.keys(); | ||
while (keys.hasNext()) { | ||
String key = (String) keys.next(); | ||
String value = (String) jsonObject.get(key); | ||
boolean dangerousKey = confusables.isDangerous(key); | ||
boolean dangerousValue = confusables.isDangerous(value); | ||
if (dangerousKey || dangerousValue) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
// Check each parameter string for any invalid values | ||
httpRequest | ||
.getParameterNames() | ||
.asIterator() | ||
.forEachRemaining( | ||
(param) -> { | ||
String paramVal = request.getParameter(param); | ||
if (!InputSanatizer.isValidInput(paramVal)) { | ||
invalidParam = true; | ||
log.error("Illegal Parameter Value " + paramVal); | ||
} | ||
}); | ||
|
||
} | ||
if (invalidParam) { | ||
try { | ||
httpResponse.sendError(HttpStatus.BAD_REQUEST.value(), "Illegal Parameter Value"); | ||
return; | ||
} catch (IOException e) { | ||
log.error("Error: " + e.getMessage()); | ||
e.printStackTrace(); | ||
return; | ||
} | ||
} | ||
|
||
if (hasHomoGlyphs(httpRequest)) { | ||
try { | ||
log.error("Request body contains homoglyphs."); | ||
httpResponse.sendError( | ||
HttpServletResponse.SC_BAD_REQUEST, "Request body contains homoglyphs."); | ||
return; | ||
} catch (IOException | JSONException e) { | ||
log.error("Error: " + e.getMessage()); | ||
e.printStackTrace(); | ||
return; | ||
} | ||
} | ||
|
||
try { | ||
chain.doFilter(httpRequest, response); | ||
} catch (IOException | ServletException e) { | ||
log.error("Error: " + e.getMessage()); | ||
e.printStackTrace(); | ||
return; | ||
} | ||
} | ||
|
||
private static boolean hasHomoGlyphs(WrappedHttp httpRequest) { | ||
if (!StringUtils.hasLength(httpRequest.getBody())) { | ||
return false; | ||
} | ||
Confusables confusables = Confusables.fromInternal(); | ||
JSONObject jsonObject = new JSONObject(httpRequest.getBody()); | ||
Iterator keys = jsonObject.keys(); | ||
while (keys.hasNext()) { | ||
String key = (String) keys.next(); | ||
String value = (String) jsonObject.get(key); | ||
boolean dangerousKey = confusables.isDangerous(key); | ||
boolean dangerousValue = confusables.isDangerous(value); | ||
if (dangerousKey || dangerousValue) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
Oops, something went wrong.