Building a Quick and Dirty Url Shortener

Posted on by 0 comment

At work last week we were discussing the security implications of url shortening services, such as tinyURL, biy.ly and goo.gl not only the fact that they can be used to hide malicious URLs for use in phishing attacks but the problem’s we’re having are:

  • Users in more restrictive access groups not being able to click links from these services
  • But worse, some users are using this service to shorten intranet links

Now that second point is an issue for me; if a shortening service were hacked our server names could be leaked to the world.

The two obvious solutions were ban all users from using such services or run our own internal service

My instinct told me that one shouldn’t be to hard to build.

So Here it is in less than 50 lines


from SimpleHTTPServer import SimpleHTTPRequestHandler
import StringIO,os,BaseHTTPServer,sqlite3
if "urls.db" in os.listdir("."):
    con = sqlite3.connect("urls.db")
    c=con.cursor()
else:
    con = sqlite3.connect("urls.db")
    c=con.cursor()
    c.execute("create table shorts (id integer primary key, url varchar unique)")
server = BaseHTTPServer.HTTPServer
server_address = ("", 8000)
class MyHandler(SimpleHTTPRequestHandler):
    def send_head(self):
        body,response = " ",200
        if self.path=="""/""":pass
        elif self.path.endswith("+"):
            c.execute('SELECT url FROM shorts WHERE id=(?)', (self.path[1:-1].decode("base64"),))
            s=c.fetchone()
            boady = s[0]        
        elif r"/add?" not in self.path:
                    response=301
            c.execute('SELECT url FROM shorts WHERE id=?', (self.path[1:].decode("base64"),))
            s=c.fetchone()    
            else:
                    x=self.path.split("?",1)[-1].replace(r"http://","")
            try:
                c.execute("insert into shorts(url) values (?)", (x,))
                con.commit()
            except sqlite3.IntegrityError:pass
            c.execute('SELECT id FROM shorts WHERE url=(?)', (x,))
            s=c.fetchone()
            body = "ok. " + str(s[0]).encode("base64")
        self.send_response(response)  
        self.send_header("Content-type", "text/html; charset=utf-8")  
        self.send_header("Content-Length", str(len(body)))  
        if response==301:
            self.send_header("Location","http://"+s[0])          
        self.end_headers()
                return StringIO.StringIO(body)
httpd = server(server_address, MyHandler)
print "Starting server..."
try:
    httpd.serve_forever()
except KeyboardInterrupt:
    httpd.socket.close()
Category: Python, Software | Tags: , ,

Leave a Reply

Your email address will not be published. Required fields are marked *