I have been collecting data and building databases for a while. As I do so, I have come across a wide variety of mistakes in thought and code varying from the notion that a captcha works to a failure to adequately protect from SQL injection. Therefore, I am going to publish fixes to what I find here with examples utilizing Groovy or Spring and Java.
First up, the SQL injection attack. Attempts to stop these attacks range from using JavaScript to setting variables. I recently came across a site that made an attempt to stop these attacks by limiting wildcards and querying with a variable. However, changing the header by resetting the variable actually gave me access to everything on the site in one fell swoop.
Suggestions
A few suggestions follow:
- Do not check anything with JavaScript, this is too easy to get around by simply rewriting the page.
- Write rules in the back end to protect from unauthorized access using SQL. Check variable combinations.
- Eliminate any suspicious non-allowable wildcards and look for key terms like LIKE, ILIKE,%, and = that are common for WHERE clauses. Select statements in SQL/POSTGRESQL follow a form similar to SELECT –data list– FROM –table– WHERE –variable— ILIKE ‘%answer%’
- Track IP Addresses and web pages using a symbol table (HashMap and the like) to eradicate any attempts to plainly just post to a server when it is not an API. This should be done in addition to any viewstate tracking and I strongly encourage the use of event validation.
- Use event validation if available or come up with your own.
Implementation
Most requests occur through a POST request and most of the requests are handled in Java using spring or a format such as aspx with Groovy Grails starting to become popular.
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/path") public class PostController{ //RequestMethod.GET also exists @RequestMapping(value="/path",method=RequestMethod.POST) public ResponseEntity newAnswer(@RequestParam(value="stringq", required=true) String stringq,@RequestParam(value="",required=true) boolean wildcard){ //prep response HttPHeaders headers=new HttpHeaders(); headers.set("Content-Type","text/html; charset=utf-8"); //get IP String ip=requestAttributes.getRequest().getRemoteAddr(); String data=null; //check for appropriate response page, assumes post-like nature with single url //makes a call to a HashMap entity setup at the beginning of the program // and accessible throughout the servers existance if(IPmap.get(ip).compareTo('appropriatePageURL')==0){ //create variable data here with response JSON or string }else{ //create innappropriate use message } return new ResponseEntity(data, headers, HttpStatus.CREATED); } }
The hashmap in this case is a static hash map. However, for security (even if using package level access modifiers) a file may be the solution. This will add time to the response though.