Første leksjon: ikke lekke hemmelighetene dine i en medium illustrasjon etter innlegg

Den beste måten å lagre hemmeligheter i appen din er ikke å lagre hemmeligheter i appen din

Ansvarsfraskrivelse: metoden beskrevet i denne artikkelen er veldig avhengig av AWS. Når det er sagt, kan konseptet fortsatt gjelde for andre tilbydere ...

Hvis du noen gang har bygd en app på Internett, kom du over kampen for å beholde hemmeligheter (databasens legitimasjon, api-nøkler osv.) På serveren din.

Historisk har utviklere funnet flere måter å oppnå dette på. Hver av dem har et visst nivå av sikkerhet og bekvemmelighet. Jeg vil lede deg gjennom dem slik at du kan få en følelse av hvor vi kommer fra.

Lagre hemmeligheter i koden din

# innstillinger / instans_settings.py
STRIPE_API_KEY = '3ef8-843a-49dc-a34d' # Ikke fortell noen! plz?

Dette er tydeligvis den mest praktiske metoden. Du skriver API-nøkkelen i koden din som en konstant, og deretter skyver du den til kildekontrollen, og voilà!

Men det er også den minst sikre metoden. Du la bare en viktig hemmelighet spres på hver utviklers datamaskin (eller eksterne stasjoner), på kildekontrollleverandørens lagring, på CI-leverandørens server osv. Dette øker risikoen for at denne hemmeligheten kan lekke.

Lagring av hemmeligheter i miljøet

stripe_api_key = os.environ ["STRIPE_API_KEY"]

Dette er en jeg har brukt ganske ofte. Du må enten stille inn miljøvariablene manuelt på hver server eller bruke en slags orkestrator for å håndtere det for deg, noe som er litt mindre praktisk enn forrige metode. Til tross for dette har det fordelen at bare noen pålitelige individer har tilgang til det.

Det er fortsatt noen problemer: en enkel feilkonfigurasjon (for eksempel å kjøre en produksjonsserver i feilsøkingsmodus) eller en sikkerhetsfeil kan føre til lekkasje av alle miljøvariablene.

Lagring av hemmeligheter i databasen

Jeg tar opp dette kort: Du vil fortsatt ha databasens legitimasjon utenfor et sted, og derfor beseire formålet med å legge hemmelighetene dine der. Ved å ha daglige sikkerhetskopier av alle tjenestene dine API-nøkler øker dessuten risikoen for lekkasje på et tidspunkt.

Bruke en hemmelighetssynkroniseringstjeneste

Det er SaaS som tilbyr å ta vare på dine API-nøkler og andre hemmeligheter for deg. De holder dem trygge og lar deg spørre dem fra deres tjeneste etter behov. Vi har fortsatt det samme problemet som den forrige metoden: du trenger en veldig hemmelig API-nøkkel for å få alle API-nøklene dine.

Lagrer hemmeligheter i koden din… men kryptert

En moderne versjon av den første metoden er å kryptere hemmelighetene i koden din, og dermed ikke eksponere verdiene deres for kildekontrollen, andre utviklere og så videre. For å dekryptere disse hemmelighetene, trenger imidlertid serveren fortsatt å administrere en nøkkel. Dette kommer tilbake til spørsmålet om å distribuere og opprettholde en stor hemmelighet som låser opp alle andre hemmeligheter.

Hvorfor er det utrygt?

Disse metodene har samme karakteristikk; de innebærer fortsatt å ha hemmeligheter på serveren din, og de kan lekke eller bli stjålet

I verste fall

Se for deg følgende scenario. En angriper brøt seg inn på serveren din ved hjelp av en sårbarhet i Apache. Han / hun begynner deretter å søke etter databasens legitimasjon og API-nøkler i konfigurasjonsfilen din, koden din, miljøet. Hvis hemmelighetene dine på en eller annen måte er skjult / kryptert nok, vil ikke angriperen finne noe. Men det betyr ikke at han / hun vil stoppe der. Ved å bruke noe som LiME, kan hackeren fremdeles bla i serverens minnedump for å trekke ut disse hemmelighetene.

Vi kan gjøre det bedre

Vi presenterer:

Brukerbeviselsesfri tjenestetilgang ved hjelp av en IAM-autentisert API Gateway som proxy ™

(Jeg er forferdelig med å finne fengende navn, og dette er egentlig ikke varemerke)

