time warner cable – different person, different problem?

I haven’t a problem that was maddening when dealing with Time Warner since 2010. It’s that time again.

Background

My cable/DVR box has been slowing getting worsening problems for a while:

  1. freezing periodically for a few seconds
  2. saying there was 0% recorded (a reboot solved that, but it happened about once a month)
  3. turning off and not recording with a reboot. then after the reboot would start recording the middle of a show as if it were a long standing agreement

As I had shows I wanted to watch on the DVR, I chose to live with the first two problems. The third one is core functionality of a DVR so had to deal with it and get a different DVR.

Saturday

I went to the Time Warner store. I returned the Scientific American box and was given a “new” Samsung box. And by “new” I mean a box that someone else returned, they presumably tested and then gave to me. Here’s what happened:

  1. I plugged in the box and it told me to call Time Warner to activate. I haven’t had to do that when trading boxes in the past, but ok. That’s reasonable. They activated the box and had me restart the box. I appeared to have TV.
  2. I went to “Free Primetime On Demand” and got a message to call Time Warner. The rep says she needs to check if it is on my plan. It is FREE primetime on demand. I’m pretty sure it is on everyone’s plan. (This is the station for network tv after it airs. Which I wanted to watch because my DVR wasn’t working last week when I tried to record them.) She eventually gets back to me and agrees I should have it. Guess what the solution was? Reboot the box. I imagine she did something at her end as well.
  3. A little later in the day, I found that cable stations would freeze after a few seconds of play. Network stations (over the air equivalents) played just fine. When I called time warner she “runs a signal test” and tells me the problem is with the box and they can send a tech. If the problem is with the box, I can go to the store and trade boxes again. I don’t need to wait for a tech. When I complain I don’t want to wait for a tech, she tells me it won’t come until Tuesday if they mail a box. I don’t want them to mail the box. I then tried rebooting again.
  4. Provisioning – H/E error – We never got to the bottom of this one although it sounds like an issue with the box. (I also had noCP, but that was when I had the box plugged in wrong.) The tech “ran a signal test.” The tech claimed the provisioning error was because it was a used box and it was downloading updates. At 6:30pm, the rep says she will call me back at 8:30pm to follow up.
  5. She calls at just before 11pm. That’s late to be calling someone. What if I had children who were sleeping? At 11pm, she “ran a signal test” and told me the problem was with the box.

Sunday

Back to the Time Warner store. The rep lives near me and asked if there was construction nearby. There was. He then runs a signal test and tells me there is a problem with the signal. As I spoke to several people who did that the previous day who “ran a signal test”, I was suspicious. He shows me a red screen. However, the cable box was in my hand rather than plugged in at home so still suspicious. He tells me that they need to send a tech to check/fix the signal. Sigh. I give up. Fine. I’ll arrange to be home for a tech to come.

Monday

I had an appointment for between 3 and 4pm. That gave me time to work for half a day in the office and telecommute the rest of the day. I got home around 2pm. I have two messages on my cell phone voicemail and one on my home phone. Two messages say that if I don’t pick up, my appointment will be cancelled. The last says my appointment is confirmed and the tech will call before coming up. Weird.

Since I had time, I decided to go buy lunch. I get back at 2:15pm. At 2:21pm, the tech arrives. That’s not between 3 and 4. What if I wasn’t home? Would I have missed my appointment?

The tech said the problem was the box. (No kidding, this was apparent on Saturday.) He installed a new box. A brand new box.  This time a Cisco one. Which requires over 40 minutes of software downloads before it starts. Which their tech had to be here for. So he got paid to watch videos on my couch for almost an hour. This isn’t his fault. The tech did a great job. He was helpful and polite. Just not necessary. I am perfectly capable of plugging in a box and waiting for an hour.

 

fixing clickjacking and brute force login for jforum

I’ve been blogging about some of the security fixes we’ve made in the CodeRanch fork of JForum such as XSS with quotes and CSRF. Today it is time to write about Clickjacking and preventing brute force logins.

Clickjacking

Clickjacking is an attack where someone includes your site in transparent frames and the attacker intercepts anything typed in/clicked. We had originally decided not to do anything about ClickJacking because we want our site to be available in frames. For example, DZone serves the main page in a frame when asking people to vote on it.

However, that doesn’t mean that we shouldn’t protect anything. We decided to protect the most critical parts of the site – the admin screens and the login form. That leaves the read only pages (which we don’t mind framed) and editing posts/user info (which is displayed publicly anyway).

The implementation turned out to be simple. We added this header to the relevant pages. (the admin screens are always within a frame on the site and the login screen is when an admin’s session times out).

