<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Recent Articles</title>
  <id>https://www.sultanik.com/recent.atom</id>
  <updated>2025-12-19T07:00:00Z</updated>
  <link href="https://www.sultanik.com/" />
  <link href="https://www.sultanik.com/recent.atom" rel="self" />
  <generator>Werkzeug</generator>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Can chatbots craft correct code?</title>
    <id>https://www.sultanik.com/blog/chatbots</id>
    <updated>2025-12-19T07:00:00Z</updated>
    <published>2025-12-19T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/chatbots" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>I recently attended the <a href="https://www.ai.engineer/code">AI Engineer Code Summit</a> in New York, an invite-only gathering of AI leaders and engineers. One theme emerged repeatedly in conversations with attendees building with AI: the belief that we’re approaching a future where developers will <em>never</em> need to look at code again. When I pressed these proponents, several made a similar argument:</p>
<blockquote><p>Forty years ago, when high-level programming languages like C became increasingly popular, some of the old guard resisted because C gave you less control than assembly. The same thing is happening now with LLMs.</p></blockquote>
<p>On its face, this analogy seems reasonable. Both represent increasing abstraction. Both initially met resistance. Both eventually transformed how we write software. But this analogy really thrashes my cache because it misses a fundamental distinction that matters more than abstraction level: <em><strong>determinism</strong></em>.</p>
<p>The difference between compilers and LLMs isn’t just about control or abstraction. It’s about semantic guarantees. And as I’ll argue, that difference has profound implications for the security and correctness of software.</p>
<p>As I wrote back in 2017 in “<a href="/blog/AutomationOfAutomation">Automation of Automation</a>,” there are fundamental limits on what we can automate. But those limits don’t eliminate determinism in the tools we’ve built; they simply mean we can’t automatically prove every program correct. Compilers don’t try to prove your program correct; they just faithfully translate it.</p><div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2025/12/19/can-chatbots-craft-correct-code/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Speedrunning the New York Subway</title>
    <id>https://www.sultanik.com/blog/subwayspeedrun</id>
    <updated>2025-08-25T07:00:00Z</updated>
    <published>2025-08-25T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/subwayspeedrun" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>It all began, as many great adventures do, at <a href="https://www.empirehacking.nyc/">Empire Hacking</a>. There, I encountered the inimitable <a href="https://www.youtube.com/@immigrantjackson">@ImmigrantJackson</a>, a YouTuber with a penchant for public transit and a dream: to break the world record for visiting every subway stop in New York City in the least time possible. (And, of course, to film the journey, what for those delicious likes, comments, and subscriptions.)</p><p>The only problem was: Immigrant Jackson didn’t know the fastest route. Surrounded by a room full of Trail of Bits computer scientists, he figured he’d ask our advice. The rules were simple. He didn’t need to exit the subway car; simply passing through a stop, even on an express train, counted as a “visit.” Stops could be visited multiple times, although this would of course be suboptimal. And there was no need to visit Staten Island … because we’re civilized. We live in a society. So, where should he start, and what would be the best route?</p><p>The coterie of curious computer coders coalescing around the inquisitor quickly classified this question as a case of the Traveling Salesman Problem (TSP). TSP is a classical problem in computer science in which one must find the shortest route for a traveling salesman to visit each city on a map. TSP is known to be computationally intractable to solve optimally for networks even as small as the New York subway system. Therefore, everyone dismissed the problem as “impossible.”</p><p>Except for me.</p><p>You see, <a href="https://youtu.be/Q3NnEuCLADE">my now-ancient PhD dissertation</a> was on <em>combinatorial optimization</em> and <em>approximation algorithms</em>: tools for solving problems like TSP efficiently with a result that is not necessarily optimal, but at least close to optimal. I knew that there were algorithms capable of solving TSP very quickly, producing a route guaranteed to be at most 50% longer than the optimal solution. In fact, <a href="https://arxiv.org/abs/1402.0423">one of the results of my dissertation</a> was the surprising revelation that even if you choose a feasible route at random, it will, on average, be only thrice the length of the optimal solution.</p><p>This, dear reader, was how I was <a href="https://xkcd.com/356/">nerd-sniped</a> into optimizing (speedrunning?) the NYC subway.</p><p>The first challenge was that, even when you discard Staten Italy, the subway system still has <em>a lot</em> of stations. There are close to 500. This exercise was fun and all, but I wasn’t about to spend hours encoding hundreds of stations, lines, transfer points, headways, and average trip times into a program.</p><p>There is an open standard for specifying public transit data: the <a href="https://gtfs.org/">General Transit Feed Specification (GTFS)</a>. Fortunately, the <a href="https://www.mta.info/developers">MTA has a public API implementing GTFS</a>. It’s just a collection of CSV files that are quite straightforward to parse. The dataset is sufficient to construct a graph with a node for each subway station and an edge if there is a subway line that connects the two stations. Actually, the data represents subway <em>platforms</em> rather than stations, which is necessary to calculate things like transfer times between train lines.</p><p>The New York Subway network is a <em>directed</em> graph: some neighboring stations are accessible to each other only in one direction. For example, the <a href="https://en.wikipedia.org/wiki/Aqueduct_Racetrack_station">Aqueduct Racetrack station</a> only has a platform for northbound trains, not southbound trains. <a href="https://www.cs.cmu.edu/~odonnell/hits09/asadpour-goemans-madry-oveis-gharan-saberi-ATSP.pdf">The best algorithms for approximating a solution to TSP on directed graphs</a> are not great, only guaranteeing a solution of three or four times the length of the optimal solution. Therefore, I decided to relax the problem to an undirected graph (i.e., I assume that every station has trains to its neighbors bidirectionally). This turned out not to be an issue and permitted the use of the <a href="https://en.wikipedia.org/wiki/Christofides_algorithm">Christofides algorithm</a>, which guarantees a solution at most 50% longer than optimal.</p><p>The next and final relaxation is to partially ignore actual timetables and headways. When a transfer between lines is necessary, I assume that the transfer will require the “minimum transfer time” reported by GTFS (i.e.<em>,</em> the amount of time required to walk from one platform to another) plus one-half the average headway for that line throughout the day. Therefore, the resulting route has the potential to strand the poor YouTuber on the last train at the end of a line. Validating the resulting route’s real-world feasibility is left as an exercise to the reader.</p><p>The Christofides algorithm was able to approximate a solution to the TSP for my relaxed subway network graph in a matter of milliseconds. This is compared to the unfathomable amount of computation required to brute-force calculate the optimal solution, an amount so large that it afforded me the horrifying opportunity to learn that <a href="https://googology.fandom.com/wiki/Googolchime">there is a whole community of “googologists” who compete with each other to name large numbers</a>. We’re talking <em>googolchime</em> levels of computation. <em>Guppybell</em> levels, even!</p><p>The resulting tour visits all 474 stations, 155 of which are visited more than once. The tour requires 34 transfers. The expected time for completing this tour is 20 hours, 42 minutes. That’s about <a href="https://www.youtube.com/watch?v=6xoWvBAUVIg">45 minutes faster than the record</a>, which was about 21 and a half hours.</p><video autoplay="" loop="" muted="" playsinline="" preload="metadata">
