Skip to content

Commit ff0e20d

Browse files
committed
store hashed basic http credentials
1 parent 46728a6 commit ff0e20d

File tree

6 files changed

+66
-8
lines changed

6 files changed

+66
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55

66
## Unreleased
7-
8-
> 2016-09-06 :new: v1.10.0: SSL support
7+
> 2016-09-06 :new: v1.10.0:
8+
* SSL support: prevent basic HTTP Auth credential sniffing.
9+
* ```auth_key_sha1``` store hashed basic HTTP auth credentials in configuration file.
910

1011
## Released
1112

src/main/java/org/elasticsearch/plugin/readonlyrest/acl/blocks/Block.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ public Block(Settings s, ESLogger logger) {
7272
conditionsToCheck.add(new ActionsRule(s));
7373
} catch (RuleNotConfiguredException e) {
7474
}
75+
try {
76+
conditionsToCheck.add(new AuthKeySha1Rule(s));
77+
} catch (RuleNotConfiguredException e) {
78+
}
7579
}
7680

7781
public String getName() {

src/main/java/org/elasticsearch/plugin/readonlyrest/acl/blocks/rules/impl/AuthKeyRule.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
public class AuthKeyRule extends Rule {
1919
private final static ESLogger logger = Loggers.getLogger(AuthKeyRule.class);
2020

21-
private String authKey;
21+
protected String authKey;
2222

2323
public AuthKeyRule(Settings s) throws RuleNotConfiguredException {
2424
super(s);
@@ -30,7 +30,6 @@ public AuthKeyRule(Settings s) throws RuleNotConfiguredException {
3030
else {
3131
throw new RuleNotConfiguredException();
3232
}
33-
3433
}
3534

3635
// Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
@@ -65,6 +64,10 @@ public RuleExitResult match(RequestContext rc) {
6564
return NO_MATCH;
6665
}
6766

68-
return authKey.equals(authHeader) ? MATCH : NO_MATCH;
67+
return checkEqual(authHeader) ? MATCH : NO_MATCH;
68+
}
69+
70+
protected boolean checkEqual(String provided) {
71+
return authKey.equals(provided);
6972
}
70-
}
73+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.elasticsearch.plugin.readonlyrest.acl.blocks.rules.impl;
2+
3+
import com.google.common.base.Charsets;
4+
import com.google.common.hash.Hashing;
5+
import org.elasticsearch.ElasticsearchParseException;
6+
import org.elasticsearch.common.Base64;
7+
import org.elasticsearch.common.logging.ESLogger;
8+
import org.elasticsearch.common.logging.Loggers;
9+
import org.elasticsearch.common.settings.Settings;
10+
import org.elasticsearch.plugin.readonlyrest.acl.blocks.rules.RuleNotConfiguredException;
11+
12+
import java.io.IOException;
13+
14+
/**
15+
* Created by sscarduzio on 13/02/2016.
16+
*/
17+
public class AuthKeySha1Rule extends AuthKeyRule {
18+
19+
private final static ESLogger logger = Loggers.getLogger(AuthKeySha1Rule.class);
20+
21+
public AuthKeySha1Rule(Settings s) throws RuleNotConfiguredException {
22+
super(s);
23+
try {
24+
authKey = new String(Base64.decode(authKey),Charsets.UTF_8);
25+
} catch (IOException e) {
26+
throw new ElasticsearchParseException("cannot parse configuration for: " + this.KEY);
27+
}
28+
}
29+
30+
@Override
31+
protected boolean checkEqual(String provided) {
32+
try {
33+
String decodedProvided = new String(Base64.decode(provided), Charsets.UTF_8);
34+
String shaProvided = Hashing.sha1().hashString(decodedProvided, Charsets.UTF_8).toString();
35+
return authKey.equals(shaProvided);
36+
} catch (IOException e) {
37+
return false;
38+
}
39+
}
40+
}

src/test/java/org/elasticsearch/rest/action/readonlyrest/acl/test/ACLTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ public final void testHttpBasicAuth() throws Throwable {
171171
assertTrue(res.getBlock().getPolicy() == Block.Policy.ALLOW);
172172
assertEquals(res.getBlock().getName(), "2");
173173
}
174+
@Test
175+
public final void testSHA1HttpBasicAuth() throws Throwable {
176+
String secret64 = Base64.encodeBytes("sha1configured:p455wd".getBytes(Charsets.UTF_8));
177+
RequestContext rc = mockReq("/index1/_search?q=item.getName():fishingpole&size=200", "1.1.1.1", "", "Basic " + secret64, 0, Method.DELETE, null, null, null);
178+
BlockExitResult res = acl.check(rc);
179+
assertTrue(res.isMatch());
180+
assertTrue(res.getBlock().getPolicy() == Block.Policy.ALLOW);
181+
assertEquals(res.getBlock().getName(), "15");
182+
}
174183

175184
@Test
176185
public final void testXforwardedForHeader() throws Throwable {

src/test/test_rules.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ readonlyrest:
9999
hosts: [1.1.1.2]
100100
indices: ["i1", "i2", "i3"]
101101

102-
103-
102+
- name: 15
103+
type: allow
104+
auth_key_sha1: a5aa590854b3806350b345ea154a52e3391aed32 #sha1configured:p455wd

0 commit comments

Comments
 (0)