response.setHeader("X-Frame-Options", "SAMEORIGIN");

It turned out the method only needed to be called from two places: UserAction (for login) and the AdminCommand (for the admin console).

While this isn’t complete protection, it is certainly better than the nothing we had before. And it is easy to add more screens in the future if we need to. We also didn’t include the JavaScript framebusting logic for older browsers because Google Analytics says hardly of our users are on such browsers.

Preventing Brute Force Logins

Another security issue that we knew about but didn’t fix because “it wasn’t a problem” was preventing brute force logins. It seemed like high time to do something about that one too. While this was more work than fixing Clickjacking, it wasn’t a huge deal either. The logic is mostly in one (well unit tested) class that gets called from the method with the login check. There is also a property file to externalize the number of attempts/wait. And a job to clear out the Map once a day for attempts where the IP gives up and goes away.

The idea is that an IP gets a number of “free” attempts. After that more login attempts from that IP must wait longer and longer. Once a user logs in successfully from that IP or there are no attempts for a certain amount of time,t he clock starts over and the “free” attempts are back.

This approach doesn’t protect against a distributed attack because the IPs are different. (I choose the IP based approach so someone can’t lock out a user’s account specifically by targeting them and entering invalid passwords. That said, we aren’t running a bank so it seems unlikely for someone to go through that much effort to attack us.

Note: I got a private comment to be careful about IP blocking due to companies using a single public IP for thousands of users. This approach is NOT using IP blocking. Let’s say have 1000 users from InfoSys. (We probably have more, but that’s not the point.) Most of those users will either know their password or use the “remember password” functionality. If a few forget their password and type in a bunch of wrong attempts, the time throttling kicks in.  It seems unlikely for multiple users to having this problem at the same time. And as soon as anyone from the company (IP) has a correct password, the “penalty” count resets.

Code for the curious:

package net.jforum.repository;

import java.util.*;

import net.jforum.util.preferences.*;

/**
 * We prevent brute force login attacks by throttling how often we will check
 * credential after three failed logins from the same IP since the last success.
 * If there are no failures within an hour, the clock will restart on this
 * throttling.
 *
 * @author Jeanne
 * @version $Id: $
 */
public class FailedLoginRepository {
    private static final int NUM_SECONDS_IN_MINUTE = 1000 * 60;
    private static FailedLoginRepository cache = new FailedLoginRepository();
    private Map<String, List<Date>> failedLogins;
    private int maxLoginsBeforeThrottling;
    private int numMinutesForReset;
    private int[] throttlingDelay;

    // ----------------------------------------------------------------
    public FailedLoginRepository() {
        failedLogins = new HashMap<String, List<Date>>();
        numMinutesForReset = SystemGlobals.getIntValue(ConfigKeys.BRUTE_FORCE_PREVENTION_NUM_MINUTES_FOR_RESET);
        String waitTimes = SystemGlobals.getValue(ConfigKeys.BRUTE_FORCE_PREVENTION_WAIT_TIMES);
        setWaitsAsIntArray(waitTimes);
        setMaxLoginsBeforeThrottling();
    }

    private void setMaxLoginsBeforeThrottling() {
        for (int i = 0; i < throttlingDelay.length; i++) {
            if (throttlingDelay[i] == 0) {
                maxLoginsBeforeThrottling++;
            }
        }
    }

    private void setWaitsAsIntArray(String waitTimes) {
        String[] stringArray = waitTimes.split(",");
        throttlingDelay = new int[stringArray.length];
        for (int i = 0; i < throttlingDelay.length; i++) {
            throttlingDelay[i] = Integer.parseInt(stringArray[i].trim());
        }
    }

    // ----------------------------------------------------------------
    public static FailedLoginRepository getInstance() {
        return cache;
    }

    // ----------------------------------------------------------------
    /**
     * After a successful login from the API, remove the blocks. This indicates
     * the user just mistyped and not a hacker.
     *
     * @param ip
     */
    public void successfulAttempt(String ip) {
        failedLogins.remove(ip);
    }

    // ----------------------------------------------------------------
    /**
     * Keep track of time of login failure
     *
     * @param ip
     * @param now
     */
    public void failedAttempt(String ip, Date now) {
        removeOldAttempts(ip);
        List<Date> fails = failedLogins.get(ip);
        if (fails == null) {
            fails = new ArrayList<Date>();
            failedLogins.put(ip, fails);
        }
        fails.add(now);
    }

    public void failedAttempt(String ip) {
        failedAttempt(ip, new Date());
    }

    // ----------------------------------------------------------------
    /**
     * If there haven't been any failed attempts from that IP in the last hour,
     * start over.
     *
     * @param ip
     */
    private void removeOldAttempts(String ip) {
        List<Date> fails = failedLogins.get(ip);
        if (fails != null) {
            Date lastFail = getLastFail(fails);
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.MINUTE, -numMinutesForReset);
            if (lastFail.before(cal.getTime())) {
                failedLogins.remove(ip);
            }
        }
    }

    private Date getLastFail(List<Date> fails) {
        Date lastFail = fails.get(fails.size() - 1);
        return lastFail;
    }

    public void removeAllOldAttempts() {
        for (String ip : failedLogins.keySet()) {
            removeOldAttempts(ip);
        }
    }

    // ----------------------------------------------------------------
    public boolean shouldCheckPassword(String ip) {
        removeOldAttempts(ip);
        int waitRemaining = numberMinutesUntilNextAllowedLogin(ip, new Date());
        return waitRemaining == 0;
    }

    public boolean shouldCheckPassword(String ip, Date now) {
        removeOldAttempts(ip);
        List<Date> fails = failedLogins.get(ip);
        return fails == null || fails.size() <= maxLoginsBeforeThrottling;
    }

    // ----------------------------------------------------------------
    public int numberMinutesUntilNextAllowedLogin(String ip) {
        return numberMinutesUntilNextAllowedLogin(ip, new Date());
    }

    /**
     * Contains algorithm for delays: see if already waited number of minutes
     * need to wai
     *
     * @param ip
     * @return
     */
    public int numberMinutesUntilNextAllowedLogin(String ip, Date now) {
        List<Date> fails = failedLogins.get(ip);
        if (fails == null) {
            return 0;
        }
        int index = fails.size() - 1;
        if (index >= throttlingDelay.length) {
            index = throttlingDelay.length - 1;
        }
        int delay = throttlingDelay[index];
        Date lastFailure = getLastFail(fails);
        int numMinutesWaited = (int) (now.getTime() - lastFailure.getTime()) / NUM_SECONDS_IN_MINUTE;
        int result = delay - numMinutesWaited;
        // if delay is over, do need to wait longer
        if (result < 0) {
            result = 0;
        }
        return result;
    }
}

 

