Wrong credentials approved by git

Viewed 46

So I needed to add my personal GitHub account to my office laptop in which I was already using my work github account. So I created a separate ssh key and stored that into a separate file. I added that newly created ssh to my personal github account.

Then I added a config file like this:

Work
   Host github.com
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa
   
 Personal account
   Host github.com-personal  
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa_personal

I then created a PRIVATE new repository in personal git repository and cloned it like the following so that it will use personal ssh token:

git clone git@github.com-personal:prajatpadhi/udemy-react-maximillian.git

I then made some commits and pushed. But I was surprised to see that the commit's author was my work's userid because I had forgotten to change the username and email of my local repository.

But shouldn't in such a case there should be an authorization error as the repository was private in the personal git hub account. How did GitHub allowed access?

My personal userid is lets say pp and work's pp1. How can pp1 be allowed to push a commit to pp's private repository?

2 Answers

Here is a simple, but basically untested, pre-push hook that can check for commits made with user.name and/or user.email settings that you don't want. Modify the check() function as desired.

#! /bin/sh
#
# pre-push hook to check commits to be sent
#
# The check() function takes a commit hash ID and decides if it's OK
# (returns zero) or not (returns nonzero).
check() {
        local hash="$1" ret=0
        set -- $(git log --no-walk --pretty=format:"%an %ae" $hash | sed 's/ /-/g')
        case "$1" in
        my-name-ok) ;;
        my-name-bad) echo "oops, wrong author name on commit $hash"; ret=1;;
        *) echo "oops? unknown author name $1 on $hash"; ret=1;;
        esac
        case "$2" in
        my-email-ok@my-host-ok) ;;
        *) echo "oops? unknown email address $2 on $hash"; ret=1;;
        esac
        return $ret
}

# cheesy hack to get appropriate number of 0s, assumes we're
# on a branch that exists.
NULLHASH=$(git rev-parse HEAD | sed 's/./0/g')

# Use git rev-list to figure out which commits to check.
# We could get fancy and accumulate them and uniq-ize them,
# but probably no reason to bother.
TF=$(mktemp)
trap "rm -f \"$TF\"" 0 1 2 3 15
status=0
while read localref localhash remoteref remotehash; do
        if [ "$localhash" = $NULLHASH ]; then continue; fi # --delete
        if [ "$remotehash" = $NULLHASH ]; then
                # creating a new name on the remote, so we don't
                # know for sure what's new to them, but we'll just
                # assume that `--not --remotes` is good here (!!!)
                scancmd="git rev-list $localhash --not --remotes
        else
                scancmd="git rev-list $remotehash..$localhash"
        fi

        # shell loops run in subshell if we use a pipe, so use a temp file
        $scancmd >$TF
        while read hash; do
                if check $hash; then status=1; fi
        done <$TF
done
exit $status

Again, this is untested, so test it (and make any required changes to check as there are definitely some required). The general idea here is to scan each commit before git push sends it. When we're augmenting some existing branch in the remote, git rev-list $remotehash..$localhash enumerates the commits we're adding.

There is a flaw here (kind of deliberate): if $remotehash denotes some commit we don't have locally, the git rev-list above will fail. That won't make the overall script fail, but it means they have commits you don't, and you might want to abort the git push. You could fancy this up some more by using git rev-parse --quiet --verify with the $remotehash value: if we can parse it, we have the commit (or tag); if not, we don't. If we don't have it, we may be resetting the branch backwards, or both resetting it backwards and moving it forwards, as --force would. You'll need to decide what, if anything, you'd like to do about this situation.

But shouldn't in such a case there should be an authorization error as the repository was private in the personal git hub account.
How did GitHub allowed access?

No, commit authorship has nothing to do with authentication/access.

It is better to use a conditional includeIf.<condition>.path global setting in order to set user.name/user.email depending on the project folder you are in.

That way, you don't forget to set the right name/email, and your created commits are done with the right author.

Related