<source src="/images/speedrunning-ny-subway.mp4" type="video/mp4" /></video><p>This is neat and all, but we spent an unnecessary amount of energy encoding the New York subway system as a graph. What else might we do with it? One straightforward computation is to calculate each station’s <a href="https://en.wikipedia.org/wiki/Eigenvector_centrality"><em>eigenvector centrality</em></a>. Imagine you’re given the Sisyphean task of riding the subway for all eternity. Every time you arrive at a station, you flip a coin. If it’s heads, you stay on the current train. If it’s tails, you get off and transfer to another line or direction. If you were to pause your infinite tour at any arbitrary point in time, what’s the probability that you are at a particular station? The higher the probability, the more “centrally connected” the station. That’s exactly what eigenvector centrality calculates.</p><p>Eigenvector centrality is actually what Google originally used in its <a href="https://en.wikipedia.org/wiki/PageRank">PageRank algorithm</a> to rank the relative importance (centrality) of web pages. Each page is like a subway station, and hyperlinks on the page are like the subway lines connecting them. Eigenvector centrality is relatively easy to calculate, either directly (it’s related to the eigenspectrum of the graph’s adjacency matrix, thanks to spooky <a href="https://en.wikipedia.org/wiki/Spectral_graph_theory">spectral graph theory</a> magic) or using a technique called <a href="https://en.wikipedia.org/wiki/Power_iteration"><em>power iteration</em></a> (which relies on a convergence that happens when you multiply the adjacency matrix by a vector a bunch of times). Either way, you can calculate it with a single function call in <a href="https://networkx.org/">NetworkX</a>.</p><p>What do you think will be the most probable stop on your infinite subway tour? Or, another way to ask the same question: Which stop will you visit most often on your tour? Unsurprisingly, it will be Times Square, with a probability of a little over 30%. The next most probable station is 42nd St. Port Authority Bus Terminal, coming in at about 8%. Then 50th St., 59th St. Columbus Circle, Grand Central 42nd St., and 34th St. Penn Station are all between 4% and 5%.</p><p>So, what have we learned? First of all, don’t attend Empire Hacking without the expectation of being intellectually stimulated. Secondly, don’t immediately discount a problem just because it is NP-hard or computationally intractable to solve; you might be able to approximate a solution of sufficient optimality. Thirdly, <a href="https://www.latimes.com/archives/la-xpm-1991-12-08-bk-306-story.html">Times Square may not be the “center of the universe,”</a> but it is <em>definitely</em> the center of the New York subway system. Finally, remember to like, comment, and subscribe!</p><details><summary>Click to see the complete tour route!</summary>1 (0.0hrs): Far Rockaway-Mott Av<br />2 (0.0hrs): Beach 25 St<br />3 (0.1hrs): Beach 36 St<br />4 (0.1hrs): Beach 44 St<br />5 (0.1hrs): Beach 60 St<br />6 (0.1hrs): Beach 67 St<br />7 (0.2hrs): Broad Channel<br />8 (0.3hrs): Beach 90 St<br />9 (0.3hrs): Beach 98 St<br />10 (0.3hrs): Beach 105 St<br />11 (0.4hrs): Rockaway Park-Beach 116 St<br />12 (0.4hrs): Beach 105 St (visit 2)<br />13 (0.4hrs): Beach 98 St (visit 2)<br />14 (0.4hrs): Beach 90 St (visit 2)<br />15 (0.5hrs): Broad Channel (visit 2)<br />16 (0.6hrs): Howard Beach-JFK Airport<br />17 (0.7hrs): Aqueduct-N Conduit Av<br />18 (0.7hrs): Aqueduct Racetrack<br />19 (0.7hrs): Rockaway Blvd<br />20 (0.8hrs): 104 St<br />21 (0.8hrs): 111 St<br />22 (0.9hrs): Ozone Park-Lefferts Blvd<br />23 (0.9hrs): 111 St (visit 2)<br />24 (0.9hrs): 104 St (visit 2)<br />25 (0.9hrs): Rockaway Blvd (visit 2)<br />26 (0.9hrs): 88 St<br />27 (1.0hrs): 80 St<br />28 (1.0hrs): Grant Av<br />29 (1.0hrs): Euclid Av<br />30 (1.0hrs): Shepherd Av<br />31 (1.1hrs): Van Siclen Av<br />32 (1.1hrs): Liberty Av<br />33 (1.1hrs): Broadway Junction<br />transfer lines<br />34 (1.2hrs): Broadway Junction<br />35 (1.2hrs): Alabama Av<br />36 (1.3hrs): Van Siclen Av<br />37 (1.3hrs): Cleveland St<br />38 (1.3hrs): Norwood Av<br />39 (1.3hrs): Crescent St<br />40 (1.4hrs): Cypress Hills<br />41 (1.4hrs): 75 St-Elderts Ln<br />42 (1.4hrs): 85 St-Forest Pkwy<br />43 (1.4hrs): Woodhaven Blvd<br />44 (1.5hrs): 104 St<br />45 (1.5hrs): 111 St<br />46 (1.5hrs): 121 St<br />47 (1.6hrs): Sutphin Blvd-Archer Av-JFK Airport<br />48 (1.7hrs): Jamaica Center-Parsons/Archer<br />49 (1.7hrs): Sutphin Blvd-Archer Av-JFK Airport (visit 2)<br />50 (1.7hrs): Jamaica-Van Wyck<br />51 (1.7hrs): Briarwood<br />52 (1.8hrs): Sutphin Blvd<br />53 (1.8hrs): Parsons Blvd<br />54 (1.9hrs): 169 St<br />55 (2.0hrs): Jamaica-179 St<br />56 (2.0hrs): 169 St (visit 2)<br />57 (2.0hrs): Parsons Blvd (visit 2)<br />58 (2.1hrs): Sutphin Blvd (visit 2)<br />59 (2.1hrs): Briarwood (visit 2)<br />60 (2.1hrs): Kew Gardens-Union Tpke<br />61 (2.2hrs): 75 Av<br />62 (2.2hrs): Forest Hills-71 Av<br />63 (2.2hrs): 67 Av<br />64 (2.2hrs): 63 Dr-Rego Park<br />65 (2.3hrs): Woodhaven Blvd<br />66 (2.3hrs): Grand Av-Newtown<br />67 (2.3hrs): Elmhurst Av<br />68 (2.4hrs): Jackson Hts-Roosevelt Av<br />69 (2.4hrs): 65 St<br />70 (2.4hrs): Northern Blvd<br />71 (2.4hrs): 46 St<br />72 (2.5hrs): Steinway St<br />73 (2.5hrs): 36 St<br />74 (2.5hrs): Queens Plaza<br />75 (2.6hrs): Court Sq-23 St<br />76 (2.6hrs): Lexington Av/53 St<br />77 (2.6hrs): 5 Av/53 St<br />78 (2.7hrs): 7 Av<br />79 (2.7hrs): 50 St<br />80 (2.7hrs): 42 St-Port Authority Bus Terminal<br />81 (2.8hrs): 34 St-Penn Station<br />82 (2.8hrs): 23 St<br />83 (2.8hrs): 14 St<br />84 (2.9hrs): W 4 St-Wash Sq<br />85 (2.9hrs): Spring St<br />86 (2.9hrs): Canal St<br />87 (2.9hrs): World Trade Center<br />88 (3.0hrs): Canal St (visit 2)<br />89 (3.0hrs): Chambers St<br />90 (3.0hrs): Fulton St<br />transfer lines<br />91 (3.1hrs): Fulton St<br />92 (3.1hrs): Wall St<br />93 (3.1hrs): Bowling Green<br />94 (3.2hrs): Wall St (visit 2)<br />95 (3.2hrs): Fulton St (visit 2)<br />96 (3.2hrs): Brooklyn Bridge-City Hall<br />97 (3.2hrs): Canal St<br />98 (3.3hrs): Brooklyn Bridge-City Hall (visit 2)<br />transfer lines<br />99 (3.3hrs): Chambers St<br />100 (3.4hrs): Fulton St<br />101 (3.4hrs): Broad St<br />102 (3.4hrs): Fulton St (visit 2)<br />103 (3.4hrs): Chambers St (visit 2)<br />104 (3.5hrs): Canal St<br />105 (3.5hrs): Bowery<br />106 (3.5hrs): Delancey St-Essex St<br />107 (3.6hrs): Bowery (visit 2)<br />108 (3.6hrs): Canal St (visit 2)<br />transfer lines<br />109 (3.6hrs): Canal St (visit 2)<br />110 (3.7hrs): Spring St<br />111 (3.7hrs): Bleecker St<br />112 (3.7hrs): Astor Pl<br />113 (3.7hrs): 14 St-Union Sq<br />114 (3.8hrs): 23 St<br />115 (3.8hrs): 28 St<br />116 (3.8hrs): 33 St<br />117 (3.8hrs): Grand Central-42 St<br />118 (3.9hrs): 51 St<br />119 (3.9hrs): 59 St<br />120 (3.9hrs): 68 St-Hunter College<br />121 (3.9hrs): 77 St<br />122 (4.0hrs): 86 St<br />123 (4.0hrs): 96 St<br />124 (4.0hrs): 103 St<br />125 (4.0hrs): 110 St<br />126 (4.1hrs): 116 St<br />127 (4.1hrs): 125 St<br />128 (4.1hrs): 3 Av-138 St<br />129 (4.3hrs): Hunts Point Av<br />130 (4.4hrs): Parkchester<br />131 (4.4hrs): Castle Hill Av<br />132 (4.4hrs): Zerega Av<br />133 (4.4hrs): Westchester Sq-E Tremont Av<br />134 (4.5hrs): Middletown Rd<br />135 (4.5hrs): Buhre Av<br />136 (4.5hrs): Pelham Bay Park<br />137 (4.6hrs): Buhre Av (visit 2)<br />138 (4.6hrs): Middletown Rd (visit 2)<br />139 (4.6hrs): Westchester Sq-E Tremont Av (visit 2)<br />140 (4.6hrs): Zerega Av (visit 2)<br />141 (4.7hrs): Castle Hill Av (visit 2)<br />142 (4.7hrs): Parkchester (visit 2)<br />143 (4.7hrs): St Lawrence Av<br />144 (4.7hrs): Morrison Av-Soundview<br />145 (4.8hrs): Elder Av<br />146 (4.8hrs): Whitlock Av<br />147 (4.8hrs): Hunts Point Av (visit 2)<br />148 (4.8hrs): Longwood Av<br />149 (4.9hrs): E 149 St<br />150 (4.9hrs): E 143 St-St Mary’s St<br />151 (4.9hrs): Cypress Av<br />152 (4.9hrs): Brook Av<br />153 (5.0hrs): 3 Av-138 St (visit 2)<br />154 (5.0hrs): 125 St (visit 2)<br />155 (5.1hrs): 138 St-Grand Concourse<br />156 (5.1hrs): 149 St-Grand Concourse<br />transfer lines<br />157 (5.2hrs): 149 St-Grand Concourse<br />158 (5.2hrs): 3 Av-149 St<br />159 (5.4hrs): E 180 St<br />160 (5.4hrs): Morris Park<br />161 (5.5hrs): Pelham Pkwy<br />162 (5.5hrs): Gun Hill Rd<br />163 (5.5hrs): Baychester Av<br />164 (5.6hrs): Eastchester-Dyre Av<br />165 (5.6hrs): Baychester Av (visit 2)<br />166 (5.7hrs): Gun Hill Rd (visit 2)<br />167 (5.7hrs): Pelham Pkwy (visit 2)<br />168 (5.7hrs): Morris Park (visit 2)<br />169 (5.8hrs): E 180 St (visit 2)<br />170 (5.8hrs): Bronx Park East<br />171 (5.9hrs): Pelham Pkwy<br />172 (5.9hrs): Allerton Av<br />173 (5.9hrs): Burke Av<br />174 (5.9hrs): Gun Hill Rd<br />175 (6.0hrs): 219 St<br />176 (6.0hrs): 225 St<br />177 (6.0hrs): 233 St<br />178 (6.0hrs): Nereid Av<br />179 (6.1hrs): Wakefield-241 St<br />180 (6.1hrs): Nereid Av (visit 2)<br />181 (6.2hrs): 233 St (visit 2)<br />182 (6.2hrs): 225 St (visit 2)<br />183 (6.2hrs): 219 St (visit 2)<br />184 (6.2hrs): Gun Hill Rd (visit 2)<br />185 (6.4hrs): E 180 St (visit 3)<br />186 (6.4hrs): West Farms Sq-E Tremont Av<br />187 (6.4hrs): 174 St<br />188 (6.5hrs): Freeman St<br />189 (6.5hrs): Simpson St<br />190 (6.5hrs): Intervale Av<br />191 (6.5hrs): Prospect Av<br />192 (6.6hrs): Jackson Av<br />193 (6.6hrs): 3 Av-149 St (visit 2)<br />194 (6.6hrs): 149 St-Grand Concourse (visit 2)<br />195 (6.7hrs): 135 St<br />196 (6.7hrs): 145 St<br />197 (6.8hrs): Harlem-148 St<br />198 (6.8hrs): 145 St (visit 2)<br />199 (6.8hrs): 135 St (visit 2)<br />200 (6.9hrs): 125 St<br />201 (6.9hrs): 116 St<br />202 (6.9hrs): Central Park North (110 St)<br />203 (7.0hrs): 96 St<br />204 (7.0hrs): 72 St<br />205 (7.1hrs): 66 St-Lincoln Center<br />206 (7.1hrs): 59 St-Columbus Circle<br />transfer lines<br />207 (7.1hrs): 59 St-Columbus Circle<br />208 (7.2hrs): 7 Av (visit 2)<br />209 (7.2hrs): 47-50 Sts-Rockefeller Ctr<br />210 (7.2hrs): 57 St<br />211 (7.2hrs): 47-50 Sts-Rockefeller Ctr (visit 2)<br />212 (7.3hrs): 42 St-Bryant Pk<br />213 (7.3hrs): 34 St-Herald Sq<br />214 (7.3hrs): 23 St<br />215 (7.3hrs): 14 St<br />216 (7.4hrs): W 4 St-Wash Sq<br />217 (7.4hrs): Broadway-Lafayette St<br />218 (7.4hrs): Grand St<br />219 (7.5hrs): Broadway-Lafayette St (visit 2)<br />220 (7.5hrs): 2 Av<br />221 (7.5hrs): Delancey St-Essex St<br />222 (7.6hrs): East Broadway<br />223 (7.6hrs): York St<br />224 (7.6hrs): Jay St-MetroTech<br />transfer lines<br />225 (7.7hrs): Jay St-MetroTech<br />226 (7.7hrs): DeKalb Av<br />227 (7.7hrs): Atlantic Av-Barclays Ctr<br />228 (7.8hrs): 7 Av<br />229 (7.8hrs): Prospect Park<br />230 (7.9hrs): Parkside Av<br />231 (7.9hrs): Church Av<br />232 (7.9hrs): Beverley Rd<br />233 (7.9hrs): Cortelyou Rd<br />234 (8.0hrs): Newkirk Plaza<br />235 (8.0hrs): Avenue H<br />236 (8.0hrs): Avenue J<br />237 (8.0hrs): Avenue M<br />238 (8.1hrs): Kings Hwy<br />239 (8.1hrs): Avenue U<br />240 (8.1hrs): Neck Rd<br />241 (8.2hrs): Sheepshead Bay<br />242 (8.2hrs): Brighton Beach<br />243 (8.2hrs): Ocean Pkwy<br />244 (8.3hrs): W 8 St-NY Aquarium<br />245 (8.3hrs): Coney Island-Stillwell Av<br />246 (8.3hrs): W 8 St-NY Aquarium (visit 2)<br />247 (8.4hrs): Neptune Av<br />248 (8.4hrs): Avenue X<br />249 (8.4hrs): Avenue U<br />250 (8.4hrs): Kings Hwy<br />251 (8.5hrs): Avenue P<br />252 (8.5hrs): Avenue N<br />253 (8.5hrs): Bay Pkwy<br />254 (8.5hrs): Avenue I<br />255 (8.6hrs): 18 Av<br />256 (8.6hrs): Ditmas Av<br />257 (8.6hrs): Church Av<br />258 (8.6hrs): Fort Hamilton Pkwy<br />259 (8.7hrs): 15 St-Prospect Park<br />260 (8.7hrs): 7 Av<br />261 (8.7hrs): 4 Av-9 St<br />262 (8.8hrs): Smith-9 Sts<br />263 (8.8hrs): Carroll St<br />264 (8.8hrs): Bergen St<br />265 (8.9hrs): Hoyt-Schermerhorn Sts<br />266 (8.9hrs): Lafayette Av<br />267 (8.9hrs): Clinton-Washington Avs<br />268 (8.9hrs): Franklin Av<br />transfer lines<br />269 (9.0hrs): Franklin Av<br />transfer lines<br />270 (9.0hrs): Franklin Av (visit 2)<br />271 (9.1hrs): Nostrand Av<br />272 (9.1hrs): Kingston-Throop Avs<br />273 (9.1hrs): Utica Av<br />274 (9.2hrs): Ralph Av<br />275 (9.2hrs): Rockaway Av<br />276 (9.2hrs): Broadway Junction (visit 2)<br />transfer lines<br />277 (9.3hrs): Broadway Junction<br />278 (9.3hrs): Atlantic Av<br />279 (9.3hrs): Sutter Av<br />280 (9.3hrs): Livonia Av<br />281 (9.4hrs): New Lots Av<br />282 (9.4hrs): East 105 St<br />283 (9.4hrs): Canarsie-Rockaway Pkwy<br />284 (9.4hrs): East 105 St (visit 2)<br />285 (9.5hrs): New Lots Av (visit 2)<br />286 (9.5hrs): Livonia Av (visit 2)<br />transfer lines<br />287 (9.6hrs): Junius St<br />288 (9.6hrs): Pennsylvania Av<br />289 (9.6hrs): Van Siclen Av<br />290 (9.7hrs): New Lots Av<br />291 (9.7hrs): Van Siclen Av (visit 2)<br />292 (9.7hrs): Pennsylvania Av (visit 2)<br />293 (9.7hrs): Junius St (visit 2)<br />294 (9.7hrs): Rockaway Av<br />295 (9.8hrs): Saratoga Av<br />296 (9.8hrs): Sutter Av-Rutland Rd<br />297 (9.8hrs): Crown Hts-Utica Av<br />298 (9.9hrs): Kingston Av<br />299 (9.9hrs): Nostrand Av<br />300 (9.9hrs): Franklin Av-Medgar Evers College<br />301 (10.0hrs): President St-Medgar Evers College<br />302 (10.0hrs): Sterling St<br />303 (10.0hrs): Winthrop St<br />304 (10.1hrs): Church Av<br />305 (10.1hrs): Beverly Rd<br />306 (10.2hrs): Newkirk Av-Little Haiti<br />307 (10.2hrs): Flatbush Av-Brooklyn College<br />308 (10.2hrs): Newkirk Av-Little Haiti (visit 2)<br />309 (10.2hrs): Beverly Rd (visit 2)<br />310 (10.3hrs): Church Av (visit 2)<br />311 (10.3hrs): Winthrop St (visit 2)<br />312 (10.3hrs): Sterling St (visit 2)<br />313 (10.3hrs): President St-Medgar Evers College (visit 2)<br />314 (10.4hrs): Franklin Av-Medgar Evers College (visit 2)<br />315 (10.4hrs): Eastern Pkwy-Brooklyn Museum<br />316 (10.5hrs): Grand Army Plaza<br />317 (10.5hrs): Bergen St<br />318 (10.5hrs): Atlantic Av-Barclays Ctr<br />transfer lines<br />319 (10.6hrs): Atlantic Av-Barclays Ctr<br />320 (10.7hrs): 36 St<br />321 (10.7hrs): 9 Av<br />322 (10.8hrs): Fort Hamilton Pkwy<br />323 (10.8hrs): 50 St<br />324 (10.8hrs): 55 St<br />325 (10.8hrs): 62 St<br />transfer lines<br />326 (10.9hrs): New Utrecht Av<br />327 (10.9hrs): 18 Av<br />328 (10.9hrs): 20 Av<br />329 (11.0hrs): Bay Pkwy<br />330 (11.0hrs): Kings Hwy<br />331 (11.0hrs): Avenue U<br />332 (11.0hrs): 86 St<br />333 (11.1hrs): Coney Island-Stillwell Av (visit 2)<br />334 (11.2hrs): Bay 50 St<br />335 (11.3hrs): 25 Av<br />336 (11.3hrs): Bay Pkwy<br />337 (11.3hrs): 20 Av<br />338 (11.3hrs): 18 Av<br />339 (11.3hrs): 79 St<br />340 (11.4hrs): 71 St<br />341 (11.4hrs): 62 St (visit 2)<br />transfer lines<br />342 (11.5hrs): New Utrecht Av (visit 2)<br />343 (11.5hrs): Fort Hamilton Pkwy<br />344 (11.5hrs): 8 Av<br />345 (11.6hrs): 59 St<br />346 (11.6hrs): Bay Ridge Av<br />347 (11.6hrs): 77 St<br />348 (11.7hrs): 86 St<br />349 (11.7hrs): Bay Ridge-95 St<br />350 (11.7hrs): 86 St (visit 2)<br />351 (11.8hrs): 77 St (visit 2)<br />352 (11.8hrs): Bay Ridge Av (visit 2)<br />353 (11.8hrs): 59 St (visit 2)<br />354 (11.9hrs): 53 St<br />355 (11.9hrs): 45 St<br />356 (11.9hrs): 36 St (visit 2)<br />357 (12.0hrs): 25 St<br />358 (12.0hrs): Prospect Av<br />359 (12.0hrs): 4 Av-9 St<br />360 (12.0hrs): Union St<br />361 (12.1hrs): Atlantic Av-Barclays Ctr (visit 2)<br />transfer lines<br />362 (12.1hrs): Atlantic Av-Barclays Ctr (visit 2)<br />363 (12.2hrs): Nevins St<br />364 (12.2hrs): Borough Hall<br />365 (12.2hrs): Nevins St (visit 2)<br />366 (12.2hrs): Hoyt St<br />367 (12.3hrs): Borough Hall<br />transfer lines<br />368 (12.3hrs): Court St<br />369 (12.4hrs): Jay St-MetroTech (visit 2)<br />transfer lines<br />370 (12.4hrs): Jay St-MetroTech (visit 2)<br />371 (12.4hrs): High St<br />372 (12.4hrs): Jay St-MetroTech (visit 3)<br />373 (12.5hrs): Hoyt-Schermerhorn Sts (visit 2)<br />374 (12.5hrs): Fulton St<br />375 (12.5hrs): Clinton-Washington Avs<br />376 (12.6hrs): Classon Av<br />377 (12.6hrs): Bedford-Nostrand Avs<br />378 (12.6hrs): Myrtle-Willoughby Avs<br />379 (12.6hrs): Flushing Av<br />380 (12.7hrs): Broadway<br />381 (12.7hrs): Metropolitan Av<br />382 (12.7hrs): Nassau Av<br />383 (12.8hrs): Greenpoint Av<br />384 (12.8hrs): 21 St<br />385 (12.8hrs): Court Sq<br />transfer lines<br />386 (12.9hrs): Court Sq<br />387 (12.9hrs): Hunters Point Av<br />388 (12.9hrs): Vernon Blvd-Jackson Av<br />389 (12.9hrs): Hunters Point Av (visit 2)<br />390 (13.0hrs): Court Sq (visit 2)<br />391 (13.0hrs): Queensboro Plaza<br />transfer lines<br />392 (13.0hrs): Queensboro Plaza<br />393 (13.0hrs): 39 Av-Dutch Kills<br />394 (13.1hrs): 36 Av<br />395 (13.1hrs): Broadway<br />396 (13.1hrs): 30 Av<br />397 (13.1hrs): Astoria Blvd<br />398 (13.2hrs): Astoria-Ditmars Blvd<br />399 (13.2hrs): Astoria Blvd (visit 2)<br />400 (13.2hrs): 30 Av (visit 2)<br />401 (13.2hrs): Broadway (visit 2)<br />402 (13.3hrs): 36 Av (visit 2)<br />403 (13.3hrs): 39 Av-Dutch Kills (visit 2)<br />404 (13.3hrs): Queensboro Plaza (visit 2)<br />transfer lines<br />405 (13.3hrs): Queensboro Plaza (visit 2)<br />406 (13.4hrs): 33 St-Rawson St<br />407 (13.4hrs): 40 St-Lowery St<br />408 (13.4hrs): 46 St-Bliss St<br />409 (13.4hrs): 52 St<br />410 (13.5hrs): 61 St-Woodside<br />411 (13.5hrs): 69 St<br />412 (13.5hrs): 74 St-Broadway<br />413 (13.5hrs): 82 St-Jackson Hts<br />414 (13.5hrs): 90 St-Elmhurst Av<br />415 (13.6hrs): Junction Blvd<br />416 (13.6hrs): 103 St-Corona Plaza<br />417 (13.6hrs): 111 St<br />418 (13.6hrs): Mets-Willets Point<br />419 (13.7hrs): Flushing-Main St<br />420 (13.8hrs): Mets-Willets Point (visit 2)<br />421 (13.8hrs): Junction Blvd (visit 2)<br />422 (13.9hrs): 74 St-Broadway (visit 2)<br />transfer lines<br />423 (13.9hrs): Jackson Hts-Roosevelt Av (visit 2)<br />424 (14.0hrs): Queens Plaza (visit 2)<br />425 (14.1hrs): Lexington Av/59 St<br />426 (14.2hrs): 5 Av/59 St<br />427 (14.2hrs): 57 St-7 Av<br />428 (14.3hrs): Lexington Av/63 St<br />429 (14.3hrs): 72 St<br />430 (14.3hrs): 86 St<br />431 (14.4hrs): 96 St<br />432 (14.4hrs): 86 St (visit 2)<br />433 (14.4hrs): 72 St (visit 2)<br />434 (14.5hrs): Lexington Av/63 St (visit 2)<br />435 (14.5hrs): Roosevelt Island<br />436 (14.6hrs): 21 St-Queensbridge<br />437 (14.6hrs): Roosevelt Island (visit 2)<br />438 (14.6hrs): Lexington Av/63 St (visit 3)<br />439 (14.7hrs): 57 St-7 Av (visit 2)<br />440 (14.7hrs): 49 St<br />441 (14.8hrs): Times Sq-42 St<br />transfer lines<br />442 (14.8hrs): Times Sq-42 St<br />transfer lines<br />443 (14.9hrs): Times Sq-42 St<br />444 (14.9hrs): Grand Central-42 St<br />transfer lines<br />445 (15.0hrs): Grand Central-42 St<br />446 (15.0hrs): 5 Av<br />447 (15.0hrs): Times Sq-42 St<br />448 (15.1hrs): 34 St-Hudson Yards<br />449 (15.1hrs): Times Sq-42 St (visit 2)<br />transfer lines<br />450 (15.2hrs): Times Sq-42 St (visit 2)<br />451 (15.2hrs): 34 St-Herald Sq<br />452 (15.2hrs): 28 St<br />453 (15.2hrs): 23 St<br />454 (15.3hrs): 14 St-Union Sq<br />455 (15.3hrs): 8 St-NYU<br />456 (15.3hrs): Prince St<br />457 (15.4hrs): Canal St<br />transfer lines<br />458 (15.4hrs): Canal St<br />459 (15.4hrs): City Hall<br />460 (15.5hrs): Cortlandt St<br />461 (15.5hrs): Rector St<br />462 (15.5hrs): Whitehall St-South Ferry<br />transfer lines<br />463 (15.6hrs): South Ferry Loop<br />transfer lines<br />464 (15.6hrs): Whitehall St-South Ferry (visit 2)<br />465 (15.7hrs): Court St (visit 2)<br />transfer lines<br />466 (15.7hrs): Borough Hall (visit 2)<br />467 (15.7hrs): Clark St<br />468 (15.8hrs): Wall St<br />469 (15.8hrs): Fulton St<br />470 (15.9hrs): Park Place<br />471 (15.9hrs): Chambers St<br />472 (15.9hrs): WTC Cortlandt<br />473 (15.9hrs): Rector St<br />474 (16.0hrs): South Ferry<br />475 (16.0hrs): Rector St (visit 2)<br />476 (16.0hrs): WTC Cortlandt (visit 2)<br />477 (16.0hrs): Chambers St (visit 2)<br />478 (16.1hrs): Franklin St<br />479 (16.1hrs): Canal St<br />480 (16.1hrs): Houston St<br />481 (16.1hrs): Christopher St-Sheridan Sq<br />482 (16.2hrs): 14 St<br />483 (16.2hrs): 18 St<br />484 (16.2hrs): 23 St<br />485 (16.2hrs): 28 St<br />486 (16.2hrs): 34 St-Penn Station<br />487 (16.3hrs): Times Sq-42 St (visit 2)<br />488 (16.3hrs): 50 St<br />489 (16.3hrs): 59 St-Columbus Circle (visit 2)<br />490 (16.3hrs): 66 St-Lincoln Center (visit 2)<br />491 (16.4hrs): 72 St (visit 2)<br />492 (16.4hrs): 79 St<br />493 (16.4hrs): 86 St<br />494 (16.4hrs): 96 St (visit 2)<br />495 (16.5hrs): 103 St<br />496 (16.5hrs): Cathedral Pkwy (110 St)<br />497 (16.5hrs): 116 St-Columbia University<br />498 (16.5hrs): 125 St<br />499 (16.6hrs): 137 St-City College<br />500 (16.6hrs): 145 St<br />501 (16.6hrs): 157 St<br />502 (16.7hrs): 168 St-Washington Hts<br />503 (16.7hrs): 181 St<br />504 (16.7hrs): 191 St<br />505 (16.7hrs): Dyckman St<br />506 (16.8hrs): 207 St<br />507 (16.8hrs): 215 St<br />508 (16.8hrs): Marble Hill-225 St<br />509 (16.8hrs): 231 St<br />510 (16.9hrs): 238 St<br />511 (16.9hrs): Van Cortlandt Park-242 St<br />512 (16.9hrs): 238 St (visit 2)<br />513 (17.0hrs): 231 St (visit 2)<br />514 (17.0hrs): Marble Hill-225 St (visit 2)<br />515 (17.0hrs): 215 St (visit 2)<br />516 (17.0hrs): 207 St (visit 2)<br />517 (17.1hrs): Dyckman St (visit 2)<br />518 (17.1hrs): 191 St (visit 2)<br />519 (17.1hrs): 181 St (visit 2)<br />520 (17.1hrs): 168 St-Washington Hts (visit 2)<br />transfer lines<br />521 (17.2hrs): 168 St<br />522 (17.3hrs): 175 St<br />523 (17.3hrs): 181 St<br />524 (17.3hrs): 190 St<br />525 (17.4hrs): Dyckman St<br />526 (17.4hrs): Inwood-207 St<br />527 (17.5hrs): Dyckman St (visit 2)<br />528 (17.5hrs): 190 St (visit 2)<br />529 (17.5hrs): 181 St (visit 2)<br />530 (17.5hrs): 175 St (visit 2)<br />531 (17.6hrs): 168 St (visit 2)<br />532 (17.6hrs): 163 St-Amsterdam Av<br />533 (17.6hrs): 155 St<br />534 (17.6hrs): 145 St<br />535 (17.7hrs): 135 St<br />536 (17.7hrs): 145 St<br />537 (17.8hrs): Tremont Av<br />538 (17.9hrs): Fordham Rd<br />539 (17.9hrs): Kingsbridge Rd<br />540 (18.0hrs): Bedford Park Blvd<br />541 (18.0hrs): Norwood-205 St<br />542 (18.0hrs): Bedford Park Blvd (visit 2)<br />543 (18.1hrs): Kingsbridge Rd (visit 2)<br />544 (18.1hrs): Fordham Rd (visit 2)<br />545 (18.2hrs): 182-183 Sts<br />546 (18.2hrs): Tremont Av (visit 2)<br />547 (18.2hrs): 174-175 Sts<br />548 (18.2hrs): 170 St<br />549 (18.3hrs): 167 St<br />550 (18.3hrs): 161 St-Yankee Stadium<br />transfer lines<br />551 (18.4hrs): 161 St-Yankee Stadium<br />552 (18.4hrs): 167 St<br />553 (18.4hrs): 170 St<br />554 (18.4hrs): Mt Eden Av<br />555 (18.5hrs): 176 St<br />556 (18.5hrs): Burnside Av<br />557 (18.5hrs): 183 St<br />558 (18.5hrs): Fordham Rd<br />559 (18.6hrs): Kingsbridge Rd<br />560 (18.6hrs): Bedford Park Blvd-Lehman College<br />561 (18.6hrs): Mosholu Pkwy<br />562 (18.7hrs): Woodlawn<br />563 (18.7hrs): Mosholu Pkwy (visit 2)<br />564 (18.7hrs): Bedford Park Blvd-Lehman College (visit 2)<br />565 (18.8hrs): Kingsbridge Rd (visit 2)<br />566 (18.8hrs): Fordham Rd (visit 2)<br />567 (18.8hrs): 183 St (visit 2)<br />568 (18.8hrs): Burnside Av (visit 2)<br />569 (18.9hrs): 167 St (visit 2)<br />570 (19.0hrs): 161 St-Yankee Stadium (visit 2)<br />transfer lines<br />571 (19.0hrs): 161 St-Yankee Stadium (visit 2)<br />572 (19.0hrs): 155 St<br />573 (19.1hrs): 145 St (visit 2)<br />574 (19.1hrs): 125 St<br />575 (19.1hrs): 116 St<br />576 (19.2hrs): Cathedral Pkwy (110 St)<br />577 (19.2hrs): 103 St<br />578 (19.2hrs): 96 St<br />579 (19.2hrs): 86 St<br />580 (19.3hrs): 81 St-Museum of Natural History<br />581 (19.3hrs): 72 St<br />582 (19.3hrs): 59 St-Columbus Circle (visit 2)<br />583 (19.3hrs): 42 St-Port Authority Bus Terminal (visit 2)<br />584 (19.4hrs): 34 St-Penn Station (visit 2)<br />585 (19.4hrs): 14 St (visit 2)<br />transfer lines<br />586 (19.4hrs): 8 Av<br />587 (19.5hrs): 6 Av<br />588 (19.5hrs): 14 St-Union Sq<br />589 (19.5hrs): 3 Av<br />590 (19.5hrs): 1 Av<br />591 (19.6hrs): Bedford Av<br />592 (19.6hrs): Lorimer St<br />593 (19.6hrs): Graham Av<br />594 (19.7hrs): Grand St<br />595 (19.7hrs): Montrose Av<br />596 (19.7hrs): Morgan Av<br />597 (19.7hrs): Jefferson St<br />598 (19.8hrs): DeKalb Av<br />599 (19.8hrs): Myrtle-Wyckoff Avs<br />600 (19.8hrs): Halsey St<br />601 (19.9hrs): Wilson Av<br />602 (19.9hrs): Bushwick Av-Aberdeen St<br />603 (19.9hrs): Broadway Junction (visit 2)<br />604 (19.9hrs): Bushwick Av-Aberdeen St (visit 2)<br />605 (20.0hrs): Wilson Av (visit 2)<br />606 (20.0hrs): Halsey St (visit 2)<br />607 (20.0hrs): Myrtle-Wyckoff Avs (visit 2)<br />transfer lines<br />608 (20.1hrs): Myrtle-Wyckoff Avs<br />609 (20.1hrs): Seneca Av<br />610 (20.1hrs): Forest Av<br />611 (20.2hrs): Fresh Pond Rd<br />612 (20.2hrs): Middle Village-Metropolitan Av<br />613 (20.2hrs): Fresh Pond Rd (visit 2)<br />614 (20.3hrs): Forest Av (visit 2)<br />615 (20.3hrs): Seneca Av (visit 2)<br />616 (20.3hrs): Myrtle-Wyckoff Avs (visit 2)<br />617 (20.3hrs): Knickerbocker Av<br />618 (20.4hrs): Central Av<br />619 (20.4hrs): Myrtle Av<br />620 (20.5hrs): Marcy Av<br />621 (20.5hrs): Hewes St<br />622 (20.5hrs): Lorimer St<br />623 (20.6hrs): Flushing Av<br />624 (20.6hrs): Myrtle Av (visit 2)<br />625 (20.6hrs): Kosciuszko St<br />626 (20.6hrs): Gates Av<br />627 (20.7hrs): Halsey St<br />628 (20.7hrs): Chauncey St<br />629 (20.7hrs): Broadway Junction (visit 2)<br /></details>
<br />
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2025/08/25/speedrunning-the-new-york-subway/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Detecting code copying at scale with Vendetect</title>
    <id>https://www.sultanik.com/blog/vendetect</id>
    <updated>2025-07-21T07:00:00Z</updated>
    <published>2025-07-21T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/vendetect" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>Earlier this month, the maintainer of <a href="https://cheatingdaddy.com/">Cheating-Daddy</a> <a href="https://x.com/soham_btw/status/1940952786491027886">discovered</a> that a Y-Combinator-funded startup had copied their GPL-licensed codebase, stripped out the comments, and re-released it as “<a href="https://pickle.com/glass">Glass</a>” under an incompatible license. This isn’t an isolated incident; we see code theft and improper vendoring constantly during security assessments. So we built a tool to catch it automatically.</p>