Oversikt

I et nøtteskall bruker vi forekomstrollen til EC2-forekomsten for å ringe en sikker samtale til en API Gateway, som deretter får den til ønsket tjeneste, etter å ha endret forespørselen ved å legge til de nødvendige legitimasjonene. Æsj! Det er mye informasjon for en enkelt setning.

De sier at et bilde er verdt 1000 ord. UTFORDRING AKSEPTERT

Fortsatt tapt? La oss dissekere dette

For det første, for at dette skal fungere, må vi bruke den opprinnelige måten for EC2-forekomster (eller ECS Containers and Lambdas) for å ringe til andre AWS-ressurser, som er ved å bruke IAM-roller.

For det andre må vi lage en Rest API-ressurs i API Gateway. Det er noen spesifikke konfigurasjoner som må brukes slik at kropp, overskrifter og spørringsparametere kan passeres. I tillegg må vi endre forespørselen slik at vi kan injisere de målrettede tjenestegistrene. Endelig må vi aktivere det hemmelige våpenet: IAM-basert autorisasjon.

Det tredje og siste trinnet består i å signere URL-en før du ringer til de ønskede proxy-tjenester.

¿Que?

For de av dere som ikke er så kjent med teknologiene jeg nettopp har nevnt, og som fremdeles er usikker på hva dette handler om, her er en sammenligning av før og etter bruk av legitimasjonsfri servicetilgang ved hjelp av en IAM-autentisert API Gateway som proxy ™:

Jeg bruker den velkjente GitHub API og Postman for denne demonstrasjonen:

Før (Direkte samtale til GitHub):

Etter (samtale via API Gateway):

Jeg kan allerede høre deg si:

Du fortalte oss at dette var uten legitimasjon og jeg ser en tilgangsnøkkel, en hemmelig nøkkel og et symbol !!!

Dette er fordi den bærbare datamaskinen min ikke har det hemmelige våpenet. Når du har startet dette og kjøres på en EC2-forekomst, blir disse midlertidige sikkerhetsopplysningene automatisk hentet fra forekomstmetadataene. Hvis konseptet med midlertidig legitimasjon er nytt for deg, er her et utdrag fra dokumentasjonen (vektlegging min):

En applikasjon på forekomsten [...] får tillatelser for handlingene og ressursene du har definert for rollen gjennom sikkerhetsinformasjon som er knyttet til rollen. Disse sikkerhetsopplysningene er midlertidige, og vi roterer dem automatisk. Vi stiller nye legitimasjonsbeskrivelser til rådighet minst fem minutter før utløpet av de gamle legitimasjonsbeskrivelsene.

For å være rettferdig, vil en mer nøyaktig beskrivelse av denne metoden være Tjenestetilgang ved hjelp av en IAM-autentisert API Gateway som proxy uten bruk av langsiktige legitimasjonsbeskrivelser. Vi kan imidlertid være enige om at "kortsiktige midlertidige legitimasjon som brukes til å signere samtaler til proxy-tjenester begrenset via IAM" er langt mindre attraktive for angripere enn vanlige API-nøkler og andre langsiktige hemmeligheter.

Dette er en enorm oppgradering fra et sikkerhetsperspektiv

Viktige sikkerhetsforbedringer:

  • Midlertidig legitimasjon behøver aldri håndteres av utviklere
  • De spørres programmatisk, så det er ikke nødvendig å ha dem skrevet til en konfigurasjonsfil
  • Hvis det er lekket eller stjålet, vil disse midlertidige legitimasjonene fungere i høyst en time
  • Alle forespørsler kan logges inn i CloudWatch for revisjon
  • Du kan begrense målrettet API ved hjelp av en IAM-policy

Det siste kulepunktet er spesielt nyttig når du jobber med et API som GitHub som mangler en finkornet tillatelsesmodell. Ved hjelp av følgende IAM-policy kan jeg begrense API-en til bare å tillate GET-metoden på / repos / PokaInc / test-github-api / problems endpoint.

{
    "Versjon": "2012-10-17",
    "Uttalelse": [
        {
            "Handling": [
                "Execute-api: Start"
            ]
            "Ressurs": [
                "ARN: AWS: henrette-api: us-øst-1: 123456789010: w974f1rs6e / dev / GET / repos / PokaInc / test-github-api / problemer"
            ]
            "Effekt": "Tillat"
        }
    ]
}