own your expertise – a conference for women developers

Yesterday, <Write/Speak/Code> had a one day workshop for women developers called “Own your Expertise.” The idea is for more women to start “Building the foundation for  Thought Leadership, Conference Speaking & Open Source Contributing.” I had mixed feelings about going to a female only event. I asked a teammate to join me though and off we went. In this blog post, I’ll share some of the “gender” topics that came up and my reaction to them. [The rest of the workshop was more content driven like brainstorming topics].

Networking

There was lots of time for networking. Some of it was just general time. Some was structured networking.

My reaction: The environment was set up well for people to talk to each other and share experiences. Unlike at a core-tech conference, there were more icebreakers and “natural” opportunities to talk to people. I also felt like there were less people on laptops all day (presumably because it was Saturday) or with a group of colleagues that all came together. This made it easier to approach people. Also, there was a good mix of employed people, students and those looking for jobs. There were also a lot more career changers than at the typical tech event I go to.

Impostor Syndrome

  • Women have more trouble internalizing accomplishments
  • Proof of success is dismissed as luck/timing
  • This is common even in high achieving women
  • Even as kids, guys tend to attribute failure to luck or bad judging
  • Women tend to underestimate abilities.

My reactions: 

  1. I was surprised at the number of hands that went up when asked if the audience was not sure if they were as good a developer because they didn’t start coding when they were 12 or code for fun. (I do code for fun and started when I was a kid.) It’s ok not to code for fun. That said, practice makes perfect. And I believe those who code for fun are likely to become better developers and faster.
  2. A lot of this resonated from the book “The Confidence Code“. Which helped me realize that guys are more likely to sound confident even when wrong. Which is a problem because it encourages management to see that “the guys know what they are doing.” Making this a self fulling prophecy.
  3. Personally, I saw this last week when I gave a presentation. I’m not normally nervous when giving a presentation. For this one I was because my exposure to the topic was one day of a vendor showing us the product. I was fine. I knew almost everything I was asked. At least I didn’t APPEAR nervous.
  4. I also see see this when guys sound more confident even when wrong. I feel a resistance to challenging someone who sounds 100% confidence because it makes me doubt whether I’m right. I’ll check after the meeting, but sometimes the moment is gone then.

Stereotype Threat

People tend to perform worse when worried about refuting a stereotype