<p><a href="https://github.com/trailofbits/vendetect">Vendetect</a> is our new open-source tool for detecting copied and vendored code between repositories. It uses semantic fingerprinting to identify similar code even when variable names change or comments disappear. More importantly, unlike academic plagiarism detectors, it understands version control history, helping you trace vendored code back to its exact source commit.</p>
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2025/07/21/detecting-code-copying-at-scale-with-vendetect/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Investigate your dependencies with Deptective</title>
    <id>https://www.sultanik.com/blog/deptective</id>
    <updated>2025-07-08T07:00:00Z</updated>
    <published>2025-07-08T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/deptective" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>Have you ever tried compiling a piece of open-source software, only to discover that you neglected to install one of its native dependencies? Or maybe a binary “fell off the back of a truck” and you want to try running it but have no idea what shared libraries it needs. Or maybe you need to use a poorly packaged piece of software whose maintainers neglected to list a native dependency.</p>
<p><a href="https://github.com/trailofbits/deptective">Deptective</a>, our new open-source tool, solves these problems. You can give it any program, script, or command, and it will find a set of packages sufficient to run the software successfully.</p><div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2025/07/08/investigate-your-dependencies-with-deptective/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Preventing account takeover</title>
    <id>https://www.sultanik.com/blog/account_takeover</id>
    <updated>2025-02-05T07:00:00Z</updated>
    <published>2025-02-05T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/account_takeover" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
