How can i make sure that passing parameters don't have any cross site scripting contents - rest

I am creating Rest Web services Using Spring & passing parameters to the method from model class.
My inputs parameters are as
{
"user_id": 23,
"user_email_id": "q#q.c",
"user_password": "fdsdsdf",
"firstname": "<script>window.alert(‘surprise!’);</script>",
"lastname": "kdfgkdf",
"mobile_number": "1414141414",
"user_status": 1,
"isdeleted": 0,
"created_by": 1,
"profile_picturename": "kfksdjfhksjd",
"address": "sfdsdfsd"
}
& My ReST controller method is as
#RequestMapping(value = "/validate", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public Object AddUser(#Valid #RequestBody UserInputModel userInputModel, BindingResult br, HttpServletResponse response) throws Exception {
//Logic
}
Here i want to make sure that passing parameter dont contain any Xss or how can i make sure that HTML encoder will work for my input model
Thanks in advance

Use Hibernate Validator's #SafeHtml annotation:
https://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html/ch02.html#validator-defineconstraints-hv-constraints
You need to add jsoup as a dependency
Example:
#Entity
public class Foo {
#SafeHtml(...)
private String firstName;
}
Then if you validate the entity, it will be not valid if firstName contains xss

Related

REST Api Spring boot with mongodb how to get json?

#GetMapping("/getAccount")
public Account validateAccount(#RequestBody) {
}
Very new to spring boot. My account file has 5+ values all strings, username, password, id, and some etc things.
Given this
{
"username": "bob"
"password": "password"
}
It should give this with 200 response code OK
{
"id": "45645646546"
"username": "bob"
"password": "password"
"status": "Single"
"filler": "filler"
}
However I'm not sure how to read the "username" and "password" json in my validateAccount function
Not really related to this question but does anyone know how to send a response code in the function? Like .sendresponseheader(400) something like that
public class AccountDTO {
#JsonIgnore
private Long id;
#NotNull
private String username;
#NotNull
private String password;
#JsonIgnore
private String status;
#JsonIgnore
private String filler;
// getters & setters
}
You may want to create a DTO (Data Transaction Object) as shown above. Here's a link to it's wiki.
Next pass map user input into this DTO using #RequestBody annotation.
#RestController
public class AccountController {
#GetMapping("/accounts")
public ResponseEntity<Account> validateAccount(#RequestBody AccountDTO accountDTO) {
return new ResponseEntity<>(accountService.validate(accountDTO), HttpStatus.OK);
}
}
Or you can use
#RestController
public class AccountController {
#GetMapping("/accounts")
public Response validateAccount(#RequestBody AccountDTO accountDTO) {
return new ResponseEntity().ok(accountService.validate(accountDTO));
}
}
The user input will be converted from json to AccountDTO using whatever JSON processor your're using most probably it'll be com.fasterxml.jackson.core.
The #JsonIgnore and #NotNull annotation will ensure only username and password fields are used and others are ignored while taking input from user.
You can pass this DTO to your service classes and use something like findByUsername() in your Business Logic and return populated AccountDTO using the below mapper function or some external libraries like Model Mapper or MapStruct.
public toAccountDTO(Account account) {
AccountDTO accountDTO = new AccountDTO();
accountDTO.setUsername(account.getUsername());
// and so on...
return accountDTO;
}
And for your last query, wrap the returned AccountDTO object in ResponseEntity wrapper to provide a proper Response Code with your payload. Here's a link to ResponseEntity Java docs.
AccountDto.java
===============
class AccountDto{
private Long id;
private String username;
private String password;
private String status;
private String filler;
//getters & setters
}
#GetMapping("/getAccount")
public ResponseEntity validateAccount(#RequestBody AccountDto accountDto) {
return new ResponseEntity<>(accountServie.validate(accountDto),HttpStatus.OK);
}
You can do your custom operations before returning the response. Take a look Best Practice of REST
For json response nothing specific just mark class with #RestController.
For #RequestBody just use a pojo to bind the values
For error code and status you can use ResponseEntity

RestAssured, POJO and dealing with lists