My reaction: I agree with this. It becomes a distraction. Or you feel like you have to do more because of it. Luckily, I’m good at not noticing. Every once in a while, someone will point it out and then I’ll notice. For example, there was one point where I was the only female under my officer’s part of the company. (I work for a bank; our senior managers are called officers.) This meant I went to a meeting every few months with all guys. I hadn’t noticed until someone started talking about the topic. Then I had an “oh, yeah” moment. Luckily, I do believe that the guys didn’t care either and moved on quickly. But it was certainly a distraction for the day or so that it was on my mind.

Negative feedback loop

The work too hard loop:

worry –> work hard –> good job –> approval/relief –> worry

My reaction: While I didn’t experience this one personally, I have seen it in a few others. Of both genders though. It does highlight an important lesson about not worrying (excessively) about things you can’t control.

Objective feedback/support system

  • Have people you can talk to who you trust to be objective
  • What’s the problem? What’s the worst that can happen? Is what you’re feeling objectively true or just your perspective?

My reaction: This is definitely important. Since we were in a workshop that frequently brought up gender, I ran through a tally of the genders of the people I talk to when having difficulties in a tech environment.

  • At CodeRanch, it is 3 men and 1 woman. (Most of the senior moderators are guys so I suspect this is talking to who is available.) At CodeRanch, most of the “problems” are someone saying something in the forums that is mean/hurtful. But sometimes, I’ll ask these people for advice on how to deal with an anonymized work problem if the people I’d ask at work are too close to it.
  • At work, it is 4 women and 1 man. Interesting how this is the reverse. Granted, I talk to other people about problems (like my manager at the current time.). I’m only counting the people that I feel like I can say anything to. While I’ve come close to that point with managers, I don’t think I could get 100% there.

Qualifying accomplishments

  • Women tend to use words that downplay what they do. Words like “just”, “only”, “good timing”, “luck”, etc make the person sound less skilled.
  • The idea is not to brag, but then it gets over done.

My reaction: They did an exercise where you were given an accomplishment and just said “thank you.” That was really easy. While I do use unnecessary qualifiers, I don’t do it a lot. And I don’t tend to do so in response to a compliment. I think when I use the qualifiers, I’m thinking about precision or not taking credit for something others do. That said, this is something I definitely see when talking to people. “I just figured out …”

Look at the data

Record positive feedback, measurable progress, accomplishments.

My reaction: Right on! At my first job, I was given the advice to record what I accomplish throughout the year so I remember it when it is appraisal time. This is excellent advice. I have a document at work with just that. I also have a list of public (non-work) accomplishments on my CodeRanch bio. It contains certifications, public conference talks, book contributions/tech editing, robotics and CodeRanch. I started posting this list to establish tech credibility. Then I continued because it is cool! I like that it is on CodeRanch rather than Linked In. This makes it about sharing rather than looking for a job.

“You guys”

The presenter said “you guys” once and  corrected it to “you ladies”

My reactions:

  1. I use the phrase “use guys” all the time. I consider it a gender neutral phrase. The problem is that “girls” maps to “boys” and “ladies” maps to “gentleman.” Girls is no good because it implies children. And ladies seems oddly formal.
  2. I don’t mind if someone uses an actual male phrase (online or at work) as long as it doesn’t keep happening. At CodeRanch, it is because Jeanne isn’t recognized as a female name internationally. I’ve corrected “sir” a number of times online.

Your body language shapes who you are

We saw a snippet of this Ted talk. The major themes in the snippet we watched were:

  1. you should just do something and eventually you’ll become it
  2. power poses increase confidence (and guys take up more space)

My reaction: The Power Pose thing felt stupid. Not passing judgement on it though. New things sometimes to feel stupid/silly. Google has millions of hits on it including yoga, so there is presumably something to it.

Credibility

  • Knowledge
  • Expertise – There was an exercise where everyone said “I’m an expert at ______ because ________”.
  • Shiny bauble – you have a small amount of time to convince others they should listen to you. Grab attention

My reaction: This was easy for me because I’ve done a lot :). It was interesting to see what others said. I was also in the same group as my teammate for the expertise exercise. It was nice to hear her say her expertise confidently.

Help others

  • Teach things that you already know
  • Ask the first question so someone else doesn’t have to
  • Connect with others
  • Reframe bragging into sharing and helping others

My reaction: Funny, I do ask the first question a lot. I agree with the helping others. That’s a part of robotics mentoring and CodeRanch and Toastmasters. All hobbies of mine. While I don’t like “be a good female role model”, I don’t think about that much. Most of the time, I’m me and I happen to be female. Now let’s go talk about tech!