This blog post highlights key points from our new white paper <a href="https://resources.trailofbits.com/hubfs/Resources/trailofbits-20250205-account-takeover-recommended-practices.pdf" target="_blank"><i>Preventing Account Takeovers on Centralized Cryptocurrency Exchanges</i></a>, which documents ATO-related attack vectors and defenses tailored to CEXes.
</p>
<p>
Imagine trying to log in to your centralized cryptocurrency exchange (CEX) account and your password and username just… don’t work. You try them again. Same problem. Your heart rate increases a little bit at this point, especially since you are using a password manager. Maybe a service outage is all that’s responsible (knock on wood), and your password will work again as soon as it’s fixed? But it is becoming increasingly likely that you’re the victim of an account takeover (ATO).
</p>
<p>CEXes’ choices dictate how (or if) the people who use them can secure their funds. Since account security features vary between platforms and are not always documented, the user might not know what to expect nor how to configure their account best for their personal threat model. Design choices like not supporting <a href="https://www.cisa.gov/sites/default/files/publications/fact-sheet-implementing-phishing-resistant-mfa-508c.pdf">phishing-resistant</a> multifactor authentication (<a href="https://www.ecfr.gov/current/title-16/chapter-I/subchapter-C/part-314/section-314.4#:~:text=Implement%20multi%2Dfactor%20authentication%20for%20any%20individual%20accessing%20any%20information%20system">MFA</a>) methods like <a href="https://security.googleblog.com/2019/05/new-research-how-effective-is-basic.html#:~:text=In%20fact%2C%20zero%20users%20that%20exclusively%20use%20security%20keys%20fell%20victim%20to%20targeted%20phishing%20during%20our%20investigation.">U2F hardware security keys</a>, or not tracking user events in order to push in-app “<a href="https://security.googleblog.com/2019/05/new-research-how-effective-is-basic.html#:~:text=Here%E2%80%99s%20how%20it%20works%3A%20if%20we%20detect%20a%20suspicious%20sign%2Din%20attempt%20(say%2C%20from%20a%20new%20location%20or%20device)%2C%20we%E2%80%99ll%20ask%20for%20additional%20proof%20that%20it%E2%80%99s%20really%20you.%20This%20proof%20might%20be%20confirming%20you%20have%20access%20to%20a%20trusted%20phone%20or%20answering%20a%20question%20where%20only%20you%20know%20the%20correct%20response.">was this you?</a>” account lockdown prompts when anomalies happen invite the attacker in.</p>
<p>Our white paper’s goal is to inform and enable CEXes to provide a <a href="https://www.cisa.gov/sites/default/files/2023-10/SecureByDesign_1025_508c.pdf">secure-by-design</a> platform for their users. Executives can get a high-level overview of the vulnerabilities and entities involved in user account takeover. We recommend a set of overlapping security controls that they can bring to team leads and technical product managers to check for and prioritize if not yet implemented. Security engineers and software engineers can also use our work as a reference for the risks of not integrating, maintaining, and documenting appropriate ATO mitigations.</p>
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2025/02/05/preventing-account-takeover-on-centralized-cryptocurrency-exchanges-in-2025/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Cruising Through Paradoxes</title>
    <id>https://www.sultanik.com/blog/cruising</id>
    <updated>2024-08-01T19:55:00Z</updated>
    <published>2024-08-01T19:55:00Z</published>
    <link href="https://www.sultanik.com/blog/cruising" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
    I grew up on the fringes of suburbia, at the cusp of what most would consider rural Pennsylvania.
    In the Spring, we gagged from the stench of manure.
    In the Fall, Schools closed on the first day of hunting season.
    In the Winter, fresh, out-of-season fruits were missing from the grocer.
    All year round, procuring exotic ingredients like avocados entailed a forty-five-minute drive toward civilization.
    During the school year, I was the first to be picked up and last to be dropped off by the bus,
    enduring a ride that was well over an hour each way.