I'm writing a test for an API and at one endpoint I get JOSN in response with couple arrays into one array.
Can I make POJO class which mapping those array/arrays into a class object?
for example, JSON in response looks like this:
{
"total": 55,
"limit": 500,
"skip": 0,
"data": [
{
"id": 13,
"email": "probe#gmail.com",
"phone": "121-121-123",
"firstName": "Prob",
"lastName": "Buraz",
"platforms": [
{
"id": 3,
"name": "Dowe Assis",
"url": "ins.probe.com",
"user_platforms": {
"id": 496,
"userId": 13,
"platformId": 100,
"user_id": 82
}
}
], .....
And so on. I suppose that I can use this class for mapping response into POJO:
#JsonIgnoreProperties(ignoreUnknown = true)
public class GetUsers {
public Integer total;
public Integer limit;
public List<DataReference> data;
#JsonIgnoreProperties(ignoreUnknown = true)
public static class DataReference{
public int id;
public String email;
public String phone;
public String firstName;
public String lastName;
public List<Platform> platforms;
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Platform{
public Integer id;
public String name;
public String url;
}
}
}
But in the test code i can get nothing more then data elements. platforms elements are untouchable:
GetUsers users = given()
.header("Authorization",
"Bearer " + adminToken) //
.when()
.get()
.then()//.log().all()
.statusCode(200)//.log().all()
.extract().as(GetUsers.class);
i can checks values of array data like those:
assertThat(users.data).extracting(user -> user.email).contains("probe1#gmail.com", probe+2#gmail.com, ... );
But i can't access to any value of users.data.platforms.name or users.data.platforms.id and so on.
How I can access to platform element for one of users?
users.data.platforms.name
How i can do that (access platforms data) for one or for all listed users in data array?
Which library you are using for JSON POJO mapping?
If there is no error with mapping then platform variable can be accessed using following.
Add getter setter in POJO
users.getData.getindex(0).getplatforms.getindex(0).getid();
users is object of GetUsers Class which is used to map the JSON response.

Optional #Pathvariable in REST controller spring 4

I'm writing a Rest Service (HTTP Get endpoint), where in the below uri does the following
http://localhost:8080/customers/{customer_id}
fetch the details for the customer_id passed in the uri
if the customer_id is not passed (http://localhost:8080/customers), fetch all the customers details.
Code:
#RequestMapping(method = RequestMethod.GET, value = "customers/{customer_id}")
public List<Customer> getCustomers(
#PathVariable(name = "customer_id", required = false) final String customerId) {
LOGGER.debug("customer_id {} received for getCustomers request", customerId);
}
However, with the above code, for the second scenario control is flowing to getCustomers().
Note: I'm using Java8 and spring-web 4.3.10 version
Highly appreciate any help on this.
Optional #PathVariable is used only if you want to map both GET /customers/{customer_id} and GET customers into single java method.
You cannot send request which will be sent to GET /customers/{customer_id} if you don't send customer_id.
So in your case it will be:
#RequestMapping(method = RequestMethod.GET, value = {"/customers", "customers/{customer_id}"})
public List<Customer> getCustomers(#PathVariable(name = "customer_id", required = false) final String customerId) {
LOGGER.debug("customer_id {} received for getCustomers request", customerId);
}
public abstract boolean required
Whether the path variable is required.
Defaults to true, leading to an exception being thrown if the path variable is missing in the incoming request. Switch this to false if you prefer a null or Java 8 java.util.Optional in this case. e.g. on a ModelAttribute method which serves for different requests.
You can use null or Optional from java8
This may help someone that is trying to use multiple optional path variables.
If you have more than one variable, you can always accept multiple paths.
For instance:
#GetMapping(value = {"customers/{customerId}&{startDate}&{endDate}",
"customers/{customerId}&{startDate}&",
"customers/{customerId}&&{endDate}",
"customers/{customerId}&&"
})
public Customer getCustomerUsingFilter(#PathVariable String customerId, #PathVariable Optional<Date> startDate, #PathVariable Optional<Date> endDate)
Then you would call this URL using all the path separators (in this case &)
Like GET /customers/1&& or
GET /customers/1&&2018-10-31T12:00:00.000+0000 or
GET /customers/1&2018-10-31T12:00:00.000+0000& or
GET /customers/1&2018-10-31T12:00:00.000+0000&2018-10-31T12:00:00.000+0000
You should create two end-point here to handle the individual request :
#GetMapping("/customers")
public List<Customer> getCustomers() {
LOGGER.debug("Fetching all customer");
}
#GetMapping("/customers/{id}")
public List<Customer> getCustomers(#PathVariable("id") String id) {
LOGGER.debug("Fetching customer by Id {} ",id);
}
#GetMapping is equivalent to #RequestMapping(method = RequestMethod.GET) and #GetMapping("/customers/{id}") is equivalent to #RequestMapping(method = RequestMethod.GET, value = "customers/{id}")
Better approach would be like this :
#RestController
#RequestMapping("/customers")
public class CustomerController {
#GetMapping
public List<Customer> getAllCustomers() {
LOGGER.debug("Fetching all customer");
}
#GetMapping("/{id}")
public Customer getCustomerById(#PathVariable("id") String id) {
LOGGER.debug("Fetching customer by Id {} ",id);
}

How to return dynamic field from restful json webservice

I have created restful json webservice using Sprint MVC and jackson jars.
My controller looks like this :-
#Controller
public class AdminController {
#RequestMapping(value = "/fetchMyData", method = RequestMethod.POST)
public #ResponseBody MyResponse getDynamicResponse(#RequestBody UserRequest userRequest) {
MyResponse myResponse = someDAO.calldatabase("userRequest) ");
return myResponse;
}
However, now my consumers don't want all the fields in response , as we have around 150 fields and they need 2 or 3 at a time. They will send the list of fields in request and I will need to same those fields only.
So now sometimes my output should be :-
{
"field1": "someValue",
"field2": "someOtherValue"
}
Other time it will be :-
{
"field1": "someValue",
"field2": "someOtherValue",
"field3": "someOtherValue"
}
Using some static annotation like #JSONIgnore or #JsonIgnoreProperties(ignoreUnknown = true, value = {"field1"}) is not option as it will hardcode for everytime.
I can try overriding method of class ObjectMapper from Jackson by extending , but not sure how to tell my class to Spring MVC during Serialization??
Easiest workaround is i can use annotation #JsonInclude(Include.NON_NULL) but then I will not able to send null in response ?
Any thoughts or way to achieve return dynamic number of fields from my Spring MVC restful webservice on runtime ??

Spring boot REST application

I am trying to make a RESTful application in Java using Spring boot by following the tutorial here. I want to modify it so that I can extract an identifier from the URL and use it to serve requests.
So http://localhost:8080/members/<memberId> should serve me a JSON object with information about the member whose ID is <memberId>. I don't know how to
Map all http://localhost:8080/members/* to a single controller.
Extract the from the URL.
Should the logic of extracting the memberId and using it be part of the controller or a separate class, as per the MVC architecture?
I am new to Spring/Spring-boot/MVC. It is quite confusing to get started with. So please bear with my newbie questions.
Map all http://localhost:8080/members/* to a single controller.
You can use a placeholder in a request mapping to so it'll handle multiple URLs. For example:
#RequestMapping("/members/{id}")
Extract the id from the URL
You can have the value of a placeholder injected into your controller method using the #PathVariable annotation with a value that matches the name of the placeholder, "id" in this case:
#RequestMapping("/members/{id}")
public Member getMember(#PathVariable("id") long id) {
// Look up and return the member with the matching id
}
Should the logic of extracting the memberId and using it be part of the controller or a separate class, as per the MVC architecture?
You should let Spring MVC extract the member id from the URL as shown above. As for using it, you'll probably pass the URL to some sort of repository or service class that offers a findById method.
As you can see in the code below, service for customer are in one controller to get one and to add new customer.
So, you will have 2 services:
http://localhost:8080/customer/
http://localhost:8080/customer/{id}
#RestController("customer")
public class SampleController {
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Customer greetings(#PathVariable("id") Long id) {
Customer customer = new Customer();
customer.setName("Eddu");
customer.setLastname("Melendez");
return customer;
}
#RequestMapping(value = "/{id}", method = RequestMethod.POST)
public void add(#RequestBody Customer customer) {
}
class Customer implements Serializable {
private String name;
private String lastname;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getLastname() {
return lastname;
}
}
}