Men vent, det er mer!

Andre fordeler ved å bruke API Gateway som proxy

  • Bruksstatistikk. Dette kan være nyttig for å identifisere trender og forhindre takstbegrensning fra tredjeparts tjenester.
  • Hogst. Når dette er aktivert, kan du ha detaljerte logger for hver forespørsel, inkludert opprinnelse og parametere brukt.
  • Caching. Har du vanskeligheter eller hastighetsbegrensende problemer? Med tre linjer CloudFormation-kode kan du legge til en cache-backend til proxyen din.
  • Lokal utvikling. Utviklere som bruker en IAM-bruker lokalt, kan få tilgang til de fullstendige tjenestene direkte i stedet for å stole på hardkodet legitimasjon på datamaskinen.

På dette tidspunktet vil jeg anta at du er solgt på ideen, og at du vil prøve ut metoden selv.

Koden

Tatt i betraktning her på Poka vi er CloudFormation afi · cio · nados, har jeg laget en proof-of-concept-mal tilgjengelig på GitHub.

Provisioning

Følg instruksjonene i README.md for å opprette proxy.

Bruker proxy

Dette er også beskrevet i readme, men jeg vil legge det inn her, så jeg kan overbevise deg om at det ikke er svart magi.

La oss se på denne koden

returner AWSRequestsAuth (
      [...]
      ** boto_utils.get_credentials ()
)

Det er her vi vanligvis ville ha sett hardkodede legitimasjon, tilgang til en konfigurasjonsfil eller en spørring til miljøet. I stedet ber denne metoden metadatatjenesten om midlertidige nøkler. Hvis EC2-forekomstrollen har tilstrekkelige tillatelser, vil samtalen gå til GitHub, ellers vil API Gateway avvise den.

Konklusjon

Jeg håper dette innlegget bidro til å øke bevisstheten om dårlig sikrede hemmeligheter i applikasjonsservere og hvordan bruk av API Gateway som en proxy kan være til nytte for deg utover den ekstra sikkerheten.

Advarsler (og løsningene deres)

  • Hva om jeg vil proxy av en intern tjeneste som ikke er utsatt for internett?

Forklaringen kan ha et eget dedikert blogginnlegg. Men kort historie, du kan tilby en VPC-aktivert AWS Lambda som målet for API Gateway-proxy. Lambda må overføre overskrifter, spørringsparametere og organ til den interne tjenesten, samle svaret og returnere det til API Gateway.

  • Dette fungerer bra med REST API-er, men hva med TCP-tjenester som relasjonsdatabaser eller cache-servere?

Igjen, dette ville fortjent et komplett blogginnlegg. I et nøtteskall kan vi lage en mikrotjeneste (tilgjengelig via, du gjettet det, en IAM-autentisert API Gateway) som vil opprette legitimasjon on-the-fly for de ønskede tjenestene. For eksempel: hvis mikrotjenesten blir bedt om PostgreSQL-legitimasjon, kan den utstede en CREATE ROLE-kommando med et tilfeldig generert passord. I tillegg kan rollen ha en levetid ved bruk av VALID UNTIL-egenskapen.

Alternatives

Har du ikke produsert arbeidsmengden på AWS? Denne metoden kan ikke fungere for deg? Det er andre verktøy der ute som kan hjelpe deg med å takle hemmelighetsstyring.

  • http://engineering.nike.com/cerberus/
  • https://www.vaultproject.io/
  • https://docs.docker.com/engine/swarm/secrets/

Referanser for denne artikkelen:

http://blog.arkency.com/2017/07/how-to-safely-store-api-keys-in-rails-apps/
https://blog.rackspace.com/securing-application-secrets-with-ec2-parameter-store
https://www.envkey.com/
https://www.hashicorp.com/blog/Vault-announcement/
https://docs.docker.com/engine/swarm/secrets/
http://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html
http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html
http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html

Spesiell takk til Tea Rudolf, Etienne Talbot, Simon-Pierre Gingras, Maxime Leblanc og Marilou Simard-Baril for korreksjonene (Ja, jeg trenger så mye folk til å gå gjennom engelsk) og takk til Julie Dorion-Bélanger for illustrasjonene.

Har du spørsmål / forslag til dette innlegget? Skriv en kommentar nedenfor, så gjør jeg mitt beste for å svare på den.