</p>
<p>
    I also grew up in tandem with the burgeoning cruise line industry.
    My parents quickly adopted that mode of travel, and it eventually became our sole form of vacation.
    As a kid, it was great: I had the freedom to roam the decks on my own, there were innumerable activities,
    and an unlimited supply of delicious foods with exotic names like “Consommé Madrilene” and “Contrefilet of Prime
    Beef Périgueux”.
    My parents loved it because it kept their kids busy, was very affordable (relative to equivalent landed resorts),
    and had sufficient calories to satisfy their growing boy’s voracious appetite.
    This was also a transitional period when cruises were holding onto the vestiges and traditions of luxury ocean
    liners. All cruise lines had strict dress codes, requiring formal attire some evenings (people brought tuxedos!).
    The crew were largely Southern and Eastern European. As a kid who had never traveled outside North America, it felt
    like I was LARPing as James Bond.
</p>
<p>
    When I moved out of my parents’ house for college, I wanted a change of scenery.
    While I had the option to move to a “college town”, I instead chose to live in a large city.
    And I loved it.
    It was like living on a cruise, all year round: Activities galore, amazing food, and all within a short distance of
    each other.
    A friend could call me up and say, ”Hey, we are hanging out at [X], would you like to join us?” And, regardless of
    where X was in the city, I could meet them there within fifteen minutes either by walking, biking, or taking public
    transport.
</p>
<p>
    I didn’t <em>need</em> cruises anymore.
</p>
<hr />
<h3>Preface</h3>
<p>
    This year, for his birthday, my father only had one request: that he and his extended family take a cruise to
    celebrate. I just returned from that cruise, and it was a very different experience from the ones of my youth.
</p>
<p>
    As an adult who had by this point lived the majority of his life in large cities,
    all I wanted to do was lay by a pool or, preferably, the beach all day and read a book.
    Those are both difficult things when you’re sharing a crowded pool space with over six thousand other people,
    and the ship doesn’t typically dock close to a good beach.
    Skating rink? Gimmicky specialty restaurants? Luxury shopping spree? Laser tag? Pub trivia? Theater productions?
    Comedy shows?
    I can do all of those things any day of the week a short distance from my house.
    When I vacation, I want to escape all that freneticism.
</p>
<p>
    My wife, kids, and I were the only urbanites in our group, and my parents didn’t seem to comprehend why we
    had such little interest in all the activities. And then it dawned on me: <b>A cruise is just a simulated city.</b>
    <em>Why would I want an artificial version of what I already have?</em>
</p>
<p>
    So, lying down on a deck chair, instead of reading my book, I started writing.
    The idea of <em>simulated urbanism</em> <a href="https://www.youtube.com/watch?v=aGjc-gsh834">isn’t new</a>,
    but it’s typically discussed in terms of curated amusement parks like Disney and the emergence of suburban
    “lifestyle center” developments. Therefore, initially, my goal was to channel this insight into as obnoxious a
    treatise as possible, in order to trigger my suburbanite traveling companions. <em>Simulated</em> urbanism? That
    reminded me of <a href="https://en.wikipedia.org/wiki/Jean_Baudrillard">Baudrillard</a>!
    I would make it a completely over-the-top academic analysis of the topic.
</p>
<img src="/images/simulacrum.png" alt="Simulacra and Simulation" style="max-width: 80%; display: block; margin-top: 16px; margin-bottom: 12px; margin-left: auto; margin-right: auto; padding: 4px; background-color: #fff; border: 1px solid #ddd; border-radius: 4px;"/>
<p>
    The following was compiled from a series of texts I sent to our group
    chat throughout the cruise.
</p>
<hr style="height:0px;border: none;border-top: 3px solid black;" />
<h4>Abstract</h4>
<p>
    This article explores the paradox of vacation preferences among suburban Americans who gravitate toward densely populated environments such as cruises, European cities, and amusement parks, despite residing in sparsely populated areas. It examines how cruises and lifestyle centers, which mimic urban density while offering suburban convenience, satisfy the suburban desire for urban-like experiences. The article contrasts these preferences with those of urban Americans, who experience density daily and may seek different vacation experiences. By analyzing the dynamics of suburban and urban vacation choices, we highlight the complex interplay between suburban living and the pursuit of urban escapism.
</p>
<h2>Simulated Urbanism</h2>

<h3>Simulacra and Simulation</h3>

The concept of ”simulated urbanism,” as seen in cruise ships and lifestyle centers, can be analyzed through the lens
of Jean Baudrillard’s philosophy, particularly his ideas on simulation and hyperreality. Baudrillard argues that in
contemporary society, simulations—representations or imitations of reality—have become so pervasive that they blur the
distinction between what is real and what is artificially constructed. In the context of simulated urbanism, lifestyle
centers and cruise ships serve as hyperreal environments that imitate the vibrancy and density of urban life without the
complexities and inconveniences associated with real urban spaces. They provide an experience that is more accessible,
manageable, and, in some ways, more appealing than the genuine urban environments they emulate.

According to Baudrillard, these simulations can create a sense of hyperreality, where the imitation becomes more
influential or desirable than reality itself. Suburban Americans, who are accustomed to the sprawling, car-dependent
landscapes of suburbia, find in these simulated urban environments a curated and sanitized version of city life. This
artificial urbanism allows them to engage with the aesthetics and experiences of urban density—such as walkability,
diverse entertainment, and social interaction—without the perceived drawbacks of real urban living, like congestion,
pollution, and crime. Thus, simulated urbanism not only fulfills a desire for the excitement and dynamism of city life
but also constructs a hyperreal experience that is tailored to the preferences and comfort of suburban consumers,
aligning with Baudrillard’s notion of a society increasingly detached from the authenticity of the real world.

<h3>Metamodernism</h3>

<p>
    Suburbanites’ predilections for cruising can be interpreted through the theoretical framework of metamodernism, which posits an oscillation between opposing cultural and experiential paradigms. The cruise experience encapsulates a synthesis of modernist aspirations for progress, order, and structured entertainment, alongside a postmodern sensibility characterized by irony and skepticism towards mass consumerism and the spectacle. This dialectical tension aligns with metamodernism’s core principle of navigating and reconciling contradictions. Within the confines of a cruise, suburbanites engage with the modernist ideal of escape and luxury, encountering a curated simulacrum that offers both adventure and novelty. Simultaneously, they remain cognizant of the inherent artifice and commodification intrinsic to the cruise experience, reflecting a postmodern consciousness of the limitations and constructed nature of such escapism.
</p>
<p>
    Furthermore, the pragmatic idealism inherent in metamodernism is evident in the suburban pursuit of cruising, representing a quest for authenticity within a meticulously orchestrated environment. Suburbanites partake in cruising as a form of meaningful escapism that, although commodified, facilitates genuine opportunities for relaxation, social interaction, and cultural exploration. This dynamic reflects a metamodern synthesis of sincerity and irony, wherein participants seek genuine engagement and fulfillment while maintaining an awareness of the artificial and consumerist underpinnings of the cruise industry. The cruise, thus, serves as a microcosm of metamodern cultural hybridity, integrating diverse influences and experiences into a cohesive assemblage that enables suburbanites to navigate the complexities of contemporary existence with both optimism and reflexivity. This exemplifies the metamodern tension between the yearning for authentic connection and the recognition of its mediated nature, embodying a dialectical interplay that is central to metamodern thought.
</p>

<h3>Dialectics</h3>

<p style="color:gray;">
(To be read as if dictated by <a href="https://en.wikipedia.org/wiki/Slavoj_%C5%BDi%C5%BEek">Slavoj Žižek</a>.)
</p>

<p>
From a Hegelian perspective, urbanites’ preferences for relaxing vacations can be understood through the lens of dialectical progression and the quest for synthesis between opposing elements in their lives. Hegel’s philosophy emphasizes the process of thesis, antithesis, and synthesis, <span style="color:gray;">[sniff]</span> where the contradictions and tensions between different aspects of existence lead to the development of higher levels of understanding and being. A dance of contradictions and tensions.
</p>

<!--<p>Urbanites, who live in environments characterized by constant activity, complexity, and stimulation, may seek vacations as a form of antithesis to their daily experiences. These relaxing retreats provide a counterbalance, allowing them to reconcile the tension between the fast-paced nature of urban life and the human need for rest and tranquility.</p>-->

<p>
Urbanites are like rats in a maze of their <em>own</em> making, living in this frenetic environment of constant stimulation and complexity. So, what do they do? They escape to a vacation that provides the antithesis of urban life, a necessary counterbalance that allows them to confront the contradictions of their daily existence.
</p>

<p>
In this dialectical process, the vacation can be seen as a moment of synthesis, where urbanites integrate the contrasting aspects of their existence—work and leisure, complexity and simplicity, stimulation and relaxation. Through this synthesis, they achieve a more harmonious state of being, temporarily resolving the contradictions inherent in their lives. <span style="color:gray;">[nose pull]</span> Hegel might argue that this pursuit of balance is part of a broader process of self-realization and development, as individuals continually seek to reconcile opposing forces within themselves and their environments. This dialectical movement reflects a deeper philosophical journey toward self-awareness and fulfillment, where each vacation experience contributes to a more nuanced understanding of personal and existential needs.
</p>

<p>
Moreover, Hegel would likely emphasize that this process is not static but dynamic, as urbanites constantly redefine and re-evaluate their desires and experiences in pursuit of higher forms of understanding and contentment. <span style="color:gray;">[sniff]</span> This ongoing dialectical interaction between urban life and vacation preferences underscores the complexity of human existence and the continuous evolution of individual consciousness within the broader historical and cultural context.
</p>

<h3>What Would Marx Say?</h3>

<p style="color:gray;">
(For extra fun, to be read as if dictated by Jordan Peterson.)
</p>

<p>
When we examine the suburbanite’s preference for urban-like vacation experiences—such as cruising or visiting bustling cities—through the lens of Marxist theory, we uncover something quite profound about the alienation inherent in capitalist societies. Suburban life is often marked by routine and compartmentalization, a strong reliance on cars, and an emphasis on private space. This creates an environment of isolation and fragmentation, which Marx identified as symptomatic of capitalist production. The sprawling nature of suburbia physically separates individuals from their workplaces, social hubs, and cultural activities, generating a dichotomy between home life and community engagement. This alienation from collective social experiences mirrors the detachment workers feel from the products of their labor and from each other in a capitalist framework.
</p>

<p>
Thus, when suburbanites seek out vacations in dense, walkable environments, they’re searching for a temporary reprieve from this isolation. These vacations allow them to engage with the social interactions and cultural experiences that are often missing from their everyday lives. In this way, vacations become a commodified form of leisure within capitalist society, packaged and sold as products designed to alleviate the stresses of alienation and labor. Suburbanites, who feel the pressures of maintaining a lifestyle dictated by capitalist norms—like homeownership and consumerism—turn to vacations as a form of respite from these demands. Cruises and urban vacations offer a concentrated form of entertainment and cultural engagement, providing an illusion of freedom and choice that contrasts with the regulated and constrained nature of suburban life. While these vacations temporarily satisfy the need for genuine human connection and cultural enrichment, Marxist theory would argue that they also reinforce the capitalist cycle, as individuals must return to their suburban routines to earn the means to participate in such leisure activities. Thus, vacations, though they offer a brief escape from alienation, ultimately underscore the pervasive influence of capitalism on leisure and personal fulfillment.
</p>

<h3>Conclusions</h3>

<p>
    As I reflect on the whirlwind of contradictions, philosophies, and cultural dynamics explored in this article, I must
admit that I find myself utterly exhausted. Much like the aftermath of a cruise, where the buffet line feels both
endless and insurmountable, I am too fatigued to draw any tidy conclusions. So, dear reader, as I lean back in my
metaphorical deck chair, I invite you to navigate these intellectual waters and draw your own conclusions. Like the
    towel animals on your cabin bed, reality might be folded and shaped in surprising ways, but the essence remains
    yours to unravel. Bon voyage in your own journey of trolling! Or is it trawling?
</p>
</content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">PoC‖GTFO Issue 0x22</title>
    <id>https://www.sultanik.com/pocorgtfo/#0x22</id>
    <updated>2024-02-03T00:00:00Z</updated>
    <published>2024-02-03T00:00:00Z</published>
    <link href="https://www.sultanik.com/pocorgtfo/#0x22" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html"><a href="/pocorgtfo/#0x22"><center style="padding-top:9px"><div style="width:80%;overflow:hidden;border:1px solid #021a40;background:white;"><img style="width:100%;padding: 0px;"
               srcset="/pocorgtfo/pocorgtfo22_large.png  700w,
                       /pocorgtfo/pocorgtfo22_medium.png 500w,
                       /pocorgtfo/pocorgtfo22_small.png  350w"
               sizes="(min-width: 768px) 730px,
                      100vw"
               src="/pocorgtfo/pocorgtfo22.png" alt="International Journal of PoC$\|$GTFO" /></div></center></a></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">How to avoid the aCropalypse</title>
    <id>https://www.sultanik.com/blog/acropalypse</id>
    <updated>2023-03-30T07:00:00Z</updated>
    <published>2023-03-30T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/acropalypse" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
Last week, news about CVE-2023-21036, nicknamed the
“<a href="https://www.da.vidbuchanan.co.uk/blog/exploiting-acropalypse.html" target="_blank">aCropalypse</a>,” spread
across <a href="https://twitter.com/ItsSimonTime/status/1636857478263750656" target="_blank">Twitter</a> and other
media, and my colleague Henrik Brodin quickly realized that the underlying flaw could be detected by our tool,
<a href="https://github.com/trailofbits/polytracker" target="_blank">PolyTracker</a>.
Coincidentally, Henrik Brodin, Marek Surovič, and I <a href="https://arxiv.org/abs/2301.08700" target="_blank">wrote</a>
 a paper that describes this class of bugs, defines a novel approach for detecting them, and introduces our
 implementation and tooling. It will appear at this year’s workshop on Language-Theoretic Security
 (<a href="https://langsec.org/spw23/" target="_blank">LangSec</a>) at the IEEE Security and Privacy Symposium.
</p>
<p>
The remainder of this blog post describes the bug and how it could have been detected or even prevented using our tools.
</p>
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2023/03/30/acropalypse-polytracker-blind-spots/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">libmagic</title>
    <id>https://www.sultanik.com/blog/libmagic</id>
    <updated>2022-08-01T07:00:00Z</updated>
    <published>2022-08-01T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/libmagic" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
A <a href="https://blog.trailofbits.com/2019/11/01/two-new-tools-that-tame-the-treachery-of-files/">couple of years
ago</a> I released <a href="https://github.com/trailofbits/polyfile">PolyFile</a>: a utility to identify and map the
semantic structure of files, including polyglots, chimeras, and schizophrenic files. It’s a bit like file, binwalk, and
Kaitai Struct all rolled into one. PolyFile initially used the <a href="https://mark0.net/soft-trid-deflist.html">TRiD
definition database</a> for file identification. However, this database was both too slow and prone to
misclassification, so we decided to switch to libmagic, the ubiquitous library behind the file command.
</p>
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2022/07/01/libmagic-the-blathering/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">PoC‖GTFO Issue 0x21</title>
    <id>https://www.sultanik.com/pocorgtfo/#0x21</id>
    <updated>2022-02-15T00:00:00Z</updated>
    <published>2022-02-15T00:00:00Z</published>
    <link href="https://www.sultanik.com/pocorgtfo/#0x21" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html"><a href="/pocorgtfo/#0x21"><center style="padding-top:9px"><div style="width:80%;overflow:hidden;border:1px solid #021a40;background:white;"><img style="width:100%;padding: 0px;"
               srcset="/pocorgtfo/pocorgtfo21_large.png  700w,
                       /pocorgtfo/pocorgtfo21_medium.png 500w,
                       /pocorgtfo/pocorgtfo21_small.png  350w"
               sizes="(min-width: 768px) 730px,
                      100vw"
               src="/pocorgtfo/pocorgtfo21.png" alt="International Journal of PoC$\|$GTFO" /></div></center></a></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">What does your code use, and is it vulnerable?</title>
    <id>https://www.sultanik.com/blog/it_depends</id>
    <updated>2021-12-16T07:00:00Z</updated>
    <published>2021-12-16T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/it_depends" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
I am proud to announce the release of
<a href="https://github.com/trailofbits/it-depends" target="_blank">it-depends</a>, an open-source tool for automatic
enumeration of dependencies. You simply point it to a source code repository, and it will build a graph with the
required dependencies. It-depends currently supports cargo, npm, pip, go, CMake, and autotools codebases, packages in
their associated package managers, and Ubuntu apt.
</p>
<div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2021/12/16/it-depends/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">PDF is Broken: a justCTF Challenge</title>
    <id>https://www.sultanik.com/blog/PDF_is_broken</id>
    <updated>2021-02-02T07:00:00Z</updated>
    <published>2021-02-02T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/PDF_is_broken" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
<p>
I recently created a challenge for the <a href="https://2020.justctf.team/" target="_blank">justCTF competition</a>
titled <a href="https://2020.justctf.team/challenges/1" target="_blank"><i>PDF is broken, and so is this file</i></a>.
It demonstrates some of the PDF file format’s idiosyncrasies in a bit of an unusual steganographic puzzle. CTF
challenges that amount to finding a steganographic needle in a haystack are rarely enlightening, let alone enjoyable.
LiveOverflow recently had <a href="https://www.youtube.com/watch?v=VVdmmN0su6E#t=11m32s" target="_blank">an excellent
video on file format tricks</a> and concludes with a similar sentiment. Therefore, I designed this challenge to teach
justCTF participants some PDF tricks and how some of the open source tools I’ve helped develop can make easy work of
these forensic challenges.
</p>
<p>
Read the full post on the Trail of Bits blog for spoilers on how to solve the puzzle.
</p><div class="alert tob-alert">
<img src="/images/logos/Trail-of-Bits-main-dark-background.png" height="32px"/>
This is an excerpt from the <a href="https://www.trailofbits.com/" target="_blank">Trail of Bits</a>
<a href="https://blog.trailofbits.com/" target="_blank">blog</a>.
You can read the full post <a href="https://blog.trailofbits.com/2021/02/02/pdf-is-broken-a-justctf-challenge/" target="_blank">here</a>.
</div></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">So, you’re thinking about getting a Ph.D.</title>
    <id>https://www.sultanik.com/blog/PhDCurious</id>
    <updated>2020-04-08T07:00:00Z</updated>
    <published>2020-04-08T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/PhDCurious" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
            <div>
            <style>
            .content img {max-width: 80%; display: block; margin-top: 16px; margin-bottom: 12px; margin-left: auto; margin-right: auto; padding: 4px; background-color: #fff; border: 1px solid #ddd; border-radius: 4px;}
            </style>
            
<p>
    <b>Note:</b> My advice is specifically related to the higher education system in the US; other countries have very different systems.
    My advice is also solely based on experience in the field of Computer Science; this may translate to other STEM fields, but certainly not all academic fields.
</p>
<h2>Do you really want a Ph.D.?</h2>
<p>
    Make sure you are doing this for the right reasons!
</p>
<h3>Reasons <em>to</em> get a Ph.D.</h3>
<ul>
    <li><b>You want to work in academia.</b> If you want to get a tenure track research position at a university, you need a Ph.D.</li>
    <li><b>You need it to get a promotion at work.</b>
        This is typically only true at larger corporations, where having
        certain credentials is necessary to progress through the ranks.
    </li>
    <li><b>You enjoy being in an academic environment and solely want the experience.</b>
        This is perfectly valid. Being in grad school can (but isn’t guaranteed to) be incredibly invigorating.
    </li>
</ul>
<h3>Reasons <em>not</em> to get a Ph.D.</h3>

<h4>Dat Phizzle Dizzle Doh</h4>
The novelty of putting those letters after your name and/or being called “Doctor” wears off real quick.

<h4>You just want to teach at a university</h4>
Universities are really hungry for adjunct professors these days. You usually don’t need a Ph.D. to teach.
Try teaching a class or two before you commit to getting a Ph.D. and making that your career.
I’ve taught a bunch of classes, both at the undergraduate and graduate levels, including developing the entire syllabus,
assignments, and slides all from scratch. It is <em>a lot</em> of work, and usually not worth what they pay you.

<h4>You want to work on your dissertation topic for the rest of your career</h4>
I know dozens, maybe hundreds of Ph.D.s, and I can count on one hand the number of people who continued research related
to their dissertation topic after graduation.

<h4>Imposter Syndrome</h4>
I’ve worked with plenty of people with <em>no degree</em> who are far more capable than people with multiple grad
degrees.

<h4>You’re probably not going to get a job in academia</h4>
I know <em>several</em> people who got Ph.D.s from top tier schools like CMU and MIT and all of them either ended up
in industry or teaching at small liberal arts schools with no graduate program (because they were dead set on ascending
the ivory tower). The academic market is super tough, and will only get tougher thanks to the inevitable closure of
smaller schools and a general preference for adjuncts over tenure-track professors. Ph.D. programs do not limit the
number of students they accept based on the anticipated number of professorial job openings. There are many more
Ph.D.s than professorships!

<h4>Even if you do get your dream job in academia, you’ll probably hate it and/or lose it</h4>
I don’t think I know of a single professor, tenured or otherwise, who loves their job.
They need to take on a huge teaching load thanks to the dearth of adjuncts and/or assume administrative positions that
do not incur an increased salary.

<h4>The financial implications and opportunity cost of leaving your job for three to ten years</h4>
Some studies have concluded that getting a Ph.D. will
<a href="https://web.cs.ucdavis.edu/~matloff/itaa.real.html">require up to <em>fifty</em> years</a> to outweigh the
opportunity cost of staying in the workforce and advancing your career. But in some circumstances
<a href="/blog/Economics_of_Education">it can be as few as five years</a>. This is because there is a lot of variance in
the compensation for graduate students. Be prepared for three to ten years of significantly reduced income.

<h4>The Snake Fight</h4>
<a href="https://www.mcsweeneys.net/articles/faq-the-snake-fight-portion-of-your-thesis-defense">Beware</a>.

<h3>Common reasons you will fail</h3>

There are myriad reasons why you might fail to complete your Ph.D. that are almost all completely out of your control.

<h4>Survivor bias is real. Trust me, I’m a survivor.</h4>
Only two out of the ~dozen students in my research lab ever completed their degree. Keep that in mind when you take
advice from the survivors.

<h4>Someone “scoops” your research</h4>
This is typically more of an issue in the more theoretical specializations, but it does happen. If someone solves your
problem before you, you’ve got to start over. <a href="/blog/Retirement_planning">I’ve written an essay about this.</a>

<h4>Your advisor switches schools</h4>
Sometimes this can be a good thing; for example, a friend of mine’s advisor transferred from an average school to MIT
right before my friend graduated, and he was able to transfer over all of his credits, defend at MIT, and get MIT on his
diploma. But I also know a bunch of people who were bitten by this, where the new school would not accept their credits
and/or there was no funding at the new school for tuition remission and a stipend, so they basically had to drop out.

<h4>Your advisor goes on sabbatical</h4>
It’s hard to be advised if your advisor is off galavanting for a year or two. Good advisors plan for this, but I know of
several cases where students had to drop out because their advisor didn’t plan ahead.

<h4>You don’t get along with your advisor, or they go AWOL, or their tenure application is denied, (or they die)</h4>

Ever look at a 101-level STEM textbook? There are usually at least two authors: The one who knows what they’re talking
about, and the one who speaks English as a native language. I had two advisors for basically the same reason. My first
advisor had lots of research grants and contracts which afforded me tuition remission and a good stipend. But that work
was mostly applied science; nothing was deep enough to turn into a thesis topic. So I took on a co-advisor who had just
been hired as a new tenure-track professor and was full of cool ideas. A few months later he unfortunately, suddenly,
died. Then I took on a <em>third</em> co-advisor (who was happy to take me on because he didn’t have to worry about
paying me from his own grants). This amounted to more work for me, since I had to do the work to “pay the bills” with my
original advisor <em>as well as</em> my <em>actual</em> research with my new co-advisor. But it also gave me a bunch of
freedom to just work on what I wanted. With that said, I had two labmates who were working under my late co-advisor who
were unable to find a place for themselves after his death, and never completed their dissertations. A lot of it is
luck.

If a professor’s tenure application is denied, they are usually given a year to wrap up their business and leave the
school. Most departments have contingency plans to pair orphaned graduate students with new advisors, but this can be
a devastating blow to most students, for all intents and purposes similar to their passing away.

<h4>You don’t have enough time to focus on your research</h4>
In my case, I was effectively working a full time job doing applied research for my first advisor <em>in addition</em>
to being a “regular” graduate student with my co-advisor. This entailed 60+ hour work weeks for basically my entire
Ph.D. It’s super hard to focus on research if you have a full time job; I only know of one or two people who
successfully completed a part-time Ph.D. while working a full time job at the same time.

<h2>You still want to get a Ph.D.?</h2>
<h3>Things you need to do before applying</h3>
<h4>Do you already have a master’s degree?</h4>
Some schools in the US do not require you to take <em>any</em> classes, while most others require you to effectively
earn a Master’s in the process of getting your Ph.D.

If you <em>do not</em> have a Master’s yet, try and choose a school that effectively forces you to earn a Master’s in
the process of getting a Ph.D., as that will be a nice consolation prize in the event that you do not complete your
dissertation.

If you <em>do</em> have a Master’s, check on your prospective school’s degree requirements and whether they will accept
your existing credits. If a school requires you to take a bunch of classes and you don’t want to earn a second Master’s,
make sure they will waive that requirement for you. This affected me when I was deciding on which program to join, since
I already had a Master’s and many schools wouldn’t budge on forcing me to re-do all of my Master’s classes.

<h4>Decide in what you want to specialize</h4>

More on this below, but it’s best if you know what you want to research <em>before</em> you apply to a program.
You don’t choose a school for a Ph.D. the same way you choose a school for an undergrad or even a Master’s degree.
Choose the school based upon how your desired research aligns with what the professors there are doing, <em>not</em>
based upon the name or prestige of the school.

<h4>Read the entire Ph.D. Comics archive</h4>

<a href="https://phdcomics.com/comics/archive_list.php">Seriously, it’s really good, and completely accurate.</a>

<h3>How to get into a good program</h3>

<h4>Find potential advisors first</h4>
Compile a list of everyone who is actively doing research in an area related to your desired specialization.
Send them an E-mail stating your desire to pursue a Ph.D. Ask them if they are taking on new students, and, if so, what
their time frame is. The easiest way to get accepted to a Ph.D. program is to have a professor advocating on your
behalf. If a professor wants to work with you, they can guide and even fast-track you through the admissions process.

<h4>You should not have to pay your way through a Computer Science Ph.D.</h4>
Don’t expect to be rich, but every decent computer science Ph.D. program should offer tuition remission <em>and</em> a
slightly-above-the-poverty-line stipend, either by acting as a teaching assistant (TA) or as a research assistant (RA).
Do not accept any less. If the school wants you to pay for your Ph.D., something is wrong.
Being an RA is preferable to a TA.

<h4>Having a source of external funding lined up will get you into almost any school</h4>
The biggest limiting factor in taking on new students both at the departmental and professorial levels is funding.
A professor will not advise a new student unless they have enough funding (either through grants/contracts that fund
RA-ship, or through departmental TA-ships). If there are no TA openings and/or the professor doesn’t have enough grant
funding to pay for your stipend and tuition remission, then they won’t take you on as a student.
In such situations, you can either pay for your own tuition and forego a stipend (never, ever, do this!),
or you can come to the table with <em>your own</em> external source of funding! This can be through a grant
program (<i>e.g.</i>, the <a href="https://www.nsf.gov/funding/pgm_summ.jsp?pims_id=6201">NSF GRFP</a>).
If a professor doesn’t have to worry about how to “feed” you, they’ll be thrilled to work with you, and it will give you
a lot more freedom in directing your own research.

<h3>How to minimize your chances of failing</h3>

<h4>Talk to your potential advisor’s current and past students</h4>

Do this preferably before even applying. How many of the professor’s students actually graduate?
Where do they end up after graduation? How many papers does each student publish per year?
How is travel to conferences funded?

<a href="https://phdcomics.com/comics/archive.php?comicid=997"><img src="/images/phdcomics/997.gif"
                                                                    alt="PhD Comics Number 997"/></a>

What is the professor’s advising style like? This will vary drastically from professor to professor.
I’d be lucky to talk to one of my co-advisors once a month.

<a href="https://phdcomics.com/comics/archive.php?comicid=851"><img src="/images/phdcomics/851.gif"
                                                                    alt="PhD Comics Number 851"/></a>

My other co-advisor would actually sit down with me 1-on-1 and we’d read aloud a new paper together,
sentence-by-sentence, ensuring that we each understood what was written before moving on. Some people might hate that,
though. Different styles work for different kinds of students. Some professors demand that you work on a specific
problem they have defined, whereas others expect you to carve out your research topic yourself. Determine what type of
advisor you <em>think</em> you need, and interview existing students to see if the professor meets your needs.

<h4>Interview your potential advisor in advance</h4>
What is a typical week in the life of an advisee like? How many regular meetings are there? How often do students
typically meet with their advisor 1-on-1? Will the professor expect you to take any specific classes, regardless of the
school’s degree requirements? Professors will often require you to take certain classes they think are really good. Is
the professor planning to go on sabbatical any time soon? Do they have tenure? (Typically, professors will earn and
usually take a sabbatical shortly after earning tenure. If a professor applies for tenure and is denied, they usually
only get a year before they are fired. Some schools give professors two chances at getting tenure.) What is the
professor’s teaching load like? Would they expect you to teach and/or TA? Or could you be an RA full time? What is their
research grant pipeline like? When do their current grants end?

<h4>Choose a topic that is unlikely to be “scooped”</h4>

I already linked to this above, but please <a href="/blog/Retirement_planning">read this essay I wrote</a>.
Try and choose a dissertation topic that can’t be duplicated by someone else first. This usually means choosing a topic
that—even if it is inherently theoretical—could worst-case be “proven” <em>empirically</em> in the event that you can’t
prove it <em>formally</em>.

<h4>Remember that your dissertation is unlikely to ever be read by anyone other than your committee members</h4>

It is, in a sense, a rite of passage. If you don’t intend to go into academia, there is no shame in doing the minimum
amount possible that can get you graduated. With that said,
<a href="/files/ESultanikPhDDissertationBook.pdf">my dissertation is super awesome and you should totally read it right
    now</a>. Plz, become the sixth person to have ever read it.

<a href="https://phdcomics.com/comics/archive.php?comicid=1164"><img src="/images/phdcomics/1164.gif"
                                                                    alt="PhD Comics Number 1164"/></a>

<h2>What to expect after you have a Ph.D.</h2>

<a href="https://phdcomics.com/comics/archive.php?comicid=844"><img src="/images/phdcomics/844.gif"
                                                                    alt="PhD Comics Number 844"/></a>
<a href="https://phdcomics.com/comics/archive.php?comicid=994"><img src="/images/phdcomics/994.gif"
                                                                    alt="PhD Comics Number 994"/></a>

            </div>
            </content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">PoC‖GTFO Issue 0x20</title>
    <id>https://www.sultanik.com/pocorgtfo/#0x20</id>
    <updated>2020-01-21T00:00:00Z</updated>
    <published>2020-01-21T00:00:00Z</published>
    <link href="https://www.sultanik.com/pocorgtfo/#0x20" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html"><a href="/pocorgtfo/#0x20"><center style="padding-top:9px"><div style="width:80%;overflow:hidden;border:1px solid #021a40;background:white;"><img style="width:100%;padding: 0px;"
               srcset="/pocorgtfo/pocorgtfo20_large.png  700w,
                       /pocorgtfo/pocorgtfo20_medium.png 500w,
                       /pocorgtfo/pocorgtfo20_small.png  350w"
               sizes="(min-width: 768px) 730px,
                      100vw"
               src="/pocorgtfo/pocorgtfo20.png" alt="Grab gifts from the genizah, reading every last page! And write in their margins! And give them all again!" /></div></center></a></content>
  </entry>
  <entry xml:base="https://www.sultanik.com/recent.atom">
    <title type="text">Breaking into Google Headquarters</title>
    <id>https://www.sultanik.com/blog/GoogleIntrusion</id>
    <updated>2019-04-05T07:00:00Z</updated>
    <published>2019-04-05T07:00:00Z</published>
    <link href="https://www.sultanik.com/blog/GoogleIntrusion" />
    <author>
      <name>Evan Sultanik</name>
      <uri>https://www.sultanik.com/</uri>
    </author>
    <content type="html">
            <div>
            <style>
            .content img {max-width: 80%; display: block; margin-top: 16px; margin-bottom: 12px; margin-left: auto; margin-right: auto; padding: 4px; background-color: #fff; border: 1px solid #ddd; border-radius: 4px;}
            </style>
            Fifteen years ago, a handful of my grad school labmates and I found ourselves at the brand new Googleplex.
Dear reader, I think it’s finally safe for me to tell the story of that one time I trespassed into Google’s
headquarters and took lots of pictures. <a href="/blog/GoogleIntrusion">Read on if you’d like to hear the story and see some of my pictures</a>.
<img src="/images/google/googleplex.jpg" alt="Google's then-new digs" style="max-width: 80%; display: block; margin-top: 16px; margin-bottom: 12px; margin-left: auto; margin-right: auto; padding: 4px; background-color: #fff; border: 1px solid #ddd; border-radius: 4px;" />

            </div>
            </content>
  </entry>
</feed>
